MCP Connector
TameFlare includes a dedicated MCP connector that parses JSON-RPC 2.0 tools/call messages into structured actions. This gives you per-tool permissions, risk scoring, and structured audit logs for all MCP (Model Context Protocol) traffic.
How it works
MCP uses JSON-RPC 2.0 over two transports:
| Transport | How it works | TameFlare support |
|---|---|---|
| Streamable HTTP | MCP server exposes an HTTP endpoint. Client sends JSON-RPC via POST. Server responds with JSON or SSE. | Full support — intercepted, parsed, and enforced |
| stdio | Client launches MCP server as a subprocess. Communication via stdin/stdout. | Not supported (process-level IPC, not network traffic) |
Production MCP deployments use Streamable HTTP. TameFlare's MCP connector intercepts these requests, parses the JSON-RPC payload, and maps each message to a structured action type.
Action types
The MCP connector parses JSON-RPC messages into three categories:
Tool calls (tools/call)
The most security-relevant MCP message. The connector extracts the tool name from params.name and maps it to mcp.tools.<tool_name>.
| JSON-RPC method | params.name | TameFlare action | Risk |
|---|---|---|---|
| tools/call | create_pull_request | mcp.tools.create_pull_request | medium |
| tools/call | delete_repository | mcp.tools.delete_repository | high |
| tools/call | read_file | mcp.tools.read_file | low |
| tools/call | execute_command | mcp.tools.execute_command | high |
| tools/call | send_email | mcp.tools.send_email | medium |
| tools/call | deploy_service | mcp.tools.deploy_service | high |
Tool discovery (tools/list)
Discovery requests are parsed as mcp.tools.list. These are low risk — the agent is asking what tools are available, not executing one.
| JSON-RPC method | TameFlare action | Risk |
|---|---|---|
| tools/list | mcp.tools.list | low |
Other JSON-RPC methods
Any other JSON-RPC method (e.g., initialize, resources/read, prompts/get) is parsed as mcp.rpc.<method>.
| JSON-RPC method | TameFlare action | Risk |
|---|---|---|
| initialize | mcp.rpc.initialize | low |
| resources/read | mcp.rpc.resources_read | low |
| prompts/get | mcp.rpc.prompts_get | low |
Risk scoring
The MCP connector uses heuristic risk scoring based on tool name patterns:
| Tool name contains | Risk level | Examples |
|---|---|---|
| delete, remove, drop | high | delete_repository, remove_user, drop_table |
| execute, run, deploy, shell | high | execute_command, run_query, deploy_service |
| create, write, send, update, post | medium | create_issue, write_file, send_message |
| read, get, list, search, fetch | low | read_file, get_user, list_repos |
| (no match) | medium | Default for unrecognized tool names |
Risk levels feed into policy evaluation. You can write policies that require approval for high-risk tool calls while allowing low-risk reads.
Setup
1. Add an MCP connector
npx tf connector add mcp \
--domains mcp-server.example.com \
--token-env MCP_AUTH_TOKENThe --domains flag specifies which MCP server hostnames this connector handles. All POST requests to these domains with Content-Type: application/json containing JSON-RPC 2.0 payloads are parsed by the MCP connector.
2. Set permissions
# Allow all tool calls
npx tf permissions set --gateway "my-agent" \
--connector mcp \
--action "mcp.tools.*" \
--decision allow
# Block destructive tools
npx tf permissions set --gateway "my-agent" \
--connector mcp \
--action "mcp.tools.delete_*" \
--decision deny
# Require approval for deployment tools
npx tf permissions set --gateway "my-agent" \
--connector mcp \
--action "mcp.tools.deploy_*" \
--decision require_approval
# Allow discovery
npx tf permissions set --gateway "my-agent" \
--connector mcp \
--action "mcp.tools.list" \
--decision allow3. Run your agent
npx tf run --gateway "my-agent" python mcp_agent.pyAll MCP Streamable HTTP traffic is now intercepted, parsed into structured actions, and enforced against your permissions.
What MCP traffic looks like
A tools/call request on the wire:
POST /mcp HTTP/1.1
Content-Type: application/json
Accept: application/json, text/event-stream
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_pull_request",
"arguments": {
"repo": "acme/backend",
"title": "Fix auth bug",
"head": "fix-auth",
"base": "main"
}
}
}The MCP connector:
- Detects the JSON-RPC 2.0 payload
- Extracts
method→tools/callandparams.name→create_pull_request - Maps to action type
mcp.tools.create_pull_request - Scores risk as
medium(contains "create") - Buffers the request body and restores it for downstream forwarding (no data loss)
- Checks permissions for this gateway + connector + action
- Injects credentials from the vault if allowed
- Logs the structured action in the traffic log
Permission patterns
The wildcard matching system works with MCP action types:
| Pattern | Matches |
|---|---|
| mcp.tools.* | All tool calls |
| mcp.tools.create_* | All tools starting with create_ |
| mcp.tools.delete_* | All tools starting with delete_ |
| mcp.tools.list | Tool discovery only |
| mcp.rpc.* | All non-tool JSON-RPC methods |
| mcp.* | Everything (tools + rpc) |
Example: governed MCP workflow
# Add MCP connector for your GitHub MCP server
npx tf connector add mcp \
--domains github-mcp.internal.com \
--token-env GITHUB_MCP_TOKEN
# Allow reads, block deletes, require approval for writes
npx tf permissions set --gateway "code-agent" --connector mcp \
--action "mcp.tools.read_*" --decision allow
npx tf permissions set --gateway "code-agent" --connector mcp \
--action "mcp.tools.list_*" --decision allow
npx tf permissions set --gateway "code-agent" --connector mcp \
--action "mcp.tools.search_*" --decision allow
npx tf permissions set --gateway "code-agent" --connector mcp \
--action "mcp.tools.create_*" --decision require_approval
npx tf permissions set --gateway "code-agent" --connector mcp \
--action "mcp.tools.delete_*" --decision deny
npx tf permissions set --gateway "code-agent" --connector mcp \
--action "mcp.tools.list" --decision allow
# Run the agent
npx tf run --gateway "code-agent" python agent.pyTraffic log output:
14:32:01 | code-agent | mcp.tools.list | ALLOW | 12ms
14:32:02 | code-agent | mcp.tools.read_file | ALLOW | 45ms
14:32:04 | code-agent | mcp.tools.create_issue | HOLD | waiting...
14:32:18 | code-agent | mcp.tools.create_issue | ALLOW | 89ms (approved)
14:32:20 | code-agent | mcp.tools.delete_branch | DENY | 1ms
Capabilities
| Capability | Status |
|---|---|
| Intercept Streamable HTTP MCP traffic | Supported |
| Parse tools/call into structured actions (mcp.tools.*) | Supported |
| Parse tools/list as discovery action | Supported |
| Parse other JSON-RPC methods (mcp.rpc.*) | Supported |
| Risk scoring by tool name heuristics | Supported |
| Per-tool permissions with wildcards | Supported |
| Credential injection for MCP servers | Supported |
| Kill switch for MCP traffic | Supported |
| Body buffering (no data loss on parse) | Supported |
| SSE response streaming | Supported (transparent tunnel) |
| stdio transport interception | Not supported (use Streamable HTTP) |
FAQ
How is this different from the generic HTTP connector?
The generic connector parses actions by HTTP method only (generic.post, generic.get). The MCP connector parses the JSON-RPC payload to extract the tool name, giving you mcp.tools.create_pull_request instead of generic.post. This enables per-tool permissions and meaningful audit logs.
What about stdio-based MCP servers?
stdio is process-level IPC (stdin/stdout), not network traffic. TameFlare's proxy cannot intercept it. For production MCP deployments, use Streamable HTTP transport — it's the recommended production transport and is fully governed by TameFlare.
Can I use TameFlare with Claude Desktop / Cursor MCP?
If your MCP server uses Streamable HTTP transport and your agent routes through tf run, yes. If the MCP connection is stdio-only (local subprocess), TameFlare cannot intercept it. Many MCP servers support both transports — configure yours to use Streamable HTTP for production.
Does the connector handle SSE responses?
Yes. MCP servers can respond with Server-Sent Events for streaming. TameFlare tunnels SSE responses transparently — the enforcement happens on the inbound request, not the response stream.
What happens if the request body isn't valid JSON-RPC?
Non-JSON-RPC requests to MCP connector domains fall through to a generic action type (mcp.rpc.unknown). The request is still logged and subject to permissions.
Next steps
- Connectors — all 8 built-in connectors
- Writing Policies — create rules for MCP tool calls
- Action Types — full action type reference
- Kill Switch — emergency stop for MCP traffic