Creating packages

Write your own AI Game Dev package: the aigd-package.json manifest, commands, slash commands, MCP tools, local development with gamedev pkg dev, sharing.

Updated November 4, 2026 View as Markdown

Packages are not only for first-party features: you can write your own to share a repeated task with your team, add a tool for the agent, or preview a custom file format. This page shows the package layout, a minimal working package, the main manifest fields, how to add an MCP tool, how to develop a package against a running app, and how to share it.

What you need

  • The AI Game Dev desktop app or the gamedev CLI, version 0.18.0 or newer.
  • A text editor. JavaScript is optional: a package can be manifest-only.

Packages follow the model of VS Code extensions: a folder with a manifest, aigd-package.json, and optional code that exports activate(ctx) and deactivate(). Your code reaches the app only through ctx.aigd. It runs in a separate extension host process, one per open project, and starts lazily when something needs it.

Package layout

my-first-package/
  aigd-package.json     the manifest (required)
  extension.js          the code named by "main" (optional)
  media/                icons and images (optional)
  LICENSE

A package must be self-contained: the app never runs npm install for it. If your code uses libraries, bundle them into the file main points to.

A minimal package

This package adds a /my-first slash command, a command palette entry, a composer toolbar button, a status bar item and one setting.

{
  "publisher": "you",
  "name": "my-first-package",
  "version": "0.1.0",
  "displayName": "My First Package",
  "description": "A /my-first slash command, a palette command, a toolbar button and a status bar item.",
  "license": "MIT",
  "main": "extension.js",
  "engines": { "aigd": ">=0.18.0" },
  "activationEvents": ["onSlashCommand:/my-first", "onCommand:you.my-first-package.hello"],
  "contributes": {
    "commands": [
      { "command": "you.my-first-package.hello", "title": "Say hello", "category": "My First Package", "icon": "$(smile)" }
    ],
    "slashCommands": [
      { "name": "/my-first", "description": "Say hello from my first package", "argumentHint": "[name]" }
    ],
    "menus": {
      "composer/toolbar": [{ "command": "you.my-first-package.hello", "group": "navigation" }]
    },
    "statusBar": [
      { "id": "you.my-first-package.status", "text": "My package", "command": "you.my-first-package.hello", "alignment": "left" }
    ],
    "settings": {
      "name": { "type": "string", "default": "game dev", "description": "Who /my-first greets", "scope": "project" }
    }
  }
}

And the code, extension.js (CommonJS):

const ID = "you.my-first-package";

exports.activate = function activate(ctx) {
  const { aigd } = ctx;
  let count = 0;

  ctx.subscriptions.push(
    aigd.commands.registerCommand(`${ID}.hello`, async () => {
      count++;
      await aigd.window.showInformationMessage(`Hello #${count} from my first package!`);
      return count;
    }),
    // Works in the desktop chat and in the CLI.
    aigd.commands.registerSlashCommand("/my-first", (inv) => {
      const who = inv.args.trim() || aigd.settings.get("name") || "game dev";
      inv.say(`Hi ${who}!`);
    }),
  );

  ctx.log.info("activated");
};

exports.deactivate = function deactivate() {};

The slash command, the toolbar button and the status bar item appear from the manifest before any code runs; activate is called the first time one of them is used.

Ids and naming rules

  • The package id is publisher.name, lowercase: here you.my-first-package. The publisher is 2 to 40 characters (letters, digits, single hyphens). Use your own publisher name; aigd is AI Game Dev's.
  • Every id a package contributes (commands, views, status bar items, tutorials) starts with the package id: you.my-first-package.hello.
  • engines.aigd is required: the oldest AI Game Dev version the package needs, for example ">=0.18.0". An older app refuses the package and says which version it needs.
  • version is semver. Installs are cached by id and version, so every change you publish needs a higher version.

Main manifest fields

