MCPcopy Create free account
hub / github.com/Flagsmith/flagsmith / PrometheusMiddleware

Class PrometheusMiddleware

mcp/src/flagsmith_mcp/metrics.py:31–89  ·  view source on GitHub ↗

Record Prometheus metrics for MCP tool calls.

Source from the content-addressed store, hash-verified

29
30
31class PrometheusMiddleware(Middleware):
32 """Record Prometheus metrics for MCP tool calls."""
33
34 async def on_call_tool(
35 self,
36 context: MiddlewareContext[mt.CallToolRequestParams],
37 call_next: CallNext[mt.CallToolRequestParams, ToolResult],
38 ) -> ToolResult:
39 tool = context.message.name
40 start = time.perf_counter()
41 try:
42 result = await call_next(context)
43 except Exception:
44 flagsmith_mcp_tool_call_duration_seconds.labels(
45 tool=tool, status="error"
46 ).observe(time.perf_counter() - start)
47 raise
48 flagsmith_mcp_tool_call_duration_seconds.labels(
49 tool=tool, status="success"
50 ).observe(time.perf_counter() - start)
51 # Text blocks already hold the serialised payload; structuredContent
52 # costs one compact dump, matching its wire encoding.
53 unstructured_bytes = sum(
54 len(block.text.encode())
55 for block in result.content
56 if isinstance(block, mt.TextContent)
57 )
58 structured_bytes = (
59 len(pydantic_core.to_json(result.structured_content, fallback=str))
60 if result.structured_content is not None
61 else 0
62 )
63 for content, size in (
64 ("unstructured", unstructured_bytes),
65 ("structured", structured_bytes),
66 ):
67 flagsmith_mcp_tool_result_bytes.labels(
68 tool=tool,
69 content=content,
70 ).observe(size)
71 return result
72
73 async def on_list_tools(
74 self,
75 context: MiddlewareContext[mt.ListToolsRequest],
76 call_next: CallNext[mt.ListToolsRequest, Sequence[Tool]],
77 ) -> Sequence[Tool]:
78 tools = await call_next(context)
79 flagsmith_mcp_tool_catalogue_bytes.set(
80 len(
81 pydantic_core.to_json(
82 [
83 tool.to_mcp_tool().model_dump(exclude_none=True, by_alias=True)
84 for tool in tools
85 ]
86 )
87 )
88 )

Callers 1

create_serverFunction · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…