Skip to content

Conversation

@kevalmahajan
Copy link
Member

@kevalmahajan kevalmahajan commented Aug 12, 2025

🐛 Bug-fix PR


📌 Summary

Closes #728
In Translate feature (stdio server to streamable-http server):
Implemented a fix that forwards requests/responses from the Streamable HTTP server to the stdio server using pub/sub, enabling full support for the connection.

🐞 Root Cause

The root cause was that responses from the Streamable HTTP server were not being forwarded to the stdio server, resulting in incomplete communication. Without this forwarding, the connection was established via StreamableHTTPSessionManager but subsequent interactions such as listing tools and handling tool calls failed.

💡 Fix Description

Previously, the multi-protocol server only implemented SSE (/message) and lacked proper handling for the Streamable HTTP protocol’s /mcp POST endpoint. As a result, HTTP clients could not send JSON-RPC requests/notifications or receive responses per the MCP spec.

This fix:

  1. Adds correct /mcp POST handling for Streamable HTTP protocol.
  2. Uses the same pubsub from StdIOEndpoint to correlate stdout JSON-RPC responses to incoming requests.
  3. Implements a bounded wait for matching stdout messages before returning the response.
  4. Maintains existing SSE behavior without regression.

This ensures full compliance with the MCP specification for both SSE and Streamable HTTP modes.

Testing 🛠️

  1. Convert a stdio server to Streamable HTTP and add it to the gateway or MCP Inspector. Verify that all functionalities including listing tools, resources, prompts, and tool invocation work correctly.
python3 -m mcpgateway.translate --stdio "npx @modelcontextprotocol/server-everything" --port 9000 --expose-streamable-http
  1. Test with a multi-protocol server supporting both Streamable HTTP and SSE simultaneously:
python3 -m mcpgateway.translate --stdio "npx @modelcontextprotocol/server-everything" --port 9000 --expose-streamable-http --expose-sse

🧪 Verification

Check Command Status
Lint suite make lint
Unit tests make test
Coverage ≥ 90 % make coverage
Manual regression no longer fails steps / screenshots

📐 MCP Compliance (if relevant)

  • Matches current MCP spec
  • No breaking change to MCP clients

✅ Checklist

  • Code formatted (make black isort pre-commit)
  • No secrets/credentials committed

@rakdutta rakdutta self-requested a review August 13, 2025 04:58
@rakdutta
Copy link
Collaborator

rakdutta commented Aug 13, 2025

PR Testing Summary:

  • make servePass

  • make testPass (80% coverage, 1626 passed, 10 skipped, 57 warnings)

  • make autoflake isort black flake8No errors

  • make pylintError:

    Module mcpgateway.services.resource_service
    mcpgateway/services/resource_service.py:417:19: W0212: Access to a protected member _initialized of a client class (protected-access)
    
    --------------------------------------------------------------------
    Your code has been rated at 10.00/10 (previous run: 10.00/10, -0.00)
    make: *** [Makefile:719: pylint] Error 4
    
  • make smoketestPass (✅ Smoketest passed!)

  • make doctestAll pass (53% coverage, 467 passed, 6 skipped, 1 warning)


Testing Steps Performed:

  1. Convert a stdio server to Streamable HTTP and add it to the gateway:

    python3 -m mcpgateway.translate --stdio "npx @modelcontextprotocol/server-everything" --port 9000 --expose-streamable-http
    • Successfully registered gateway server via UI and API:

      curl -s -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
           -H "Content-Type: application/json" \
           -d '{"name":"fast_time_mcp","url":"http://127.0.0.1:9000/mcp","transport":"STREAMABLEHTTP"}' \
           http://localhost:4444/gateways
  2. Test with a multi-protocol server supporting both Streamable HTTP and SSE:

    python3 -m mcpgateway.translate --stdio "npx @modelcontextprotocol/server-everything" --port 9000 --expose-streamable-http --expose-sse
    • Successfully registered gateway server via UI and API for and Streamable HTTP and SEE

      curl -s -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
           -H "Content-Type: application/json" \
           -d '{"name":"fast_time","url":"http://localhost:9000/sse"}' \
           http://localhost:4444/gateways
      curl -s -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
           -H "Content-Type: application/json" \
           -d '{"name":"fast_time_mcp","url":"http://127.0.0.1:9000/mcp","transport":"STREAMABLEHTTP"}' \
           http://localhost:4444/gateways

Copy link
Collaborator

@madhav165 madhav165 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added sse and mcp servers from translate and both worked from gateway.

  • Connect to gateway
  • Tools work

Signed-off-by: Keval Mahajan <mahajankeval23@gmail.com>
Signed-off-by: Keval Mahajan <mahajankeval23@gmail.com>
@crivetimihai crivetimihai force-pushed the translate_streamablehttp branch from b59c10c to adc9575 Compare August 13, 2025 19:19
Copy link
Member

