Bridge utility enabling Claude Desktop to connect to HTTP-based MCP servers via stdio transport
Project description
MCP HTTP-to-STDIO Bridge for Claude Desktop Integration
This Python script enables Claude Desktop to connect to MyAlly's Share Server via the MCP protocol.
Overview
Purpose: Bridge Claude Desktop's stdio-based MCP protocol to MyAlly's HTTP-based Share Server MCP endpoint.
Architecture:
Claude Desktop (stdio) ←→ mcp_http_to_stdio.py (HTTP) ←→ MyAlly Share Server
Prerequisites
- Python 3.8+
- MyAlly backend running (Share Server must be mounted)
- Valid share key from workspace owner
Installation
Option 1: Install from PyPI (Recommended)
pip install mcp-http-to-stdio
This will install the package globally and make the mcp-http-to-stdio command available system-wide.
Option 2: Install from Source
If you're developing or testing:
git clone https://github.com/your-org/agentic-enterprise.git
cd agentic-enterprise/packages/mcp-http-to-stdio
pip install -e .
Getting a Share Key
-
Ensure MyAlly backend is running:
cd services/myally start_backend.bat # Windows ./start_backend.sh # Linux/macOS
-
Obtain a share key from the workspace owner:
- Owner goes to Settings → Workspace Sharing → Manage Keys
- Owner creates a share key for your email
- Owner reveals and copies the share key (starts with
ally_share_)
Configuration for Claude Desktop
Location of Configuration File
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
Configuration Format
After PyPI Installation (Recommended)
If you installed via pip install mcp-http-to-stdio:
{
"mcpServers": {
"myally-workspace": {
"command": "mcp-http-to-stdio",
"args": [
"--url",
"http://localhost:8081/share/mcp"
],
"env": {
"ALLY_SHARE_KEY": "ally_share_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}
From Source Installation
If you're running from source:
{
"mcpServers": {
"myally-workspace": {
"command": "python",
"args": [
"-m",
"mcp_http_to_stdio",
"--url",
"http://localhost:8081/share/mcp"
],
"env": {
"ALLY_SHARE_KEY": "ally_share_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}
Important:
- Replace
ally_share_xxx...inenv.ALLY_SHARE_KEYwith your actual share key - If Share Server is on a different host/port, update the
--urlparameter - Security: Share key is passed via environment variable (not visible in process list)
Remote Server Configuration
If MyAlly backend is running on a remote server:
{
"mcpServers": {
"myally-remote": {
"command": "mcp-http-to-stdio",
"args": [
"--url",
"https://myally-server.example.com/share/mcp"
],
"env": {
"ALLY_SHARE_KEY": "ally_share_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}
Usage
After configuring Claude Desktop:
- Restart Claude Desktop to load the new MCP server
- Verify connection: Type in Claude: "What MCP tools are available?"
- Use shared workspaces: Claude will see shared workspaces as tools with names from the
mcp_tool_namefield
Example Interaction
You: What workspaces are shared with me?
Claude: I can see the following shared workspaces via MCP:
- ally_project_alpha: Development workspace for Project Alpha
- ally_docs_team: Team documentation workspace
You: Query the ally_project_alpha workspace: What files are in the project?
Claude: [Uses the ally_project_alpha MCP tool to query the shared workspace]
Conversation Continuity
Each workspace tool maintains conversation history through the conversation_id parameter, enabling multi-turn interactions with full context.
How It Works
Every response includes the conversation_id in two places:
-
In the response text (at the beginning):
<conversationId>conv_abc123...</conversationId> [Actual response content here] -
In response metadata (programmatic access):
{ "result": { "content": [...], "_meta": { "conversation_id": "conv_abc123...", "workspace_id": "ws_xyz...", "tool_name": "sales_knowledge" } } }
Starting a New Conversation
Omit the conversation_id parameter:
{
"name": "sales_knowledge",
"arguments": {
"query": "What are our top 5 customers?"
}
}
Response:
<conversationId>conv_abc123...</conversationId>
Here are the top 5 customers:
1. Acme Corp - $500K
2. TechStart - $350K
...
Continuing a Conversation
Include the conversation_id from the previous response:
{
"name": "sales_knowledge",
"arguments": {
"query": "Show me details for the top 3",
"conversation_id": "conv_abc123..."
}
}
Response:
<conversationId>conv_abc123...</conversationId>
Detailed information for Acme Corp, TechStart, and BlueSky Inc:
Acme Corp:
- Total revenue: $500K
- Contract date: 2024-01-15
...
Claude will have full context from the previous query about "top 5 customers" and understand that "the top 3" refers to those customers.
Example Multi-Turn Conversation
User: Ask sales_knowledge: "What accounts did we close last month?"
Claude: [Calls tool with no conversation_id]
Response: <conversationId>conv_abc123...</conversationId>
We closed 3 accounts last month: Acme Corp, TechStart, BlueSky Inc...
User: "What was the total value?"
Claude: [Calls tool with conversation_id="conv_abc123..."]
Response: <conversationId>conv_abc123...</conversationId>
The total value of accounts closed last month was $1.2M...
User: "Which one was the largest?"
Claude: [Calls tool with conversation_id="conv_abc123..."]
Response: <conversationId>conv_abc123...</conversationId>
Acme Corp was the largest at $500K...
Best Practices
- Extract conversation_id: Claude should parse the
<conversationId>tag from each response - Reuse for follow-ups: Pass the same conversation_id for contextual queries
- Start fresh when needed: Omit conversation_id for unrelated topics
- One conversation per topic: Don't mix unrelated queries in the same conversation
- Visible in responses: The XML tag makes the ID clearly visible for debugging
Error Handling
Invalid conversation_id format:
{"error": "Invalid conversation_id format: must start with 'conv_'"}
Conversation not found:
{"error": "Conversation conv_invalid... not found"}
Wrong workspace:
{"error": "Conversation conv_xyz... does not belong to workspace 'sales_knowledge'"}
Technical Details
- Format:
conv_followed by UUID (e.g.,conv_f47ac10b-58cc-4372-a567-0e02b2c3d479) - Validation: Server validates format, existence, and workspace ownership
- SDK Sessions: Backend automatically maintains Claude SDK session_id for conversation history
- Cross-workspace: conversation_ids are workspace-specific (can't use across different tools)
Command Line Arguments
python mcp_http_to_stdio.py --help
Arguments:
--share-key(required): Your share key for authentication--url(optional): Share Server MCP endpoint URL (default:http://localhost:8081/share/mcp)--timeout(optional): Request timeout in seconds (default: 300)
Logging
Logs are written to two locations:
- File:
mcp_http_to_stdio.log(in the same directory as the script) - stderr: Visible in Claude Desktop's developer console
Viewing Logs
During development:
tail -f mcp_http_to_stdio.log
In Claude Desktop:
- Enable developer mode in settings
- Open developer console
- Look for MCP-related messages
Troubleshooting
Issue: "Invalid or expired share key"
Cause: Share key is incorrect, expired, or deleted
Solution:
- Verify share key is correct (starts with
ally_share_) - Ask workspace owner to regenerate key if expired
- Check backend logs:
services/myally/dist/logs/backend.log
Issue: "Connection refused" or "Failed to connect"
Cause: MyAlly backend is not running or URL is incorrect
Solution:
- Verify backend is running:
curl http://localhost:8080/api/v1/health(main backend) - Verify Share Server is running:
curl http://localhost:8081/share/health - Check Share Server status in UI: Settings → Workspace Sharing → Server Status
- Verify URL in configuration matches backend location
Issue: "Tool not found" or "No shared workspaces"
Cause: No workspaces are shared with your user, or workspace sharing is not enabled
Solution:
- Ask workspace owner to share workspace with your email
- Verify owner enabled sharing: Settings → Workspace Sharing → Share Workspace (toggle ON)
- Verify owner granted you access: Settings → Workspace Sharing → Manage Access (your email checked)
Issue: Claude Desktop doesn't see the MCP server
Cause: Configuration file is malformed or in wrong location
Solution:
- Verify JSON syntax is valid (use https://jsonlint.com)
- Check file location matches your OS
- Restart Claude Desktop after configuration changes
- Check Claude Desktop logs for MCP initialization errors
Security Notes
- Share keys are sensitive: Treat them like passwords
- Do not commit share keys to version control
- Rotate share keys regularly: Owner can delete and regenerate in UI
- Rate limiting: 10 failed authentication attempts = 30-minute IP ban
- Encryption: Share keys are bcrypt-hashed in backend database
Advanced Configuration
Multiple Workspaces from Different Owners
You can add multiple MCP servers, one per share key:
{
"mcpServers": {
"myally-project-alpha": {
"command": "python",
"args": [
"/path/to/mcp_http_to_stdio.py",
"--share-key", "ally_share_key_from_owner_1",
"--url", "http://localhost:8080/share/mcp"
]
},
"myally-docs-team": {
"command": "python",
"args": [
"/path/to/mcp_http_to_stdio.py",
"--share-key", "ally_share_key_from_owner_2",
"--url", "http://localhost:8080/share/mcp"
]
}
}
}
Performance Configuration
Custom Timeout
Default timeout is 5 minutes (300 seconds). To customize, add the --timeout parameter:
{
"mcpServers": {
"myally-workspace": {
"command": "python",
"args": [
"/path/to/mcp_http_to_stdio.py",
"--share-key", "ally_share_xxx...",
"--url", "http://localhost:8081/share/mcp",
"--timeout", "600"
]
}
}
}
Timeout parameter:
--timeout(optional): Request timeout in seconds (default: 300)- Increase for complex queries that require extensive tool usage
- Decrease for simple queries if you want faster failure detection
Connection Pooling
The wrapper automatically configures optimized connection pooling:
Features:
- Keep-alive: HTTP connections are reused between requests
- Retry logic: Automatic retry on transient errors (429, 500-504) with exponential backoff
- Connection pool: 10 cached connections to prevent reconnection overhead
- Performance: Reduces "Resetting dropped connection" messages
Connection Pool Configuration:
- Max retries: 3 attempts
- Backoff factor: 1 second (1s, 2s, 4s delays)
- Pool size: 10 connections
- Keep-alive: Enabled by default
These settings are optimized for typical workspace query patterns and do not require tuning.
Technical Details
Protocol Flow
-
Claude Desktop sends JSON-RPC request via stdin:
{"jsonrpc": "2.0", "method": "tools/list", "id": 1}
-
Wrapper forwards to Share Server via HTTP POST:
POST /share/mcp HTTP/1.1 Host: localhost:8081 x-ally-share-key: ally_share_xxx... Content-Type: application/json {"jsonrpc": "2.0", "method": "tools/list", "id": 1}
-
Share Server authenticates and processes:
- Validates share key (bcrypt comparison)
- Returns list of accessible workspaces as MCP tools
-
Wrapper returns response via stdout:
{ "jsonrpc": "2.0", "result": { "tools": [ { "name": "ally_project_alpha", "description": "Development workspace for Project Alpha", ... } ] }, "id": 1 }
Supported MCP Methods
tools/list: Discover shared workspaces as toolstools/call: Execute query against shared workspace (buffered response)
Performance Characteristics
Typical Response Times:
initialize: <100ms (protocol handshake)tools/list: <500ms (database query)tools/call: 10-60 seconds (agent execution + tool usage)
Why tool calls are slow:
The tools/call method executes a full agent query in the shared workspace:
Claude Desktop → Wrapper → Share Server → Agent Queue → Worker → Claude API
↓
Tool Execution
(directory_tree, read_files, etc.)
↓
Multiple Turns
(reasoning + tool usage)
Factors affecting execution time:
- Query complexity: Simple info retrieval vs. multi-step reasoning
- Tool usage: Number and type of tools invoked by agent
- Workspace size: Large codebases take longer to index/search
- API latency: Network latency to Anthropic API
- Max turns: Higher
max_turnsparameter allows more reasoning cycles
Expected behavior:
- ✅ 10-30 seconds: Normal for typical workspace queries
- ⚠️ 30-60 seconds: Expected for complex multi-tool queries
- ❌ 60+ seconds: Consider reducing
max_turnsor simplifying query
Performance logging:
The wrapper logs timing information for monitoring:
2025-10-30 17:50:52 - INFO - Executing tool call: sales_knowledge
2025-10-30 17:51:20 - INFO - Request completed in 28.45s
2025-10-30 17:51:20 - WARNING - Slow request detected (28.45s) - this is expected for complex agent queries
Connection stability:
The wrapper uses persistent HTTP connections with keep-alive. You may see these debug messages:
DEBUG - Resetting dropped connection: localhost
This is normal behavior - urllib3 is simply re-establishing an idle connection. The wrapper's connection pooling ensures minimal overhead.
Authentication Flow
1. Client includes x-ally-share-key header
2. Share Server validates key:
- Checks if key exists in database
- Verifies bcrypt hash matches
- Checks if key is revoked
3. If valid: Execute query as workspace owner (impersonation)
4. If invalid: Return 401 error + increment rate limit counter
Related Documentation
- Share Server Overview:
REQUIREMENTS/WORKSPACE-remote.md - Implementation Guide:
REQUIREMENTS/WORKSPACE-remote-implementation-steps.md - Backend Architecture:
services/myally/README.md - Share Server Code:
services/myally/app/workspace_share_server/
Support
For issues or questions:
- Check backend logs:
services/myally/dist/logs/backend.log - Check wrapper logs:
mcp_http_to_stdio.log - Review Share Server status in MyAlly UI
- Open GitHub issue with logs and configuration (redact share keys!)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_http_to_stdio-0.1.0.tar.gz.
File metadata
- Download URL: mcp_http_to_stdio-0.1.0.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
adcb0e48cb61c57f208fef9a594b33ab591b41e7c1c9cbed9ad24095970623c7
|
|
| MD5 |
8755dcd5b64e069ebf390a6d9b744802
|
|
| BLAKE2b-256 |
5d8e842d9003525a4fc793c608bfe6ebf2dae6db41a7dde6fc7a6b1de9ac083e
|
File details
Details for the file mcp_http_to_stdio-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcp_http_to_stdio-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07d8d9896b752fa1227f1740d4b4bd4e7b11b3f41d5e066a1d38df65b58c7fa3
|
|
| MD5 |
5b71f0885deb3e7449cf8fe32e333e8c
|
|
| BLAKE2b-256 |
e768d206b929a32a6946bac305c9ca4bd7357d201f818907d6361d38614bdcca
|