Add SSE transport support to code-memory MCP server#5
Add SSE transport support to code-memory MCP server#5SlackJaw74 wants to merge 0 commit intokapillamba4:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a CLI-selectable transport to the code-memory MCP server so it can run either via the default stdio transport or as a shared SSE server (to avoid per-project process/model duplication).
Changes:
- Add
--transport {stdio,sse}plus--host/--portCLI arguments and pass transport through tomcp.run(...). - Add unit tests covering CLI defaults/flags and that
main()wires transport/host/port intomcp. - Document how to run a shared SSE server and configure MCP hosts to connect to it.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
server.py |
Adds argparse-based CLI options and runs FastMCP with the selected transport (and sets host/port for SSE). |
tests/test_main.py |
Introduces tests for CLI parsing and verifies main() calls mcp.run() correctly for stdio vs SSE. |
README.md |
Documents shared SSE usage, configuration examples, and lists CLI options. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
tests/test_main.py
Outdated
| class TestMainArgParsing: | ||
| """Tests for CLI argument parsing in main().""" | ||
|
|
||
| def _parse_args(self, argv: list[str]) -> argparse.Namespace: | ||
| """Helper to call main()'s argument parser directly.""" | ||
| parser = argparse.ArgumentParser(prog="code-memory") | ||
| parser.add_argument( | ||
| "--transport", | ||
| choices=["stdio", "sse"], | ||
| default="stdio", | ||
| ) | ||
| parser.add_argument("--port", type=int, default=8765) | ||
| parser.add_argument("--host", default="127.0.0.1") | ||
| return parser.parse_args(argv) | ||
|
|
||
| def test_default_transport_is_stdio(self): | ||
| """Default transport should be stdio.""" | ||
| args = self._parse_args([]) | ||
| assert args.transport == "stdio" | ||
|
|
||
| def test_default_port_is_8765(self): | ||
| """Default SSE port should be 8765.""" | ||
| args = self._parse_args([]) | ||
| assert args.port == 8765 | ||
|
|
||
| def test_default_host_is_localhost(self): | ||
| """Default SSE host should be 127.0.0.1.""" | ||
| args = self._parse_args([]) | ||
| assert args.host == "127.0.0.1" | ||
|
|
||
| def test_sse_transport_flag(self): | ||
| """--transport sse should set transport to sse.""" | ||
| args = self._parse_args(["--transport", "sse"]) | ||
| assert args.transport == "sse" | ||
|
|
||
| def test_custom_port(self): | ||
| """--port should accept a custom port number.""" | ||
| args = self._parse_args(["--transport", "sse", "--port", "9000"]) | ||
| assert args.port == 9000 | ||
|
|
||
| def test_custom_host(self): | ||
| """--host should accept a custom host.""" | ||
| args = self._parse_args(["--transport", "sse", "--host", "0.0.0.0"]) | ||
| assert args.host == "0.0.0.0" | ||
|
|
||
| def test_invalid_transport_raises_error(self): | ||
| """Invalid transport should raise SystemExit.""" | ||
| with pytest.raises(SystemExit): | ||
| self._parse_args(["--transport", "invalid"]) | ||
|
|
||
|
|
There was a problem hiding this comment.
The arg-parsing tests build a standalone ArgumentParser instead of exercising the actual parser used by server.main(). This can easily drift (tests still pass while the CLI behavior changes). Consider refactoring server.py to expose a shared parser builder (e.g., build_arg_parser()) and have the tests call that, so the tests validate the real CLI contract.
| class TestMainArgParsing: | |
| """Tests for CLI argument parsing in main().""" | |
| def _parse_args(self, argv: list[str]) -> argparse.Namespace: | |
| """Helper to call main()'s argument parser directly.""" | |
| parser = argparse.ArgumentParser(prog="code-memory") | |
| parser.add_argument( | |
| "--transport", | |
| choices=["stdio", "sse"], | |
| default="stdio", | |
| ) | |
| parser.add_argument("--port", type=int, default=8765) | |
| parser.add_argument("--host", default="127.0.0.1") | |
| return parser.parse_args(argv) | |
| def test_default_transport_is_stdio(self): | |
| """Default transport should be stdio.""" | |
| args = self._parse_args([]) | |
| assert args.transport == "stdio" | |
| def test_default_port_is_8765(self): | |
| """Default SSE port should be 8765.""" | |
| args = self._parse_args([]) | |
| assert args.port == 8765 | |
| def test_default_host_is_localhost(self): | |
| """Default SSE host should be 127.0.0.1.""" | |
| args = self._parse_args([]) | |
| assert args.host == "127.0.0.1" | |
| def test_sse_transport_flag(self): | |
| """--transport sse should set transport to sse.""" | |
| args = self._parse_args(["--transport", "sse"]) | |
| assert args.transport == "sse" | |
| def test_custom_port(self): | |
| """--port should accept a custom port number.""" | |
| args = self._parse_args(["--transport", "sse", "--port", "9000"]) | |
| assert args.port == 9000 | |
| def test_custom_host(self): | |
| """--host should accept a custom host.""" | |
| args = self._parse_args(["--transport", "sse", "--host", "0.0.0.0"]) | |
| assert args.host == "0.0.0.0" | |
| def test_invalid_transport_raises_error(self): | |
| """Invalid transport should raise SystemExit.""" | |
| with pytest.raises(SystemExit): | |
| self._parse_args(["--transport", "invalid"]) |
README.md
Outdated
| # Custom port and host | ||
| uvx code-memory --transport sse --port 8765 --host 127.0.0.1 | ||
|
|
There was a problem hiding this comment.
Since --host 0.0.0.0 (or any non-loopback bind) will expose the MCP server to the local network, the README should include an explicit security warning (firewalling / running on trusted networks only, no auth by default) near the host/port examples so users don’t accidentally expose it.
|
@copilot open a new pull request to apply changes based on the comments in this thread |
Running mcp server using stdio creates an instance per coding agent. This can cause memory issues if multiple coding agents are working in parallel as each one must load the embedding model into memory. By allowing just one instance using SSE that problem is eliminated.
Agent-Logs-Url: https://github.com/SlackJaw74/code-memory/sessions/07e707bc-dfd0-4547-91d4-9ac71c39b4c1