# MCP Proxy Gateway
Protect any MCP server with security policies, input validation, rate limiting, and audit logging — without modifying the server's code.
The SolonGate Proxy sits between your MCP client and your MCP server, intercepting every tool call through a security pipeline before it reaches the server. Compatible with Claude Code, Claude Desktop, Cursor, Windsurf, Cline, Zed, and any stdio-based MCP client.
How It Works
MCP Client ──(stdio)──> SolonGate Proxy ──(stdio)──> MCP Server
│
[rate limit]
[input guard]
[policy eval]
[audit log]Every tool call passes through SolonGate's 9-step security pipeline. Dangerous calls (shell execution, path traversal, injection attacks) are blocked before they reach the server. Safe calls pass through transparently.
Works with every MCP client: Claude Code, Claude Desktop, Cursor, Windsurf, Cline, Zed, and any application that supports the Model Context Protocol over stdio.
Quick Setup (2 Minutes)
1Automatic Setup
Run the init command in your project directory. It auto-detects your MCP config and wraps each server with the proxy.
1npx @solongate/proxy@latest init23# Or with options:4npx @solongate/proxy@latest init --policy restricted --all
2Manual Setup
Edit your .mcp.json to wrap your server command with the proxy:
1{2 "mcpServers": {3 "my-server": {4 "command": "node",5 "args": ["./my-mcp-server/dist/index.js"]6 }7 }8}
3Restart Your Client
Restart your MCP client (Claude Code, Claude Desktop, Cursor, Windsurf, Cline, or any other). All tool calls now pass through SolonGate.
Policy Presets
restricted(recommended)Blocks shell execution, eval, and exec tools. Allows reads, writes, and queries. Best for general-purpose security.
read-onlyOnly allows read, list, get, search, and query operations. Blocks all writes, deletes, and execution.
permissiveAllows all tools but still enforces input validation (path traversal, injection detection) and rate limiting. Good for monitoring.
deny-allBlocks all tool calls. Useful for emergency lockdown or testing.
Custom Policy File
Create a JSON policy file for fine-grained control:
1{2 "id": "my-custom-policy",3 "name": "My Custom Policy",4 "version": 1,5 "rules": [6 {7 "id": "deny-dangerous",8 "description": "Block shell and exec tools",9 "effect": "DENY",10 "priority": 100,11 "toolPattern": "*exec*",12 "permission": "EXECUTE",13 "minimumTrustLevel": "UNTRUSTED",14 "enabled": true15 },16 {17 "id": "deny-web",18 "description": "Block web fetch (prevent data exfiltration)",19 "effect": "DENY",20 "priority": 101,21 "toolPattern": "*fetch*",22 "permission": "EXECUTE",23 "minimumTrustLevel": "UNTRUSTED",24 "enabled": true25 },26 {27 "id": "allow-rest",28 "description": "Allow everything else",29 "effect": "ALLOW",30 "priority": 1000,31 "toolPattern": "*",32 "permission": "EXECUTE",33 "minimumTrustLevel": "UNTRUSTED",34 "enabled": true35 }36 ]37}
Then use it with the proxy:
1solongate-proxy --policy ./my-policy.json -- node my-server.js
CLI Options
solongate-proxy [options] -- <server-command> [args...] Options: --policy <preset|file> Policy preset or JSON file (default: restricted) --name <name> Proxy display name --verbose Show detailed error messages --no-input-guard Disable input validation --rate-limit <n> Per-tool rate limit (calls/min) --global-rate-limit <n> Global rate limit (calls/min) --config <file> Load full config from JSON file --api-key <key> SolonGate Cloud API key (cloud policy + audit) --api-url <url> Custom API URL (default: api.solongate.com)
Config File
For complex setups, use a JSON config file:
1{2 "upstream": {3 "command": "node",4 "args": ["./my-server/dist/index.js"],5 "env": { "DATABASE_URL": "..." }6 },7 "policy": "restricted",8 "name": "my-protected-server",9 "verbose": true,10 "rateLimitPerTool": 30,11 "globalRateLimit": 10012}
1solongate-proxy --config solongate.json
Cloud Policy Sync
Connect the proxy to SolonGate Cloud for centrally managed policies and audit logging:
1npx @solongate/proxy@latest --api-key sg_live_xxx --policy restricted -- node my-server.js
When an API key is provided, the proxy will:
- Fetch the latest policy from your SolonGate Cloud dashboard
- Fall back to the local policy if the cloud is unreachable
- Forward audit logs for every tool call decision (fire-and-forget)
Get your API key at dashboard.solongate.com
What Gets Blocked
Blocked by Input Guard
- Path traversal:
../../etc/passwd - Shell injection:
; rm -rf / - Command substitution:
`$(whoami)` - Pipe injection:
| cat /etc/shadow - Oversized inputs (DoS prevention)
Allowed (with restricted)
- File reads:
file_read - File writes:
file_write - Database queries:
db_query - Search operations:
search - Any non-dangerous tool
Create a New MCP Server
Scaffold a new MCP server project with SolonGate protection built in:
1npx @solongate/proxy@latest create my-server
This creates a complete project with SecureMcpServer, TypeScript config, .mcp.json, and all dependencies installed. Your server is protected from day one.
Options: --policy <preset> Policy preset (default: restricted) --no-install Skip dependency installation -h, --help Show help
Inject into Existing Server
Already have an MCP server? Inject SolonGate protection with one command:
1npx @solongate/proxy@latest inject
This auto-detects your TypeScript project, installs the SDK, and swaps McpServer with SecureMcpServer — 2 lines changed, zero handler modifications. A backup is always created.
Options: --file <path> Entry file to modify (default: auto-detect) --dry-run Show changes without writing --restore Restore from backup --skip-install Don't install SDK package
1import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';23const server = new McpServer({ name: 'my-server', version: '1.0' });
SecureMcpServer
SecureMcpServer extends McpServer from the official MCP SDK. It auto-wraps every .tool() call with policy evaluation, input validation, and rate limiting — no changes to your tool handlers.
1import { SecureMcpServer, createPermissivePolicySet } from '@solongate/sdk';2import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';3import { z } from 'zod';45const server = new SecureMcpServer(6 { name: 'my-server', version: '1.0.0' },7 { policySet: createPermissivePolicySet() },8);910// Your tool handlers work exactly the same11server.tool('read_file', { path: z.string() }, async ({ path }) => ({12 content: [{ type: 'text', text: 'file contents...' }],13}));1415await server.connect(new StdioServerTransport());
Policy presets: createPermissivePolicySet() (allow all, still validates input), or pass a custom policy from your dashboard.
Restore Original Config
If you used solongate init or inject, a backup was created. To restore:
1npx @solongate/proxy@latest init --restore2# or3npx @solongate/proxy@latest inject --restore