Agents SDK

Tools and MCPs

21st Agents supports two MCP paths. Your own tools run inside the sandbox runtime. Third-party MCP servers are declared inline with mcpServers on the agent and injected with credentials at session time. The legacy sibling .mcp.json path still works for backward compatibility.

For how credentials are stored and injected into outbound requests — including non-MCP services — see Credential vaults.

Two MCP paths

Your agent tools

  • Defined in your agent definition
  • Executed by the runtime process inside the E2B sandbox
  • Runtime env vars can be used by tools without being exposed as ordinary env vars to the isolated agent process

Third-party MCP servers

  • Declared inline with mcpServers on the agent config
  • Remote HTTP MCP only in the current platform path
  • Resolved at session time from ordered workspace vaults via vaultIds
  • Proxied through the 21st relay instead of putting third-party secrets inside the sandbox
  • Legacy .mcp.json deployments still work
💡 Note — If a tool needs to read or change the active sandbox, do it from inside the tool with local filesystem APIs. If your backend service needs to read or change a sandbox from outside, use AgentClient on the Server SDK.

Inline mcpServers

The canonical path is to define remote MCP servers directly in your agent config.

agents/my-agent/index.ts
import { agent } from "@21st-sdk/agent"

export default agent({
  model: "claude-sonnet-4-6",
  mcpServers: [
    {
      name: "github",
      url: "https://api.githubcopilot.com/mcp/",
    },
    {
      name: "linear",
      url: "https://mcp.linear.app/mcp",
    },
  ],
  systemPrompt: `You are a full-stack coding assistant.
Use the configured MCP servers whenever they are helpful.`,
})

Attaching a vault to a run

Pass vaultIds on threads.run. The relay matches each declared MCP server URL against credentials in the attached vaults, first-match-wins.

server.ts
import { AgentClient } from "@21st-sdk/node"

const client = new AgentClient({
  apiKey: process.env.AGENTS_API_KEY!,
})

const result = await client.threads.run({
  agent: "repo-agent",
  sandboxId: "sbx_123",
  vaultIds: ["vault_123"],
  messages: [
    {
      role: "user",
      parts: [{ type: "text", text: "Search our GitHub MCP for the latest auth issues." }],
    },
  ],
})
💡 Note — Resolution order, multi-tenant patterns via externalUserId, OAuth refresh, default workspace vault, and credential limits all live on Credential vaults. This page stays focused on MCP-specific concerns.

Skills vs external MCP servers

The mechanism is similar, but the file location is different:

Skill

  • Lives in .claude/skills/<name>/SKILL.md
  • Contains reusable instructions and reference material
  • Usually referenced from the system prompt

MCP server

  • Usually lives inline in the agent config via mcpServers
  • Legacy sibling .mcp.json is still supported
  • Provides an interface for external tools

Legacy .mcp.json compatibility

If you already have a sibling .mcp.json next to your agent entrypoint, the CLI still uploads it during deploy.

Use either inline mcpServers or legacy .mcp.json, but not both for the same agent.

Do not put MCP config at /home/user/workspace/.mcp.json or inside template/.

Legacy .mcp.json format

For legacy deployments, the file still uses Claude Code's standard MCP config format. See Claude's MCP docs for the native format and supported options.

Keep secrets as placeholders here, for example Bearer ${NIA_TOKEN}, and set the real value through dashboard env vars.

⚠️ Warning — Do not hardcode secrets directly in .mcp.json. Use placeholders + agent env vars, or prefer a vault-based credential on Credential vaults.
.mcp.json
{
  "mcpServers": {
    "nia": {
      "type": "http",
      "url": "https://apigcp.trynia.ai/mcp",
      "headers": {
        "Authorization": "Bearer public-demo-token"
      }
    },
    "svelte": {
      "command": "npx",
      "args": ["-y", "@sveltejs/mcp"]
    }
  }
}

Placing .mcp.json in your project

For deployed agents, create a sibling .mcp.json file next to index.ts, index.js, or index.go.

The deploy CLI uploads that file automatically. Do not add it through Sandbox({ files }) or template/.

Sandbox setup still starts from the Sandbox page.

agents/my-agent/index.ts
import { agent } from "@21st-sdk/agent"

export default agent({
  model: "claude-sonnet-4-6",
  mcpServers: [
    {
      name: "github",
      url: "https://api.githubcopilot.com/mcp/",
    },
    {
      name: "linear",
      url: "https://mcp.linear.app/mcp",
    },
  ],
  systemPrompt: `You are a full-stack coding assistant.
Use the configured MCP servers whenever they are helpful.`,
})

Also create agents/my-agent/.mcp.json with the JSON above. The platform picks up that sibling file during deploy and wires the MCP servers into the runtime automatically.

More resources

  • Credential vaults — how credentials are stored, injected, resolved across vaults, and refreshed (OAuth).
  • Skills — reusable instructions and reference material referenced from the system prompt.
  • Sandbox — the runtime environment your tools and MCP servers execute in.
  • Claude MCP docs — the native .mcp.json format reference.
Tools and MCPs - 21st Agents SDK Docs