5
5
6
6
import anyio
7
7
import httpx
8
+ from mcp .server import FastMCP
8
9
from mcp .types import (
9
10
LATEST_PROTOCOL_VERSION ,
10
11
CallToolResult ,
20
21
)
21
22
import pytest
22
23
from httpx_sse import aconnect_sse
24
+ from starlette .exceptions import HTTPException
23
25
24
- from mcp_grafana import mcp
26
+ from mcp_grafana . tools import add_tools
25
27
from mcp_grafana .middleware import run_sse_async_with_middleware
26
28
27
29
from pytest_httpserver import HTTPServer
28
30
29
31
32
+ @pytest .fixture
33
+ def mcp ():
34
+ mcp = FastMCP ("grafana" )
35
+ add_tools (mcp )
36
+ return mcp
37
+
38
+
30
39
class TestMiddleware :
31
40
"""
32
41
Test that our injected starlette middleware extracts headers and
@@ -36,7 +45,28 @@ class TestMiddleware:
36
45
"""
37
46
38
47
@pytest .mark .asyncio
39
- async def test_multiple_requests (self ):
48
+ async def test_no_headers_provided (self , mcp : FastMCP ):
49
+ """
50
+ Ensure that the middleware fails if no headers are provided.
51
+ """
52
+
53
+ # Monkeypatch the MCP server to use our middleware.
54
+ mcp .run_sse_async = MethodType (run_sse_async_with_middleware , mcp )
55
+ mcp .settings .host = "127.0.0.1"
56
+ mcp .settings .port = 9500
57
+ async with anyio .create_task_group () as tg :
58
+ tg .start_soon (mcp .run_sse_async , name = "mcp" )
59
+ # Wait for the server to start.
60
+ await asyncio .sleep (0.1 )
61
+ client = httpx .AsyncClient (
62
+ base_url = f"http://{ mcp .settings .host } :{ mcp .settings .port } "
63
+ )
64
+ resp = await client .get ("/sse" )
65
+ assert resp .status_code == httpx .codes .FORBIDDEN
66
+ tg .cancel_scope .cancel ()
67
+
68
+ @pytest .mark .asyncio
69
+ async def test_multiple_requests (self , mcp : FastMCP ):
40
70
"""
41
71
Ensure that the contextvars do not leak across requests.
42
72
0 commit comments