Skip to content

Project Structure

Every AMC plugin follows the same directory layout. Some files are always required; others depend on whether your plugin has a backend, cron jobs, or CLI endpoints.

Directory Layout

A full-template plugin looks like this:

my-plugin/
  manifest.json        # Plugin metadata and configuration (required)
  package.json         # npm project file (required)
  tsconfig.json        # TypeScript compiler config (required)
  .gitignore           # Ignores node_modules/, dist/, *.amcplugin
  src/
    ui/                # Frontend source (optional if backend-only)
      index.html       # UI entry point loaded in AMC's webview
      plugin.ts        # UI logic, accesses window.AgentMC bridge
    backend/           # Backend source (optional)
      index.ts         # Exports an activate function
  dist/                # Compiled output (generated by build)
    ui/
      index.html       # Copied from src/ui/
      plugin.js        # Compiled from src/ui/plugin.ts
    backend/
      index.js         # Compiled from src/backend/index.ts
  assets/              # Static assets bundled into .amcplugin (optional)
  node_modules/        # Dependencies (gitignored)

File-by-File Reference

manifest.json (required)

The central configuration file. Declares your plugin's identity, settings, permissions, storage collections, UI entry point, backend entry point, CLI endpoints, and cron jobs.

json
{
  "plugin": {
    "id": "my-plugin",
    "name": "My Plugin",
    "version": "1.0.0",
    "author": "Your Name",
    "description": "An AMC plugin",
    "icon": "puzzle",
    "category": "other",
    "license": { "type": "free" }
  },
  "settings": [],
  "storage": { "collections": {} },
  "migrations": [],
  "sdkVersion": "^1.0.0",
  "ui": {
    "entryPoint": "dist/ui/index.html",
    "sidebar": { "title": "My Plugin", "icon": "puzzle" }
  }
}

TIP

See the Manifest page for the full field reference.

package.json (required)

Standard npm project file. The scaffolder generates it with the build, dev, package, and validate scripts pre-configured:

json
{
  "name": "my-plugin",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "tsc",
    "dev": "amc-plugin dev",
    "package": "amc-plugin package",
    "validate": "amc-plugin validate"
  },
  "devDependencies": {
    "@agent-mc/plugin-sdk": "^1.0.0",
    "typescript": "^5.5.0"
  }
}

The @agent-mc/plugin-sdk package provides TypeScript types for both the backend (PluginContext, PluginActivate, PluginBackend) and the frontend (AgentMC bridge). It is a dev dependency only -- it is not bundled into your plugin at runtime.

tsconfig.json (required)

TypeScript compiler configuration. The scaffolder targets ES2022 with bundler module resolution:

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "declaration": true,
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src"]
}

Source files under src/ compile into dist/ with the same directory structure. Non-TypeScript files in src/ui/ (HTML, CSS, images) are copied by the amc-plugin build command.

src/ui/index.html (optional)

The HTML file loaded in AMC's plugin webview. This is the entry point declared in manifest.json under ui.entryPoint.

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Plugin</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, sans-serif;
      padding: 24px;
      background: var(--surface-50, #fafafa);
      color: var(--surface-900, #111);
    }
  </style>
</head>
<body>
  <h1>My Plugin</h1>
  <script src="plugin.js"></script>
</body>
</html>

AMC injects CSS custom properties (--surface-50, --surface-900, etc.) into the webview so your plugin automatically adapts to the user's light/dark theme. Use var(--surface-*) values instead of hardcoded colors.

src/ui/plugin.ts (optional)

TypeScript for your UI logic. Access AMC APIs through window.AgentMC:

typescript
import type { AgentMC } from '@agent-mc/plugin-sdk/browser'

const amc = (window as unknown as { AgentMC: AgentMC }).AgentMC

async function init() {
  const settings = await amc.settings.getAll()
  console.log('Plugin initialized with settings:', settings)
}

init()

The AgentMC bridge is injected into the webview by AMC before your script runs. It provides access to storage, database, settings, sessions, AI, theme, toasts, export, project management, sidebar control, and static assets.

src/backend/index.ts (optional)

The backend module runs in a sandboxed Node.js worker inside AMC's main process. It exports an activate function that receives a PluginContext and returns a PluginBackend with lifecycle hooks:

typescript
import type { PluginActivate } from '@agent-mc/plugin-sdk'

const activate: PluginActivate = (ctx) => {
  return {
    onEnable() {
      ctx.log.info('Plugin enabled')
    },

    onDisable() {
      ctx.log.info('Plugin disabled')
    },

    onSettingsChanged(settings) {
      ctx.log.info('Settings changed:', settings)
    },
  }
}

export default activate

The backend is declared in manifest.json under backend.entryPoint. If your plugin is UI-only, you can omit both the src/backend/ directory and the backend field in the manifest.

dist/ (generated)

The compiled output directory. Created by npm run build (which runs tsc). The amc-plugin package command bundles dist/ alongside manifest.json and assets/ into the .amcplugin archive.

Never edit files in dist/ directly -- they are overwritten on every build.

assets/ (optional)

Static assets (images, JSON data files, etc.) that ship with your plugin. The amc-plugin package command includes this directory in the .amcplugin archive if it exists. Access assets at runtime from the frontend using amc.assets.readFile(path) and amc.assets.listFiles(path).

.gitignore

The scaffolder creates this with three entries:

node_modules/
dist/
*.amcplugin

UI-Only vs Backend-Only vs Full

ConfigurationRequired filesManifest fields
UI onlysrc/ui/index.html, src/ui/plugin.tsui
Backend onlysrc/backend/index.tsbackend
FullBoth src/ui/ and src/backend/ui, backend, and optionally cli, cron

A plugin must have at least one of ui or backend declared in the manifest.

AMC Plugin SDK