MCP Servers
Plug any MCP server into your agent. Playwright, Notion, Linear, GitHub, Slack, custom stdio or SSE servers — if it speaks the Model Context Protocol, Rush agents can use it.
What is MCP?#
The Model Context Protocol is an open spec for how LLM agents discover and call external tools. A single server can expose dozens of tools — a Notion server exposes page read/write, a Playwright server exposes browser control, and so on.
Rush agents consume MCP servers directly. Declare the server in agent.yaml and every tool it exposes becomes available to your agent, with the same permission, label, and UI machinery as built-in tools.
Declare a server#
Add an mcp_servers block to agent.yaml. Each key is the server's local name. Two transport styles:
Stdio transport (most common)
Runs the server as a local subprocess and talks to it over stdin/stdout. This is how all the npx-based public MCP servers work.
mcp_servers:
playwright:
command: npx
args: ["-y", "@anthropic-ai/mcp-playwright"]Copy-pasted from the real agents/rush-tester/playwright-tester.yaml — this is exactly how the in-repo browser testing agent pulls in Playwright-MCP.
SSE transport (for hosted servers)
Connects to a remote HTTP + Server-Sent-Events endpoint. Useful for servers that need OAuth or run on someone else's infrastructure.
mcp_servers:
notion:
url: https://mcp.notion.com/sse
transport: sse
oauth:
provider: notion
required: trueWhen oauth.required: true, the Rush app prompts the user to connect Notion before the agent runs — same integration UI as built-in OAuth tools.
All server config fields#
| Field | Scope | Notes |
|---|---|---|
command | stdio | Binary to run. Must be npx, uvx, bunx, or docker (allowlisted). |
args | stdio | Command arguments. |
env | stdio | Environment variables passed to the process. |
cwd | stdio | Working directory for command execution. |
url | sse | HTTPS endpoint for the SSE server. |
transport | sse | Set to "sse" to force SSE transport. |
oauth | sse | Object: provider (string) and required (bool). |
tools | both | Whitelist of tool names to expose. Empty = all tools from this server. |
tool_hooks | both | Harness hooks to run on tool_start / tool_result / tool_error events. |
tool_ui_components | both | Automatic generative-UI rendering per MCP tool (tool_name -> state -> component). |
Security constraints#
Rush validates every stdio server config before spawning. The guardrails exist because an MCP command runs as a local subprocess with your user's privileges.
| Constraint | Why |
|---|---|
command must be one of npx, uvx, bunx, docker | Sandboxed package managers only. No /bin/sh, no arbitrary binaries. |
| Command cannot be an absolute or relative path | Prevents pointing at a rogue local binary. |
Shell metacharacters banned in args (; | & $ ` > <, ...) | Blocks command injection via argument strings. |
Invalid configs are rejected at rush build time — you won't get a surprise security failure at runtime on a user's machine.
Whitelist specific tools#
A server may expose 30 tools when your agent only needs 3. Narrow the surface:
mcp_servers:
notion:
url: https://mcp.notion.com/sse
transport: sse
oauth: { provider: notion, required: true }
tools:
- notion_search
- notion_page_read
- notion_page_updateAny tool not in tools is filtered out before the LLM sees it. Fewer tools = tighter prompts = fewer accidental calls.
Hook MCP tool events#
MCP tools fire the same event pipeline as built-in tools, so you can observe, cache, rate-limit, or redact them with harness hooks.
mcp_servers:
notion:
url: https://mcp.notion.com/sse
transport: sse
oauth: { provider: notion, required: true }
tool_hooks:
- hook: redact_pii
event: tool_result
targets: [notion_page_read]The hook runs after notion_page_read returns, strips PII, and passes the cleaned result to the LLM.
Render MCP tool output as UI#
Map an MCP tool result to a generative UI component. No extra code — declarative in YAML.
mcp_servers:
linear:
url: https://mcp.linear.app/sse
transport: sse
oauth: { provider: linear, required: true }
tool_ui_components:
linear_list_issues:
completed:
component: issue_list
props:
issues: "{{result.issues}}"When linear_list_issues finishes, the issue_list component renders automatically with the tool output piped into its props.
See Generative UI for the full component catalog.
Real example: playwright-tester#
The in-repo agents/rush-tester/playwright-tester.yaml is a minimal working reference:
name: playwright-tester
developer: Prix
description: Browser automation testing via Playwright MCP
version: 1.0.0
models:
anthropic/claude-sonnet-4.5:
provider: openrouter
mcp_servers:
playwright:
command: npx
args: ["-y", "@anthropic-ai/mcp-playwright"]
tools:
- name: artifactsFour lines of mcp_servers — the agent now has Playwright-MCP's full browser tool surface on top of the harness artifacts tool.