Skip to main content

MCP Protocol

MCPProxy implements the Model Context Protocol (MCP) specification, providing AI clients with unified access to multiple upstream MCP servers.

Endpoint

http://127.0.0.1:8080/mcp

Note: The MCP endpoint does not require API key authentication for client compatibility.

Built-in Tools

MCPProxy provides several built-in tools for managing and interacting with upstream servers.

retrieve_tools

Search for tools across all connected servers using BM25 keyword search.

Input Schema:

{
"query": "string (required) - Search keywords",
"limit": "number (optional) - Maximum results, default 15"
}

Example:

{
"query": "create github issue",
"limit": 5
}

call_tool_read

Execute a read-only tool on an upstream server. Use for operations that query data without modifying state.

Input Schema:

{
"name": "string (required) - Tool name in server:tool format",
"args_json": "string (optional) - Tool arguments as JSON string",
"intent": {
"operation_type": "read (required)",
"data_sensitivity": "string (optional) - public|internal|private|unknown",
"reason": "string (optional) - Explanation for audit trail"
}
}

Example:

{
"name": "github:list_repos",
"args_json": "{\"org\": \"myorg\"}",
"intent": {
"operation_type": "read"
}
}

Validation: Rejected if server marks tool as destructiveHint: true.

call_tool_write

Execute a state-modifying tool on an upstream server. Use for operations that create or update resources.

Input Schema:

{
"name": "string (required) - Tool name in server:tool format",
"args_json": "string (optional) - Tool arguments as JSON string",
"intent": {
"operation_type": "write (required)",
"data_sensitivity": "string (optional) - public|internal|private|unknown",
"reason": "string (optional) - Explanation for audit trail"
}
}

Example:

{
"name": "github:create_issue",
"args_json": "{\"repo\": \"owner/repo\", \"title\": \"Bug report\", \"body\": \"Description\"}",
"intent": {
"operation_type": "write",
"reason": "Creating bug report per user request"
}
}

Validation: Rejected if server marks tool as destructiveHint: true.

call_tool_destructive

Execute a destructive tool on an upstream server. Use for operations that delete or permanently modify resources.

Input Schema:

{
"name": "string (required) - Tool name in server:tool format",
"args_json": "string (optional) - Tool arguments as JSON string",
"intent": {
"operation_type": "destructive (required)",
"data_sensitivity": "string (optional) - public|internal|private|unknown",
"reason": "string (optional) - Explanation for audit trail"
}
}

Example:

{
"name": "github:delete_repo",
"args_json": "{\"repo\": \"test-repo\"}",
"intent": {
"operation_type": "destructive",
"data_sensitivity": "private",
"reason": "User confirmed deletion"
}
}

Validation: Most permissive - allowed regardless of server annotations.

Choosing the Right Tool Variant

Use retrieve_tools to discover tools - each result includes a call_with field recommending the appropriate variant based on server annotations.

See Intent Declaration for complete documentation on the two-key security model.

upstream_servers

Manage upstream server configurations.

Actions:

  • list - List all servers
  • add - Add a new server
  • remove - Remove a server
  • enable - Enable a server
  • disable - Disable a server

Example (list):

{
"action": "list"
}

code_execution

Execute JavaScript code to orchestrate multiple tools. Disabled by default.

See Code Execution for complete documentation.

Tool Name Format

Tools from upstream servers are prefixed with the server name:

<serverName>:<originalToolName>

Examples:

  • github:create_issue
  • filesystem:read_file
  • sqlite:query

This prevents naming conflicts when multiple servers provide similar tools.

Quarantine Behavior

When a tool is called on a quarantined server:

  1. The tool call is not executed
  2. A security analysis is returned instead
  3. User must approve the server via Web UI or config

This protects against Tool Poisoning Attacks (TPA).

Connection States

Upstream servers can be in these states:

StateDescription
DisconnectedNot connected to server
ConnectingAttempting to connect
AuthenticatingOAuth flow in progress
ReadyConnected and operational
ErrorConnection failed

Tool Change Notifications

MCPProxy subscribes to the MCP notifications/tools/list_changed notification from upstream servers. This enables automatic tool re-indexing when servers add, remove, or modify their available tools.

How It Works

  1. Server Capability: Servers that support tool change notifications advertise capabilities.tools.listChanged: true during initialization
  2. Notification Handler: MCPProxy registers a notification handler after connecting to each server
  3. Automatic Re-indexing: When a notification is received, MCPProxy triggers DiscoverAndIndexToolsForServer() within seconds
  4. Fallback Behavior: Servers without notification support continue to use the 5-minute background polling cycle

Supported Connection Types

Tool change notifications are supported across all connection types:

  • stdio: Local process servers
  • HTTP/SSE: Remote HTTP-based servers
  • Streamable HTTP: Modern HTTP transport

Resilience Features

  • Deduplication: Rapid successive notifications are deduplicated to prevent redundant discovery
  • Timeout Protection: Discovery operations have a 30-second timeout
  • Graceful Degradation: Errors during discovery are logged but don't crash the proxy

Logs

When notifications are received, MCPProxy logs:

LevelMessage
INFO"Received tools/list_changed notification from upstream server"
DEBUG"Server supports tool change notifications - registered handler"
DEBUG"Tool discovery triggered by notification"
WARN"Received tools notification from server that did not advertise listChanged capability"

Error Handling

MCP errors follow the JSON-RPC 2.0 error format:

{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32600,
"message": "Invalid Request",
"data": {}
}
}