> For the complete documentation index, see [llms.txt](/llms.txt).

# Build a plugin

This guide helps you build your own MetaMask Agent Wallet plugin, starting from the [plugin template](https://github.com/MetaMask/agent-wallet-plugin-template). The template ships a working `mm hello ping` command that you can rename and extend, so you have something running before you write any code.

By the end of this guide, you have a plugin that adds your own command to Agent Wallet, tested locally and ready to publish.

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

- Install [Node.js](https://nodejs.org/en/download) v22 or later.

## 1. Clone the template[​](#1-clone-the-template "Direct link to 1. Clone the template")

Clone the [plugin template](https://github.com/MetaMask/agent-wallet-plugin-template) into a directory named after your plugin.

```
git clone https://github.com/MetaMask/agent-wallet-plugin-template my-plugin
cd my-plugin

```

## 2. Install the dependencies[​](#2-install-the-dependencies "Direct link to 2. Install the dependencies")

Use your preferred package manager to install the dependencies.

- npm
- Yarn
- pnpm
- Bun

```
npm install

```

```
yarn install

```

```
pnpm install

```

```
bun install

```

## 3. Update the manifest[​](#3-update-the-manifest "Direct link to 3. Update the manifest")

The `package.json` file declares your plugin's identity and the `mm` block declares what each command does and needs. Replace the template's placeholder values with your own:

- Set `name` and `description`.
- In the `mm` block, update each `commands[].id` to your command id.
- If a command reads wallet data or signs anything, list the capabilities and data access it needs.

Users consent to these capabilities at install time. Keep the plugin-wide `capabilities` list empty because it is merged into every command. See the [plugins reference](/agent-wallet/reference/plugins/) for every manifest field, capability, and data access category.

```
"mm": {
  "schemaVersion": 1,
  "minCliVersion": "^6.2.0",
  "capabilities": [],
  "commands": [
    {
      "id": "hello:balance",
      "capabilities": ["wallet-read"],
      "dataAccess": ["balances"]
    }
  ]
}

```

## 4. Write your command[​](#4-write-your-command "Direct link to 4. Write your command")

Rename the template's command file to match the id you declared in the manifest. The file path defines the command. For example, `src/commands/hello/ping.ts` becomes `mm hello ping` with id `hello:ping`.

To write the command, extend `PluginCommand` from `@metamask/agent-wallet/plugin` and implement `execute`. The template's command shows the full pattern.

Keep the following rules in mind as you write your command:

- You implement only `execute`, plus static configuration and the optional hooks `afterExecute`, `successHint`, and `analyticsOutcome`. The rest of the lifecycle is sealed by the host.
- `pluginCommandId` must match the command's `id` in the plugin manifest.
- `requiresAuth` and `requiresInit` gate sign-in and wallet setup. Both default to `true`.
- Declare inputs once as a schema. `schemaToFlags` and `schemaToArgs` generate the command surface, and `io.resolveInputs` resolves flags, positionals, and interactive prompts.
- The base flags `--json`, `--format`, `--toon`, and `--verbose` are inherited automatically.

```
import {
  type CommandIO,
  InputFieldType,
  type InputSchema,
  PluginCommand,
  schemaToArgs,
  schemaToFlags,
} from '@metamask/agent-wallet/plugin'

const inputs = {
  name: {
    type: InputFieldType.Text,
    flag: 'name',
    message: 'Name to greet',
    required: false,
    prompt: false,
    index: 0,
  },
} satisfies InputSchema

export default class HelloPing extends PluginCommand<{ message: string }> {
  static override description = 'Say hello from the plugin template.'
  static override requiresAuth = false
  static override requiresInit = false
  static override flags = schemaToFlags(inputs)
  static override args = schemaToArgs(inputs)

  protected readonly pluginCommandId = 'hello:ping'

  async execute(io: CommandIO) {
    const { name } = await io.resolveInputs(inputs)
    return { message: name ? `pong, ${name}!` : 'pong' }
  }
}

```

## 5. Build and test locally[​](#5-build-and-test-locally "Direct link to 5. Build and test locally")

Now build your plugin and install it into your local Agent Wallet to try it out. Install from the directory rather than a packed tarball, so Agent Wallet can read your manifest and show the full capability consent screen.

As you iterate, run `mm plugins uninstall <name>` to remove the plugin before you install it again.

- npm
- Yarn
- pnpm
- Bun

```
npm run build
mm config set experimentalPlugins true
mm config set experimentalAllowUnverifiedInstalls true
mm plugins install "file:$PWD" --accept-permissions
mm hello ping Alice

```

```
yarn build
mm config set experimentalPlugins true
mm config set experimentalAllowUnverifiedInstalls true
mm plugins install "file:$PWD" --accept-permissions
mm hello ping Alice

```

```
pnpm run build
mm config set experimentalPlugins true
mm config set experimentalAllowUnverifiedInstalls true
mm plugins install "file:$PWD" --accept-permissions
mm hello ping Alice

```

```
bun run build
mm config set experimentalPlugins true
mm config set experimentalAllowUnverifiedInstalls true
mm plugins install "file:$PWD" --accept-permissions
mm hello ping Alice

```

## 6. Publish[​](#6-publish "Direct link to 6. Publish")

When your plugin works the way you want, publish the package to npm.

Users then install it with `mm plugins install <your-package>` and review a consent screen listing your commands, data access, and requested capabilities.

- npm
- Yarn
- pnpm
- Bun

```
npm publish

```

```
yarn publish

```

```
npm publish
# couldn't auto-convert command

```

```
npm publish
# couldn't auto-convert command

```

## Next steps[​](#next-steps "Direct link to Next steps")

- Browse the [plugin examples repository](https://github.com/MetaMask/agent-wallet-plugin-examples)for complete working plugins, including an ENS resolver built on the authenticated RPC client.
- See the [plugins reference](/agent-wallet/reference/plugins/) for the manifest schema, capability types, and the published SDK surface.