FieldRequiredPurpose
publisher, name, versionYesThe id and the version
engines.aigdYesMinimum app version
displayName, description, icon, license, homepage, repository, keywordsNoWhat the Packages window shows
mainNoThe code entry; without it the package is contributions-only
activationEventsNoExtra events that start the code, such as onStartupFinished
hostsNodesktop, cli or both
dependenciesNoOther packages, { "<id>": "<range>" }
claudePluginsNoClaude plugins the package needs, { "<plugin>@<marketplace>": "<range>" }
contributesNoEverything the package adds (below)

Contribution points in contributes include commands, slashCommands, capabilities (switches in the session's Tools row), mcpServers, settings, panels, viewsContainers and views (tree or webview views in the side panels), menus and submenus, keybindings, customEditors, statusBar and tutorials. Menus use fixed ids such as commandPalette, composer/toolbar, explorer/context, editor/title and view/item/context, each with an optional when clause. The CLI shows slash commands, Tools rows, messages, quick picks, input boxes and forms; menus and panels are desktop only.

Give the agent a tool with an MCP server

The most common reason to write a package is to give the agent new tools. Declare an MCP server and a capability that switches it on per session:

{
  "publisher": "you",
  "name": "level-tools",
  "version": "0.1.0",
  "engines": { "aigd": ">=0.18.0" },
  "contributes": {
    "capabilities": [
      {
        "id": "you.level-tools",
        "label": "Level tools",
        "description": "Counts collectibles in the level files.",
        "defaultEnabled": false,
        "mcpServer": "you--level-tools"
      }
    ],
    "mcpServers": {
      "you--level-tools": {
        "command": "${node}",
        "args": ["${packageDir}/server.js"]
      }
    }
  }
}
  • The server name must be <publisher>--<name> (or <publisher>--<name>-<suffix>) of the package id, at most 96 characters, so names from different authors never collide. An unqualified name is an error.
  • Variables you can use in a stdio server: ${node}, ${packageDir}, ${projectDir} and ${globalStorage}.
  • If an MCP server with the same name is already configured in a session, the package's server is not added and the session shows a notice.

Develop against the running app

Point a project at your folder instead of a published version. The folder is used in place, reloads when a file it ships changes, and is never auto-updated. The default level is Local, which is never committed.

cd <your project>
gamedev pkg link <path-to-your-package>      # use the folder (default --local)
gamedev pkg list                             # shows "(local dev)" and which level it overrides
gamedev pkg unlink you.my-first-package      # back to the published version

If your package has a build step (src/ built into dist/), use gamedev pkg dev instead. It runs the package's dev script, or re-runs build after every source change, links the folder after the first successful build and stops every process it started when you press Ctrl+C:

gamedev pkg dev <path-to-your-package>

In the desktop app the same is in the Packages window: select the package and choose Use a local folder…, then Stop using local folder to go back. A folder whose manifest names another id is refused.

Share your package

The AI Game Dev registry carries first-party packages. To share your own, publish it on GitHub or npm; anyone can then add it by link:

gamedev pkg add github:you/my-first-package           # not pinned: receives updates
gamedev pkg add github:you/my-first-package@v0.1.0    # a tag (never auto-updated)
gamedev pkg add npm:my-first-package                  # an npm package
gamedev pkg add npm:my-first-package@^0.1.0           # with a version range

For a team, add it at the Project level so it is committed in .ai-game-dev/packages.json and every teammate gets it, pinned by the project lock file.

Before you publish a new version, raise version in aigd-package.json. A changed file under an unchanged version never reaches an install that already has that version.

Good practice

  • Keep tools focused. Every tool the agent sees takes context; a small, well-described tool is used correctly more often.
  • Declare everything you can in the manifest, so the UI is visible before your code starts.
  • Use scope: "project" for settings the team should share and scope: "machine" for paths on one computer.
  • Packages run with your user's permissions and without a sandbox. Do not ship secrets in a package, and tell users what your package does.

Learn more