Skip to main content

MCP Server

Connect your agent to any Model Context Protocol server — Notion, Linear, Sentry, GitHub's MCP, your own self-hosted server — and give the LLM the server's tools. The Pai sidecar injects the bearer token on outbound HTTPS; the agent never holds the real credential.

Get credentials

Get a bearer token or API key from the MCP server vendor:

  • Hosted MCP servers (Notion, Linear, Sentry, etc.) — follow the vendor's instructions. Typically a developer console lets you create an API key.
  • Self-hosted / stdio servers (the official MCP reference servers, in-house servers) — often unauthenticated. You can skip this step if the server doesn't require a token.

Setup

Store the token (if any), then create a Provider. Two transport modes:

SSE (hosted servers)

Most hosted MCP servers use SSE over HTTPS:

# 1. Store the bearer token in a Pai secret
pai add secret linear-mcp-token --from-literal token=lin_api_YOUR_TOKEN

# 2. Create the Provider
pai apply -f - <<EOF
apiVersion: pai.io/v1
kind: Provider
metadata:
name: linear
spec:
type: mcp
mcp:
url: https://mcp.linear.app/sse
transport: sse
auth:
type: api-key
secretRef: linear-mcp-token
policy:
mcp:
allowedTools: [list_issues, create_issue, search_issues]
deniedTools: [delete_issue]
EOF

stdio (self-hosted subprocess)

For MCP servers that run as a subprocess (e.g. the official reference servers):

apiVersion: pai.io/v1
kind: Provider
metadata:
name: filesystem
spec:
type: mcp
mcp:
transport: stdio
command: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
# no auth: stdio servers typically don't need one

Include the server binary in the Agent's packages so it's installed before the harness starts:

spec:
packages:
npm: ["@modelcontextprotocol/server-filesystem"]

Config fields

FieldDescription
mcp.transportsse (default) or stdio
mcp.urlSSE endpoint URL (required for transport: sse)
mcp.commandCommand + args to launch the server (required for transport: stdio)
auth.secretRefPai secret containing the bearer token. Optional for stdio; required for authenticated SSE servers
policy.mcp.allowedToolsTool names the agent may call. Empty = all permitted
policy.mcp.deniedToolsTool names blocked. Evaluated before allowedTools

Attach to an agent

spec:
providers:
- linear

What happens next depends on the agent mode:

  • Harness-backed agents (task / template) — Pai's harness includes a built-in MCP client. At startup it calls tools/list on the server, applies the allowedTools / deniedTools filter, and registers each tool with the LLM as linear__<tool_name>. The agent can invoke them directly.

  • Service agents (spec.type: service) — your runtime (OpenClaw, LangChain, a hand-rolled loop) is its own MCP client. Pai handles auth and policy; you still need to tell your runtime to connect to the upstream URL. Typical setup:

    spec:
    type: service
    image: ghcr.io/myorg/my-agent:latest
    providers: [linear] # Pai: sidecar interception + policy
    configFiles:
    - path: /home/node/.openclaw/openclaw.json
    content: |
    {
    "mcpServers": [
    {"name": "linear", "url": "https://mcp.linear.app/sse"}
    ]
    }

    The runtime's config format (.mcp.json, openclaw.json, etc.) is opaque to Pai. Only the outbound HTTPS request matters — the sidecar intercepts, injects the token, and enforces the tool policy.

Access control

policy.mcp.allowedTools / deniedTools gate which tools the agent can call — Pai filters the server's tool catalogue at registration time (harness agents) or at tools/call time (both modes). Combine with audit.enforcement: audit to validate a tool allowlist against live traffic before flipping it to enforce. See the Policy reference for the full field list.

  • MCP Gateway — expose an in-cluster MCP Provider to tools running on developer laptops (Claude Code, Cline, etc.).
  • Agent → Providers — attaching providers to agents and narrowing per-agent.