agentafk
Guides

Connect MCP tools and install plugins

Add external tools, skills, commands, and hooks while keeping their trust boundaries explicit.

MCP servers connect afk to external tools and data sources. Plugins add reusable skills, slash commands, named agents, MCP configuration, and optional executable setup code. Install only sources you trust: these extensions can execute programs on your machine.

Connect an MCP server

Add a server configuration

Create ~/.afk/config/mcp.json. This example gives a filesystem server access to a temporary directory on macOS or Linux:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    }
  }
}

Choose a directory appropriate to your platform and the access you intend to grant. npx may download and execute the server package; review it before starting the session.

Start a new session

AFK connects enabled servers during startup. Their tools are named mcp__<server>__<tool>, for example mcp__filesystem__read_file.

Check status and authentication

In the REPL:

/mcp
/tools
/mcp auth

/mcp shows server status, /tools includes exposed tools, and /mcp auth lists pending authorization URLs. If a server is waiting for OAuth, open its URL and use the completion syntax shown by the command: /mcp auth complete <serverName> <code>.

Configuration layers

Server definitions merge by name, with higher-priority definitions replacing the whole server entry rather than merging individual fields.

PrioritySource
HighestCLI --mcp-config <path>
Project<cwd>/.mcp.json, only with AFK_ALLOW_PROJECT_MCP=1
User~/.afk/config/mcp.json
PluginPlugin .claude-plugin/mcp.json contributions
LowestExplicitly trusted imported MCP definitions

A collision produces a warning naming the displaced source. A CLI override is an additional layer, not a clean-room replacement of all other servers. Imported MCP definitions can also be enabled explicitly through migration.

Project MCP is opt-in because a repository can declare a subprocess that runs at startup. Enable AFK_ALLOW_PROJECT_MCP=1 only for a trusted directory. A project config whose real path escapes the working directory is refused. Secret environment expansion for project servers additionally requires an allowSecretEnv allowlist in the operator's user-global server configuration; the project cannot authorize itself.

Server options

FieldPurpose
typestdio, streamable-http, or sse; inferred from command or url when omitted
command, argsExecutable and arguments for a stdio server
envEnvironment overrides for the subprocess
url, headersEndpoint and headers for an HTTP server
oauthEnable the endpoint's OAuth flow
disabledSkip a configured server
alwaysLoadAbort startup if initial connection fails
timeoutTool listing and call timeout in milliseconds, default 30000

Values in env and headers can contain ${VAR} placeholders. Expansion reads environment variables, not shell expressions. Missing variables become empty strings with a warning. Use environment-backed credentials rather than embedding a token in a checked-in file.

For a remote server, the configuration shape is:

{
  "mcpServers": {
    "remote-tools": {
      "type": "streamable-http",
      "url": "https://mcp.example.com/mcp",
      "headers": { "Authorization": "Bearer ${REMOTE_TOOLS_TOKEN}" }
    }
  }
}

This is an illustrative endpoint; use the actual endpoint supplied by your service. An OAuth server uses oauth: true instead of a manually managed bearer header when supported. Pending authorization URLs are also surfaced through Telegram when configured. On macOS, MCP OAuth credentials use the platform keychain; the non-macOS implementation uses the existing Claude credentials file backend.

Startup health checks and failures

Initial connect failures are normally warnings; other servers and the session can continue. alwaysLoad: true makes that initial failure fatal.

For an additional liveness check after the connect burst:

AFK_MCP_HEALTHCHECK=1 afk

This opt-in probe repeats tools/list on connected servers in parallel with a 5-second timeout per server. It catches servers that handshake successfully but then stop responding. Probe failures are warnings, not startup blockers, even though initial alwaysLoad connection failures are blocking. The probe is off by default to avoid an extra startup round trip.

Tool-list change notifications refresh available MCP tools without restarting the session. This does not imply that editing mcp.json reconnects servers live; start a new session after configuration changes.

Surfaces and interactive prompts

MCP is wired into the REPL, afk chat, daemon agent tasks, and Telegram sessions. Each uses its resolved configuration and working directory. The manager belongs to the top-level session; forked subagents do not automatically inherit its MCP tools. Ask the coordinator to make MCP calls when a child needs them.

