Skip to content

Commit e156fc2

Browse files
committed
update IT, changelog, cli and env args
1 parent 5b2d814 commit e156fc2

File tree

7 files changed

+101
-37
lines changed

7 files changed

+101
-37
lines changed

servers/mcp-neo4j-data-modeling/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Changed
66

77
### Added
8+
* Add HTTP transport option
89

910
## v0.1.1
1011

servers/mcp-neo4j-data-modeling/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,9 @@ Environment variables for HTTP configuration:
135135

136136
```bash
137137
export MCP_TRANSPORT=http
138-
export MCP_HTTP_HOST=0.0.0.0
139-
export MCP_HTTP_PORT=8080
140-
export MCP_HTTP_PATH=/api/mcp/
138+
export NEO4J_MCP_SERVER_HOST=0.0.0.0
139+
export NEO4J_MCP_SERVER_PORT=8080
140+
export NEO4J_MCP_SERVER_PATH=/api/mcp/
141141
mcp-neo4j-data-modeling
142142
```
143143

servers/mcp-neo4j-data-modeling/src/mcp_neo4j_data_modeling/__init__.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ def main():
1111
parser.add_argument(
1212
"--transport", default="stdio", help="Transport type (stdio, sse, http)"
1313
)
14-
parser.add_argument("--host", default=None, help="HTTP host (default: 127.0.0.1)")
14+
parser.add_argument("--server-host", default=None, help="HTTP host (default: 127.0.0.1)")
1515
parser.add_argument(
16-
"--port", type=int, default=None, help="HTTP port (default: 8000)"
16+
"--server-port", type=int, default=None, help="HTTP port (default: 8000)"
1717
)
18-
parser.add_argument("--path", default=None, help="HTTP path (default: /mcp/)")
18+
parser.add_argument("--server-path", default=None, help="HTTP path (default: /mcp/)")
1919

2020
args = parser.parse_args()
2121
asyncio.run(
2222
server.main(
23-
args.transport or os.getenv("MCP_TRANSPORT", "stdio"),
24-
args.host or os.getenv("MCP_HTTP_HOST", "127.0.0.1"),
25-
args.port or int(os.getenv("MCP_HTTP_PORT", "8000")),
26-
args.path or os.getenv("MCP_HTTP_PATH", "/mcp/"),
23+
args.transport or os.getenv("NEO4J_TRANSPORT", "stdio"),
24+
args.server_host or os.getenv("NEO4J_MCP_SERVER_HOST", "127.0.0.1"),
25+
args.server_port or int(os.getenv("NEO4J_MCP_SERVER_PORT", "8000")),
26+
args.server_path or os.getenv("NEO4J_MCP_SERVER_PATH", "/mcp/"),
2727
)
2828
)
2929

servers/mcp-neo4j-data-modeling/tests/integration/conftest.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
from typing import Any
3-
3+
import asyncio
4+
import subprocess
45
import pytest
56
import pytest_asyncio
67
from neo4j import AsyncGraphDatabase
@@ -68,3 +69,33 @@ def init_data(setup: Neo4jContainer, clear_data: Any):
6869
def clear_data(setup: Neo4jContainer):
6970
with setup.get_driver().session(database="neo4j") as session:
7071
session.run("MATCH (n) DETACH DELETE n")
72+
73+
@pytest_asyncio.fixture
74+
async def sse_server():
75+
"""Start the MCP server in SSE mode."""
76+
77+
78+
process = await asyncio.create_subprocess_exec(
79+
"uv", "run", "mcp-neo4j-data-modeling",
80+
"--transport", "sse",
81+
"--server-host", "127.0.0.1",
82+
"--server-port", "8002",
83+
stdout=subprocess.PIPE,
84+
stderr=subprocess.PIPE,
85+
cwd=os.getcwd()
86+
)
87+
88+
await asyncio.sleep(3)
89+
90+
if process.returncode is not None:
91+
stdout, stderr = await process.communicate()
92+
raise RuntimeError(f"Server failed to start. stdout: {stdout.decode()}, stderr: {stderr.decode()}")
93+
94+
yield process
95+
96+
try:
97+
process.terminate()
98+
await asyncio.wait_for(process.wait(), timeout=5.0)
99+
except asyncio.TimeoutError:
100+
process.kill()
101+
await process.wait()

