Skip to content

feat(mcp): add HTTP transport support to MCP server with configurable host and port#448

Merged
vitali87 merged 8 commits intovitali87:mainfrom
NoSugarCoffee:feat/mcp
Mar 21, 2026
Merged

feat(mcp): add HTTP transport support to MCP server with configurable host and port#448
vitali87 merged 8 commits intovitali87:mainfrom
NoSugarCoffee:feat/mcp

Conversation

@NoSugarCoffee
Copy link
Contributor

Summary

Type of Change

  • New feature

Related Issues

Test Plan

  • Manual testing (describe below)

Can start up the http server as expected, and list tools

Checklist

  • PR title follows Conventional Commits format
  • All pre-commit checks pass (make pre-commit)
  • No hardcoded strings in non-config/non-constants files
  • No # type: ignore, cast(), Any, or object type hints
  • No new comments or docstrings (code should be self-documenting)

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the MCP (Memgraph Code Processor) server by introducing an HTTP transport layer. This change allows the MCP server to be run as a web service, providing greater flexibility in how it can be deployed and integrated with other systems. Users can now choose between the existing standard I/O transport and the new HTTP transport, with options to configure the host and port for the HTTP server directly from the command line or through environment variables.

Highlights

  • HTTP Transport Support: Added HTTP transport support for the MCP server, allowing it to be exposed via a web interface.
  • Configurable Host and Port: Introduced configurable host and port options for the new HTTP server, enabling flexible deployment via command-line arguments or environment variables.
  • CLI Command Refactoring: Refactored the mcp_server CLI command to support selecting between standard I/O and HTTP transport modes.
Changelog
  • codebase_rag/cli.py
    • Modified the mcp_server command to accept transport, host, and port as typer.Option arguments.
    • Implemented conditional logic to import and run serve_http or serve_stdio based on the transport argument.
    • Resolved host and port using command-line options or default settings.
  • codebase_rag/cli_help.py
    • Added new help strings (HELP_MCP_TRANSPORT, HELP_MCP_HTTP_HOST, HELP_MCP_HTTP_PORT) for the newly introduced CLI options.
  • codebase_rag/config.py
    • Defined default configuration settings for MCP_HTTP_HOST, MCP_HTTP_PORT, and MCP_HTTP_ENDPOINT_PATH.
  • codebase_rag/constants.py
    • Introduced MCPTransport enum with STDIO and HTTP options.
    • Added MCP_HTTP_HOST and MCP_HTTP_PORT to the MCPEnvVar enum for environment variable configuration.
  • codebase_rag/logs.py
    • Added new log messages (MCP_HTTP_SERVER_STARTING, MCP_HTTP_SERVER_READY) to provide feedback on the HTTP server's status.
  • codebase_rag/mcp/init.py
    • Updated the __init__.py to explicitly import and expose serve_http and serve_stdio functions from codebase_rag.mcp.server.
  • codebase_rag/mcp/server.py
    • Renamed the main asynchronous function to serve_stdio to clarify its purpose.
    • Implemented a new serve_http asynchronous function that sets up and runs an HTTP server using Starlette and Uvicorn.
    • Integrated StreamableHTTPSessionManager for handling HTTP requests to the MCP server.
    • Added a lifespan context manager to manage the ingestor and session manager lifecycle, including logging server connection and readiness.
Activity
  • No specific activity (comments, reviews, progress updates) has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds HTTP transport support to the MCP server, making it accessible over the network. The changes include new CLI options to configure the transport, host, and port, with corresponding settings and help text. The core logic is implemented in codebase_rag/mcp/server.py with a new serve_http function that uses uvicorn and starlette. My review includes a couple of suggestions to improve code quality and robustness: one to remove unused imports and another to leverage typer's enum support for better CLI argument validation.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 15, 2026

Greptile Summary

This PR adds HTTP transport support to the MCP server, allowing it to be started with --transport http alongside the existing stdio mode. It introduces a new serve_http function backed by Starlette + uvicorn + StreamableHTTPSessionManager, a MCPTransport StrEnum, configurable host/port/path settings, and updated CLI options.

Key changes:

  • serve_http function in mcp/server.py using Starlette lifespan pattern with StreamableHTTPSessionManager
  • New MCPTransport StrEnum (stdio / http) and CLI options --transport, --host, --port
  • AppConfig extended with MCP_HTTP_HOST, MCP_HTTP_PORT, MCP_HTTP_ENDPOINT_PATH fields

Issues found:

  • MCPEnvVar.MCP_HTTP_HOST and MCPEnvVar.MCP_HTTP_PORT added to constants but never referenced anywhere — dead code since pydantic-settings handles those env vars automatically via AppConfig
  • The inner lifespan function in serve_http is missing a return type annotation (AsyncIterator[None]), violating the project's "type hints everywhere" standard

Confidence Score: 3/5

  • Functional but has outstanding type-safety and dead-code issues that should be resolved before merging
  • The core HTTP transport logic looks correct and manually tested. However, there are two unresolved issues from this review (dead MCPEnvVar entries, missing return type on lifespan) plus two previously flagged issues that remain open (nullable type annotations on CLI params, hardcoded log level string). These collectively pull the score down from an otherwise well-structured feature addition.
  • codebase_rag/constants.py (dead MCPEnvVar entries) and codebase_rag/mcp/server.py (missing lifespan return type, hardcoded log level string)

Important Files Changed

