Registering MCP Servers

MCP server definitions are stored persistently in agentd's SQLite-backed McpStore. A registered definition is a blueprint; no connection is made until the server is attached to an agent.

Add a server

Stdio transport

Use stdio when the MCP server runs as a local subprocess. agentd spawns the process and communicates over its stdin/stdout.

ash mcp add my-server stdio \
  --command /usr/local/bin/my-mcp-server \
  --args "--port,8080,--verbose" \
  --description "My local MCP tool server"
FlagRequiredDescription
nameYes (positional)Unique server name used in tool namespacing and attach commands
transportYes (positional)stdio or http
--commandYes (stdio)Absolute path to the executable
--argsNoComma-separated arguments passed to the command
--descriptionNoHuman-readable description shown in ash mcp list

HTTP transport

Use http when the MCP server is already running (local or remote) and accepts HTTP POST requests.

ash mcp add remote-server http \
  --url https://mcp.example.com/api \
  --description "Remote analytics MCP server"
FlagRequiredDescription
--urlYes (http)Base URL; agentd POSTs to <url>/message

List registered servers

ash mcp list

Output includes: name, transport type, command/URL, description, and registered environment variable keys. Secret values are never displayed.

NAME            TRANSPORT  COMMAND/URL                         DESCRIPTION
my-server       stdio      /usr/local/bin/my-mcp-server        My local MCP tool server
remote-server   http       https://mcp.example.com/api         Remote analytics MCP server

Remove a server

ash mcp remove my-server

Removing a definition does not affect agents that currently have the server attached. Use ash mcp detach first if you want to disconnect running agents.

Environment variables and secrets

If the MCP subprocess needs credentials, inject them via environment variable templates:

# Register the secret first
ash secrets add github-token

# Then declare the env template in the manifest (see Manifest Auto-Attach)
# or pass it through a custom manifest's mcp_servers field

In the manifest mcp_servers field:

mcp_servers:
  - name: github
    transport: Stdio
    command: /usr/local/bin/github-mcp
    env_template:
      - ["GITHUB_TOKEN", "{{secret:github-token}}"]

The handle {{secret:github-token}} is resolved to the plaintext value at attach time and injected into the subprocess environment. It is never stored in the database.

What happens at registration

When you run ash mcp add, agentd:

  1. Validates the definition (transport-specific required fields).
  2. Stores the definition in the mcp_servers SQLite table with serialized args and env_template.
  3. Returns a success confirmation.

No subprocess is spawned and no network connection is made until ash mcp attach (or manifest auto-attach at spawn time).