Permissions
Plugins declare the permissions they need in manifest.json. AMC shows these to the user during installation and enforces them at runtime -- if your plugin calls an API it has not been granted permission for, the call is rejected.
Permission Model
There are 7 permissions that gate access to specific API surfaces. Some APIs are available to every plugin without any permission declaration.
Always Available (No Permission Needed)
These APIs are available to all plugins, regardless of permissions:
| API | Interface | What it does |
|---|---|---|
| Settings | PluginSettings | Read the plugin's own settings (getAll(), get(key)) |
| Logging | PluginLogger | Write to AMC's log (info(), warn(), error(), debug()) |
| Events | PluginEvents | Emit and listen for plugin-scoped events (emit(), on()) |
| Sidebar | PluginSidebar | Update the sidebar badge and item list (setBadge(), setItems()) |
| Toast (show) | PluginToast.show() | Display in-app toast messages (success, error, info) |
TIP
Settings are read-only from the plugin's perspective. The user configures them through AMC's Settings > Plugins panel. Your plugin defines the available settings in manifest.json and reads their current values at runtime.
Permission Reference
storage
Grants access to: PluginStorage, PluginDb, PluginFs
Three related APIs for persisting data:
PluginStorage -- simple key-value store:
await ctx.storage.get('lastRun') // Read a value
await ctx.storage.set('lastRun', Date.now()) // Write a value
await ctx.storage.delete('lastRun') // Delete a value
await ctx.storage.list('config:') // List keys with prefixPluginDb -- structured database (SQLite collections defined in manifest):
// Insert a row
const row = await ctx.db.insert('tasks', {
title: 'Review PR',
priority: 1,
})
// Query with filters, ordering, and pagination
const results = await ctx.db.query('tasks', {
where: { priority: 1 },
orderBy: 'created_at',
order: 'DESC',
limit: 10,
offset: 0,
})
// Get, update, delete by ID
const task = await ctx.db.getById('tasks', 'abc-123')
await ctx.db.update('tasks', 'abc-123', { priority: 2 })
await ctx.db.delete('tasks', 'abc-123')
await ctx.db.deleteWhere('tasks', { priority: 0 })PluginFs -- sandboxed filesystem within the plugin's data directory:
await ctx.fs.writeFile('output/report.md', content)
const text = await ctx.fs.readFile('output/report.md')
const exists = await ctx.fs.exists('output/report.md')
const files = await ctx.fs.listDir('output')
await ctx.fs.deleteFile('output/report.md')WARNING
All filesystem paths are relative to the plugin's data directory. Plugins cannot access files outside this sandbox.
sessions
Grants access to: PluginSessions
Create and manage Claude Code sessions programmatically:
// Create a new session
const { sessionId } = await ctx.sessions.create({
prompt: 'Analyze the codebase for security issues',
projectId: 'optional-project-id',
})
// Interact with the session
await ctx.sessions.sendMessage(sessionId, 'Focus on SQL injection')
const status = await ctx.sessions.getStatus(sessionId)
const messages = await ctx.sessions.getMessages(sessionId)
// Monitor status changes
const unsubscribe = ctx.sessions.onStatusChange(sessionId, (status) => {
ctx.log.info(`Session ${sessionId} is now: ${status}`)
})
// Stop the session
await ctx.sessions.stop(sessionId)ai
Grants access to: PluginAi
Call AI models directly for text generation without creating a full session:
// Generate a response with a system prompt and user prompt
const response = await ctx.ai.generateMessage(
'You are a helpful code reviewer.',
'Review this function for potential bugs: ...',
)
// Generate a short title from text
const title = await ctx.ai.generateTitle(
'This PR adds pagination to the user list endpoint...',
)network
Grants access to: PluginHttp
Make outbound HTTP requests:
const response = await ctx.http.fetch('https://api.example.com/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: 'test' }),
})
const data = await response.json()The fetch API follows the standard Fetch API interface.
cron
Grants access to: PluginCron
Register and manage scheduled tasks:
// Register a handler for a cron job declared in manifest.json
ctx.cron.register('heartbeat', '*/30 * * * *', async () => {
ctx.log.info('Running heartbeat check')
const status = await checkHealth()
await ctx.db.insert('checks', { status, timestamp: Date.now() })
})
// Check if a job is registered
const active = ctx.cron.isRegistered('heartbeat')
// Unregister a job
ctx.cron.unregister('heartbeat')TIP
Cron jobs must also be declared in the cron.jobs array in manifest.json. The id you pass to register() must match a declared job ID. See Manifest > Cron Block.
cli
Grants access to: PluginCli
Register HTTP endpoint handlers accessible through AMC's CLI control server:
ctx.cli.handle('status', async (req) => {
// req: { method, path, body?, query? }
const checks = await ctx.db.query('checks', {
orderBy: 'created_at',
order: 'DESC',
limit: 5,
})
return {
status: 200,
body: { healthy: true, recentChecks: checks },
}
})
// Remove a handler
ctx.cli.removeHandler('status')Endpoints are reached at http://127.0.0.1:19519/plugins/<plugin-id>/<path>.
TIP
CLI endpoints must also be declared in the cli.endpoints array in manifest.json. The path you pass to handle() must match a declared endpoint path. See Manifest > CLI Block.
notifications
Grants access to: PluginToast.notify()
Send OS-level desktop notifications (system tray notifications):
ctx.toast.notify({
title: 'Build Complete',
body: 'Your project has been built successfully.',
})Note that ctx.toast.show() (in-app toasts) is available without this permission. The notifications permission is only required for ctx.toast.notify(), which triggers a native OS notification.
Declaring Permissions
Add permissions to the permissions array in manifest.json:
{
"permissions": ["storage", "sessions", "ai", "network"]
}Only request the permissions your plugin actually needs. Users see the permission list during installation, and requesting unnecessary permissions may discourage adoption.
Summary Table
| Permission | APIs Granted | Use Case |
|---|---|---|
storage | PluginStorage, PluginDb, PluginFs | Persist data, query collections, read/write files |
sessions | PluginSessions | Create/manage Claude Code sessions |
ai | PluginAi | Direct AI text generation |
network | PluginHttp | Outbound HTTP requests |
cron | PluginCron | Scheduled background tasks |
cli | PluginCli | HTTP endpoints on AMC's control server |
notifications | PluginToast.notify() | Native OS desktop notifications |
| (none) | PluginSettings, PluginLogger, PluginEvents, PluginSidebar, PluginToast.show() | Always available |