servers/mcp-neo4j-data-modeling/tests/integration/test_http_transport.py renamed to servers/mcp-neo4j-data-modeling/tests/integration/test_http_transport_IT.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,6 @@ async def parse_sse_response(response: aiohttp.ClientResponse) -> dict:
2323
raise ValueError("No data line found in SSE response")
2424

2525

26-
@pytest.fixture
27-
def mcp_server():
28-
"""Create an MCP server instance for testing."""
29-
return create_mcp_server()
30-
31-
32-
class TestTransportModes:
33-
"""Test all transport modes work correctly."""
34-
35-
@pytest.mark.asyncio
36-
async def test_stdio_transport(self, mcp_server):
37-
"""Test that stdio transport works correctly."""
38-
# Test that the server can be created and tools can be listed
39-
tools = await mcp_server.get_tools()
40-
assert len(tools) > 0
41-
tool_names = list(tools.keys())
42-
assert "validate_node" in tool_names
43-
44-
@pytest.mark.asyncio
45-
async def test_sse_transport(self, mcp_server):
46-
"""Test that SSE transport works correctly."""
47-
# Test that the server can be created and tools can be listed
48-
tools = await mcp_server.get_tools()
49-
assert len(tools) > 0
50-
tool_names = list(tools.keys())
51-
assert "validate_node" in tool_names
5226

5327
@pytest.mark.asyncio
5428
async def test_http_transport_creation(self, mcp_server):
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import aiohttp
2+
import pytest
3+
4+
5+
@pytest.mark.asyncio
6+
async def test_sse_endpoint(sse_server):
7+
"""Test that SSE endpoint is accessible."""
8+
async with aiohttp.ClientSession() as session:
9+
async with session.get("http://127.0.0.1:8002/mcp/") as response:
10+
# SSE endpoint should be accessible
11+
assert response.status in [200, 404] # 404 is okay if no specific endpoint
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import pytest
2+
import asyncio
3+
import subprocess
4+
import os
5+
6+
from testcontainers.neo4j import Neo4jContainer
7+
8+
9+
10+
11+
@pytest.mark.asyncio
12+
async def test_stdio_transport(setup: Neo4jContainer):
13+
"""Test that stdio transport can be started."""
14+
15+
# Test that stdio transport can be started (it should not crash)
16+
process = await asyncio.create_subprocess_exec(
17+
"uv", "run", "mcp-neo4j-cypher",
18+
"--transport", "stdio",
19+
"--db-url", setup.get_connection_url(),
20+
"--username", setup.username,
21+
"--password", setup.password,
22+
stdout=subprocess.PIPE,
23+
stderr=subprocess.PIPE,
24+
cwd=os.getcwd()
25+
)
26+
27+
# Give it a moment to start
28+
await asyncio.sleep(1)
29+
30+
# Check if process is still running before trying to terminate
31+
if process.returncode is None:
32+
# Process is still running, terminate it
33+
try:
34+
process.terminate()
35+
await asyncio.wait_for(process.wait(), timeout=5.0)
36+
except asyncio.TimeoutError:
37+
process.kill()
38+
await process.wait()
39+
else:
40+
# Process has already exited, which is fine for this test
41+
# We just want to verify it didn't crash immediately
42+
pass
43+
44+
# Process should have started successfully (no immediate crash)
45+
# If returncode is None, it means the process was still running when we tried to terminate it
46+
# If returncode is not None, it means the process exited (which is also acceptable for this test)
47+
assert True # If we get here, the process started without immediate crash

0 commit comments

Comments
 (0)