Filename Overview
codebase_rag/mcp/server.py Adds serve_http using Starlette + uvicorn + StreamableHTTPSessionManager; renames main to serve_stdio. Inner lifespan function is missing a return type annotation (AsyncIterator[None]) and the hardcoded "info" log level string in uvicorn.Config should use a constant.
codebase_rag/constants.py Adds MCPTransport StrEnum and extends MCPEnvVar with MCP_HTTP_HOST / MCP_HTTP_PORT. The two new MCPEnvVar entries are never referenced anywhere — they are dead code since pydantic-settings handles those env vars automatically.
codebase_rag/cli.py Updates mcp_server CLI command to accept --transport, --host, and --port options; dispatches to serve_http or serve_stdio accordingly. Type annotations for host and port (nullable options) were previously flagged.
codebase_rag/config.py Adds three new pydantic-settings fields: MCP_HTTP_HOST, MCP_HTTP_PORT, and MCP_HTTP_ENDPOINT_PATH with sensible defaults. No issues found.
codebase_rag/logs.py Adds MCP_HTTP_SERVER_STARTING and MCP_HTTP_SERVER_READY log templates. MCP_HTTP_SERVER_READY hardcodes /mcp instead of referencing settings.MCP_HTTP_ENDPOINT_PATH (previously flagged).
codebase_rag/cli_help.py Adds help text for the new --transport, --host, and --port CLI options. No issues found.
codebase_rag/mcp/init.py Updates exports from main to serve_http and serve_stdio. Clean change.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as cli.py mcp_server()
    participant Server as mcp/server.py
    participant SM as StreamableHTTPSessionManager
    participant Uvicorn
    participant Client as MCP HTTP Client

    User->>CLI: codebase-rag mcp-server --transport http [--host H] [--port P]
    CLI->>CLI: resolve host/port (CLI arg or settings)
    CLI->>Server: asyncio.run(serve_http(host, port))
    Server->>Server: create_server() → (Server, MemgraphIngestor)
    Server->>SM: StreamableHTTPSessionManager(app=server)
    Server->>Uvicorn: uvicorn.Config(Starlette app, host, port)
    Uvicorn->>Server: lifespan startup
    Server->>Server: ingestor.__enter__()
    Server->>SM: session_manager.run().__aenter__()
    SM-->>Server: ready
    Server-->>Uvicorn: yield (server ready)
    Uvicorn-->>User: HTTP server listening on host:port/mcp

    Client->>Uvicorn: POST /mcp (MCP request)
    Uvicorn->>SM: handle_request(scope, receive, send)
    SM->>Server: route to MCP tool handler
    Server-->>SM: tool result
    SM-->>Client: HTTP response
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: codebase_rag/constants.py
Line: 2410-2411

Comment:
**Unused `MCPEnvVar` entries are dead code**

`MCP_HTTP_HOST` and `MCP_HTTP_PORT` are added to `MCPEnvVar` but are never referenced anywhere in the codebase. The existing entries (`TARGET_REPO_PATH`, `CLAUDE_PROJECT_ROOT`, `PWD`) are used in `server.py` via `os.environ.get(cs.MCPEnvVar.XXX)` to read environment variables not managed by pydantic-settings. However, `MCP_HTTP_HOST` and `MCP_HTTP_PORT` are already handled automatically by pydantic-settings as `AppConfig.MCP_HTTP_HOST` / `AppConfig.MCP_HTTP_PORT`, and `serve_http` only accesses them via `settings.MCP_HTTP_HOST` / `settings.MCP_HTTP_PORT` — never through `os.environ.get`. These two entries serve no purpose and are misleading.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: codebase_rag/mcp/server.py
Line: 185-186

Comment:
**Missing return type annotation on `lifespan`**

The inner `lifespan` function has no return type annotation. Per the project's strict typing standards ("use type hints everywhere"), the decorated generator function should declare `AsyncIterator[None]` as its return type. Without it, `uv run ty check` will flag this, and the Starlette `Lifespan` type contract is not verified statically.

```suggestion
    async def lifespan(app: Starlette) -> AsyncIterator[None]:
```

You will also need to add the import — either `from collections.abc import AsyncIterator` or `from typing import AsyncIterator`.

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 602ecac

NoSugarCoffee and others added 2 commits March 15, 2026 18:39
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@codecov-commenter
Copy link

codecov-commenter commented Mar 15, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 37.20930% with 27 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
codebase_rag/mcp/server.py 9.09% 20 Missing ⚠️
codebase_rag/cli.py 12.50% 7 Missing ⚠️

📢 Thoughts on this report? Let us know!

@NoSugarCoffee NoSugarCoffee marked this pull request as draft March 15, 2026 10:51
@NoSugarCoffee NoSugarCoffee marked this pull request as ready for review March 15, 2026 11:21
@NoSugarCoffee
Copy link
Contributor Author

@vitali87, could you please review the code and let me know how we can fix the SonarCloud issues?

NoSugarCoffee and others added 3 commits March 15, 2026 20:20
@vitali87
Copy link
Owner

Thanks @NoSugarCoffee — this is a clean implementation and I'd like to get it merged.

A few things to address before merging:

  1. Rebase on latest main — main has moved significantly since this was opened (new providers, stats command, etc.)
  2. Type annotationshost and port CLI params default to None but are typed str/int. Use str | None and int | None respectively
  3. Hardcoded /mcp in log message — use settings.MCP_HTTP_ENDPOINT_PATH instead for consistency
  4. Hardcoded "info" log level — consider using a constant or making it configurable
  5. SonarCloud coverage — may need a test or two for the new serve_http path (even a basic smoke test with mocked server)

Once these are addressed, I'm happy to merge. Let me know if you need any help!

@vitali87 vitali87 merged commit 7202897 into vitali87:main Mar 21, 2026
11 of 12 checks passed
@NoSugarCoffee
Copy link
Contributor Author

@vitali87 There's a time difference, so I don't respond that quickly.Your opinion is very valuable. Thanks for the merge, even though there were some flaws.Regarding SonarCloud, it says there’s no token — it’s not a coverage issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

feat(mcp): add Streamable HTTP transport

3 participants