forked from sysown/proxysql
-
Notifications
You must be signed in to change notification settings - Fork 0
Fix: MCP stdio bridge - Make tool responses MCP-compliant and add debugging #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
01c182c
Add stdio MCP bridge for Claude Code integration
renecannao 4491f3c
Add debug logging to MCP bridge for troubleshooting
renecannao fc6b462
Fix: unwrap ProxySQL nested response format
renecannao 6d83ff1
Fix: unwrap ProxySQL response format in MCP tools and fix config syntax
renecannao edac8eb
Fix: Add verbose logging and fix stdout buffering issue in MCP stdio …
renecannao f560698
Fix: Replace stdout with truly unbuffered wrapper to prevent response…
renecannao 55dd5ba
Debug: Add detailed stdout write logging to troubleshoot Claude Code …
renecannao 2b51346
Fix: Wrap tool results in TextContent format for MCP protocol compliance
renecannao ad54f92
Revert: Simplify tool handlers back to original pass-through
renecannao f4a4af8
Fix: Write directly to stdout.buffer to bypass TextIOWrapper issues
renecannao 23e5efc
Test: Don't redirect sys.stderr, write logs directly to file
renecannao a47567f
Revert: Restore original bridge completely
renecannao 77099f7
Debug: Add minimal logging to track stdout writes and tool calls
renecannao 9b4aea0
Fix: Wrap tools/call responses in MCP-compliant content format
renecannao 49e964b
Fix: Make ProxySQL MCP server return MCP-compliant tool responses
renecannao 2ceaac0
docs: Add logging section to bridge README
renecannao 606fe2e
Fix: Address code review feedback from gemini-code-assist
renecannao File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| # ProxySQL MCP stdio Bridge | ||
|
|
||
| A bridge that converts between **stdio-based MCP** (for Claude Code) and **ProxySQL's HTTPS MCP endpoint**. | ||
|
|
||
| ## What It Does | ||
|
|
||
| ``` | ||
| ┌─────────────┐ stdio ┌──────────────────┐ HTTPS ┌──────────┐ | ||
| │ Claude Code│ ──────────> │ stdio Bridge │ ──────────> │ ProxySQL │ | ||
| │ (MCP Client)│ │ (this script) │ │ MCP │ | ||
| └─────────────┘ └──────────────────┘ └──────────┘ | ||
| ``` | ||
|
|
||
| - **To Claude Code**: Acts as an MCP Server (stdio transport) | ||
| - **To ProxySQL**: Acts as an MCP Client (HTTPS transport) | ||
|
|
||
| ## Installation | ||
|
|
||
| 1. Install dependencies: | ||
| ```bash | ||
| pip install httpx | ||
| ``` | ||
|
|
||
| 2. Make the script executable: | ||
| ```bash | ||
| chmod +x proxysql_mcp_stdio_bridge.py | ||
| ``` | ||
|
|
||
| ## Configuration | ||
|
|
||
| ### Environment Variables | ||
|
|
||
| | Variable | Required | Default | Description | | ||
| |----------|----------|---------|-------------| | ||
| | `PROXYSQL_MCP_ENDPOINT` | Yes | - | ProxySQL MCP endpoint URL (e.g., `https://127.0.0.1:6071/mcp/query`) | | ||
| | `PROXYSQL_MCP_TOKEN` | No | - | Bearer token for authentication (if configured) | | ||
| | `PROXYSQL_MCP_INSECURE_SSL` | No | 0 | Set to 1 to disable SSL verification (for self-signed certs) | | ||
|
|
||
| ### Configure in Claude Code | ||
|
|
||
| Add to your Claude Code MCP settings (usually `~/.config/claude-code/mcp_config.json` or similar): | ||
|
|
||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "proxysql": { | ||
| "command": "python3", | ||
| "args": ["/home/rene/proxysql-vec/scripts/mcp/proxysql_mcp_stdio_bridge.py"], | ||
| "env": { | ||
| "PROXYSQL_MCP_ENDPOINT": "https://127.0.0.1:6071/mcp/query", | ||
| "PROXYSQL_MCP_TOKEN": "your_token_here", | ||
| "PROXYSQL_MCP_INSECURE_SSL": "1" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Quick Test from Terminal | ||
|
|
||
| ```bash | ||
| export PROXYSQL_MCP_ENDPOINT="https://127.0.0.1:6071/mcp/query" | ||
| export PROXYSQL_MCP_TOKEN="your_token" # optional | ||
| export PROXYSQL_MCP_INSECURE_SSL="1" # for self-signed certs | ||
|
|
||
| python3 proxysql_mcp_stdio_bridge.py | ||
| ``` | ||
|
|
||
| Then send a JSON-RPC request via stdin: | ||
| ```json | ||
| {"jsonrpc": "2.0", "id": 1, "method": "tools/list"} | ||
| ``` | ||
|
|
||
| ## Supported MCP Methods | ||
|
|
||
| | Method | Description | | ||
| |--------|-------------| | ||
| | `initialize` | Handshake protocol | | ||
| | `tools/list` | List available ProxySQL MCP tools | | ||
| | `tools/call` | Call a ProxySQL MCP tool | | ||
| | `ping` | Health check | | ||
|
|
||
| ## Available Tools (from ProxySQL) | ||
|
|
||
| Once connected, the following tools will be available in Claude Code: | ||
|
|
||
| - `list_schemas` - List databases | ||
| - `list_tables` - List tables in a schema | ||
| - `describe_table` - Get table structure | ||
| - `get_constraints` - Get foreign keys and constraints | ||
| - `sample_rows` - Sample data from a table | ||
| - `run_sql_readonly` - Execute read-only SQL queries | ||
| - `explain_sql` - Get query execution plan | ||
| - `table_profile` - Get table statistics | ||
| - `column_profile` - Get column statistics | ||
| - `catalog_upsert` - Store data in the catalog | ||
| - `catalog_get` - Retrieve from the catalog | ||
| - `catalog_search` - Search the catalog | ||
| - And more... | ||
|
|
||
| ## Example Usage in Claude Code | ||
|
|
||
| Once configured, you can ask Claude: | ||
|
|
||
| > "List all tables in the testdb schema" | ||
| > "Describe the customers table" | ||
| > "Show me 5 rows from the orders table" | ||
| > "Run SELECT COUNT(*) FROM customers" | ||
|
|
||
| ## Logging | ||
|
|
||
| For debugging, the bridge writes logs to `/tmp/proxysql_mcp_bridge.log`: | ||
|
|
||
| ```bash | ||
| tail -f /tmp/proxysql_mcp_bridge.log | ||
| ``` | ||
|
|
||
| The log shows: | ||
| - stdout writes (byte counts and previews) | ||
| - tool calls (name, arguments, responses from ProxySQL) | ||
| - Any errors or issues | ||
|
|
||
| This can help diagnose communication issues between Claude Code, the bridge, and ProxySQL. | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Debug Mode | ||
|
|
||
| If tools aren't working, check the bridge log file for detailed information: | ||
|
|
||
| ```bash | ||
| cat /tmp/proxysql_mcp_bridge.log | ||
| ``` | ||
|
|
||
| Look for: | ||
| - `"tools/call: name=..."` - confirms tool calls are being forwarded | ||
| - `"response from ProxySQL:"` - shows what ProxySQL returned | ||
| - `"WRITE stdout:"` - confirms responses are being sent to Claude Code | ||
|
|
||
| ### Connection Refused | ||
| Make sure ProxySQL MCP server is running: | ||
| ```bash | ||
| curl -k https://127.0.0.1:6071/mcp/query \ | ||
| -X POST \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"jsonrpc": "2.0", "method": "ping", "id": 1}' | ||
| ``` | ||
|
|
||
| ### SSL Certificate Errors | ||
| Set `PROXYSQL_MCP_INSECURE_SSL=1` to bypass certificate verification. | ||
|
|
||
| ### Authentication Errors | ||
| Check that `PROXYSQL_MCP_TOKEN` matches the token configured in ProxySQL: | ||
| ```sql | ||
| SHOW VARIABLES LIKE 'mcp-query_endpoint_auth'; | ||
| ``` | ||
|
|
||
| ## Requirements | ||
|
|
||
| - Python 3.7+ | ||
| - httpx (`pip install httpx`) | ||
| - ProxySQL with MCP enabled |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic for handling successful tool executions and the fallback case contains duplicated code for wrapping the response in the MCP format. This can be refactored to reduce redundancy and improve maintainability.
Additionally, if the tool's result is already a string, calling
.dump()on it will add extra quotes, which is likely not the desired behavior. It's better to check if the result is a string and use its value directly in that case.The suggested refactoring addresses both of these points by first determining the content to be wrapped and then performing the wrapping in a single, shared block of code.