@crivetimihai crivetimihai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ PR #729 Review Complete

The PR successfully fixes the Streamable HTTP support in the translate feature.

Code Review

  • The changes correctly implement request/response forwarding between Streamable HTTP and stdio servers
  • Proper use of shared pubsub for both SSE and Streamable HTTP protocols
  • Clean implementation with good error handling and timeout management

Testing Results

✅ Rebased against main branch✅ Linting - All checks pass (flake8, pylint)✅ Doctests - 469 passed✅ Unit tests - 1646 passed, translate-specific tests working⚠️ Coverage - 79% (below 90% target, but acceptable for
translate.py)✅ Manual testing - Both single and multi-protocol servers work correctly:

  • Streamable HTTP /mcp endpoint handles initialize, tools/list, and tools/call
  • Multi-protocol server successfully exposes both SSE and Streamable HTTP endpoints
  • Proper JSON-RPC request/response correlation

The implementation properly addresses issue #728 and enables full MCP compliance for both SSE and Streamable HTTP modes. The PR is ready for merge.

Manual testing

pip install .
python3 -m mcpgateway.translate --stdio "npx -y kubernetes-mcp-server@latest" --port 8105 --expose-streamable-http

Works in gateway

- Replace generic Exception with specific json.JSONDecodeError and ValueError
- Addresses bandit security scan warning about try/except/continue pattern

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
- Update name-tests-test hook to exclude files in helpers/ directories
- Prevents false positives for helper modules like trace_generator.py
- Keeps the test naming convention check for actual test files

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
@crivetimihai crivetimihai merged commit 21790d3 into main Aug 14, 2025
35 of 37 checks passed
@crivetimihai crivetimihai deleted the translate_streamablehttp branch August 14, 2025 00:03
vk-playground pushed a commit to vk-playground/mcp-context-forge that referenced this pull request Sep 14, 2025
* Fixed streamable http support for translating stdio servers

Signed-off-by: Keval Mahajan <mahajankeval23@gmail.com>

* minor changes

Signed-off-by: Keval Mahajan <mahajankeval23@gmail.com>

* Fix bandit B112 warning: Use specific exception types

- Replace generic Exception with specific json.JSONDecodeError and ValueError
- Addresses bandit security scan warning about try/except/continue pattern

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* Fix pre-commit hook to exclude test helper files

- Update name-tests-test hook to exclude files in helpers/ directories
- Prevents false positives for helper modules like trace_generator.py
- Keeps the test naming convention check for actual test files

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

---------

Signed-off-by: Keval Mahajan <mahajankeval23@gmail.com>
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Co-authored-by: Mihai Criveti <crivetimihai@gmail.com>
vk-playground pushed a commit to vk-playground/mcp-context-forge that referenced this pull request Sep 14, 2025
* Fixed streamable http support for translating stdio servers

Signed-off-by: Keval Mahajan <mahajankeval23@gmail.com>

* minor changes

Signed-off-by: Keval Mahajan <mahajankeval23@gmail.com>

* Fix bandit B112 warning: Use specific exception types

- Replace generic Exception with specific json.JSONDecodeError and ValueError
- Addresses bandit security scan warning about try/except/continue pattern

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* Fix pre-commit hook to exclude test helper files

- Update name-tests-test hook to exclude files in helpers/ directories
- Prevents false positives for helper modules like trace_generator.py
- Keeps the test naming convention check for actual test files

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

---------

Signed-off-by: Keval Mahajan <mahajankeval23@gmail.com>
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Co-authored-by: Mihai Criveti <crivetimihai@gmail.com>
vk-playground pushed a commit to vk-playground/mcp-context-forge that referenced this pull request Sep 16, 2025
* Fixed streamable http support for translating stdio servers

Signed-off-by: Keval Mahajan <mahajankeval23@gmail.com>

* minor changes

Signed-off-by: Keval Mahajan <mahajankeval23@gmail.com>

* Fix bandit B112 warning: Use specific exception types

- Replace generic Exception with specific json.JSONDecodeError and ValueError
- Addresses bandit security scan warning about try/except/continue pattern

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* Fix pre-commit hook to exclude test helper files

- Update name-tests-test hook to exclude files in helpers/ directories
- Prevents false positives for helper modules like trace_generator.py
- Keeps the test naming convention check for actual test files

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

---------

Signed-off-by: Keval Mahajan <mahajankeval23@gmail.com>
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Co-authored-by: Mihai Criveti <crivetimihai@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Streamable HTTP Translation Feature: Connects but Fails to List Tools, Resources, or Support Tool Calls

5 participants