Skip to content

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:

APIInterfaceWhat it does
SettingsPluginSettingsRead the plugin's own settings (getAll(), get(key))
LoggingPluginLoggerWrite to AMC's log (info(), warn(), error(), debug())
EventsPluginEventsEmit and listen for plugin-scoped events (emit(), on())
SidebarPluginSidebarUpdate 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:

typescript
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 prefix

PluginDb -- structured database (SQLite collections defined in manifest):

typescript
// 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:

typescript
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:

typescript
// 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:

typescript
// 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:

typescript
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:

typescript
// 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:

typescript
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):

typescript
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:

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

PermissionAPIs GrantedUse Case
storagePluginStorage, PluginDb, PluginFsPersist data, query collections, read/write files
sessionsPluginSessionsCreate/manage Claude Code sessions
aiPluginAiDirect AI text generation
networkPluginHttpOutbound HTTP requests
cronPluginCronScheduled background tasks
cliPluginCliHTTP endpoints on AMC's control server
notificationsPluginToast.notify()Native OS desktop notifications
(none)PluginSettings, PluginLogger, PluginEvents, PluginSidebar, PluginToast.show()Always available

AMC Plugin SDK