MCP and Skills¶
The agent gets the MCP servers and skills of its project.
- MCP servers come from
.mcp.jsonin the workspace, read when a conversation starts:
{"mcpServers": {
"github": {"command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"],
"env": {"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"}},
"docs": {"type": "http", "url": "https://docs.example.com/mcp",
"headers": {"Authorization": "Bearer ${DOCS_TOKEN}"}}
}}
${VAR} and ${VAR:-default} take their values from --secret and --env, so tokens stay out of the file: a2a-serve config set --secret GITHUB_TOKEN. A server with a variable that has no value is skipped, and status names the variable. Servers that run a command run inside the sandbox.
To turn a server off, run a2a-serve config set --disable-mcp github. To turn it back on, run a2a-serve config unset disable-mcp github. The change applies to the next conversation, and status shows the server as off. The first-run wizard turns off the servers whose variables you skip.
The server passes these servers to the agent when a conversation starts. The Docker sandbox shows the agent a .mcp.json with no servers, so the agent can't start servers from the file on its own. On the first start, a workspace without .mcp.json gets one with no servers.
- Skills in .claude/skills, .opencode/skills and .agents/skills work with both opencode and Claude Code. When two skills share a name, the one in .claude/skills wins. With --sandbox local, only the folders your agent reads on its own work.
The server reads both inside the workspace only. It refuses a .mcp.json that is a symlink to a file outside the workspace, and leaves out skills behind such symlinks, because the agent can create them.
a2a-serve status lists the MCP servers and skills the agent found.
Not in this version: MCP servers and skills from your home directory, and limiting a server to some roles.