Servers may request input through elicitation. In the REPL, boolean and enum fields can use a selection menu; other fields accept typed input. Available interaction depends on the surface. Do not design unattended jobs around a server that requires a human response, and do not expect child sessions to answer elicitation prompts.

Install a plugin or marketplace

Use afk plugin install for a repository containing .claude-plugin/plugin.json. The source can be GitHub owner/repository shorthand or an HTTPS Git URL. Add --ref to select a tag, branch, or commit. Without a ref, installation prefers the highest semantic-version tag, then the default branch.

Manage installed extensions

afk plugin list
afk plugin update
afk marketplace list
afk marketplace update

For a specific installed plugin, use afk plugin update <name>, disable <name>, enable <name>, or remove <name>. Marketplace equivalents include update <name> and remove <name>. Use the names reported by the listing, not a guessed directory name. See the CLI reference for pinning, replacement, and noninteractive options.

Plugin installation state lives under ~/.afk/plugins/, with .index.json tracking enabled entries and cache/ holding marketplaces. Discovery understands nested marketplace layouts, but installed/enabled state still matters.

Object-valued marketplace sources

A marketplace entry's source can be a relative path, GitHub shorthand, HTTPS URL, or a supported object. The git-subdir object clones a repository and selects a plugin directory within it:

{
  "name": "example-tools",
  "source": {
    "source": "git-subdir",
    "url": "https://github.com/example/plugin-collection.git",
    "path": "plugins/example-tools",
    "ref": "v1.2.0"
  }
}

The example shows the manifest shape, not a repository you should install. url and path are required; ref and sha are optional. Unsupported or malformed object types remain visible with a skip reason, and installation refuses that entry instead of silently dropping the whole catalog.

What plugins contribute

Plugin path or fieldContribution
skills/<name>/SKILL.mdSkill instructions and metadata
commands/<name>.mdUser-invoked slash command
commands/review/security.mdNamespaced /review:security command
agents/Named agent definitions
.claude-plugin/mcp.jsonMCP server definitions
hooks/hooks.jsonCommand hooks, behind the plugin-hook trust gate
Manifest mainExecutable JavaScript setup module

Legacy Claude Code command files are parsed as prompts and listed by /skills. Their names come from the file path, not frontmatter. They remain user-invoked commands rather than automatically expanding the model's skill-routing catalog. Supported metadata such as description, argument hints, allowed tools, and model goes through the shared skill parser.

User skills can also live at ~/.afk/skills/<name>/SKILL.md without packaging a plugin. See custom skills and named agents for those layouts.

JavaScript entrypoint lifecycle

When a manifest declares main, AFK imports that module during plugin activation before the session's skill manifest is assembled. If it exports a default function, AFK awaits it and passes the host API. Use the supplied API for registration rather than importing a separate runtime copy of agent-afk, which could register against the wrong singleton or fail in a cloned plugin without dependencies.

Activation is once per resolved entrypoint path per process, not once per session. A failing import or activation is reported without aborting session startup, and the same path is not retried during that process. Module-level side effects also run at import time. This is executable code, not sandboxed Markdown.

Plugin hooks

There are two distinct mechanisms:

  1. A plugin can ship hooks/hooks.json. Command hooks load only after you set enablePluginHooks: true in user-global AFK configuration. This is independent of enableShellHooks. Unsupported hook types are skipped with a warning.
  2. A JavaScript entrypoint can call the host's registerHook API. The declaration is installed on subsequently constructed session hook registries; REPL startup also attaches declarations to its already-created registry. Handlers should derive session-specific state from their context. Exceptions are isolated, and plugins cannot disable handler timeouts with longRunning.

Do not assume /reload-plugins hot-reloads hook definitions or reruns JavaScript activation. Restart afk after changing hooks or main. See hooks for event behavior, trust settings, and Claude Code matcher compatibility.

Refresh and inspect

/reload-plugins
/skills
/agents
/mcp
/tools

/reload-plugins invalidates discovery caches and refreshes skill and agent slash registrations, reporting counts, changed names, and installed versions. It is useful after Markdown edits, not a general process or MCP restart.

On this page