Skip to content

Commit 394c860

Browse files
committed
style: apply ruff formatting to entire codebase
- Format all Python files with ruff format - Fix import sorting and organization - Ensure consistent code style across 32 files - All tests passing (129 passed, 2 skipped)
1 parent dee0720 commit 394c860

32 files changed

+1617
-1271
lines changed

src/mcpcat/__init__.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
)
2222

2323

24-
def track(server: Any, project_id: str | None = None, options: MCPCatOptions | None = None) -> Any:
24+
def track(
25+
server: Any, project_id: str | None = None, options: MCPCatOptions | None = None
26+
) -> Any:
2527
"""
2628
Initialize MCPCat tracking with optional telemetry export.
2729
@@ -88,29 +90,39 @@ def track(server: Any, project_id: str | None = None, options: MCPCatOptions | N
8890
# Initialize the dynamic tracking system by setting the flag
8991
if not data.tracker_initialized:
9092
data.tracker_initialized = True
91-
write_to_log(f"Dynamic tracking initialized for server {id(lowlevel_server)}")
93+
write_to_log(
94+
f"Dynamic tracking initialized for server {id(lowlevel_server)}"
95+
)
9296

9397
# Apply appropriate tracking method based on server type
9498
if is_fastmcp:
9599
# For FastMCP servers, use monkey-patching for tool tracking
96100
apply_monkey_patches(server, data)
97101
# Only apply minimal overrides for non-tool events (like initialize, list_tools display)
98-
from mcpcat.modules.overrides.mcp_server import override_lowlevel_mcp_server_minimal
102+
from mcpcat.modules.overrides.mcp_server import (
103+
override_lowlevel_mcp_server_minimal,
104+
)
105+
99106
override_lowlevel_mcp_server_minimal(lowlevel_server, data)
100107
else:
101108
# For low-level servers, use the traditional overrides (no monkey patching needed)
102109
override_lowlevel_mcp_server(lowlevel_server, data)
103110

104111
if project_id:
105-
write_to_log(f"MCPCat initialized with dynamic tracking for session {session_id} on project {project_id}")
112+
write_to_log(
113+
f"MCPCat initialized with dynamic tracking for session {session_id} on project {project_id}"
114+
)
106115
else:
107-
write_to_log(f"MCPCat initialized in telemetry-only mode for session {session_id}")
116+
write_to_log(
117+
f"MCPCat initialized in telemetry-only mode for session {session_id}"
118+
)
108119

109120
except Exception as e:
110121
write_to_log(f"Error initializing MCPCat: {e}")
111122

112123
return server
113124

125+
114126
__all__ = [
115127
# Main API
116128
"track",

src/mcpcat/modules/compatibility.py

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,50 +24,54 @@ def is_fastmcp_server(server: Any) -> bool:
2424
# A FastMCP server should have both _mcp_server and _tool_manager
2525
return hasattr(server, "_mcp_server") and hasattr(server, "_tool_manager")
2626

27+
2728
def has_required_fastmcp_attributes(server: Any) -> bool:
2829
"""Check if a FastMCP server has all required attributes for monkey patching.
29-
30+
3031
This validates that the server has all the attributes that monkey_patch.py expects.
3132
"""
3233
# Check for _tool_manager and its required methods
3334
if not hasattr(server, "_tool_manager"):
3435
return False
35-
36+
3637
tool_manager = server._tool_manager
3738
required_tool_manager_methods = ["add_tool", "call_tool", "list_tools"]
3839
for method in required_tool_manager_methods:
39-
if not hasattr(tool_manager, method) or not callable(getattr(tool_manager, method)):
40+
if not hasattr(tool_manager, method) or not callable(
41+
getattr(tool_manager, method)
42+
):
4043
return False
41-
44+
4245
# Check for _tools dict on tool_manager (used for tracking existing tools)
4346
if not hasattr(tool_manager, "_tools") or not isinstance(tool_manager._tools, dict):
4447
return False
45-
48+
4649
# Check for add_tool method on the server itself (used for adding get_more_tools)
4750
if not hasattr(server, "add_tool") or not callable(server.add_tool):
4851
return False
49-
52+
5053
# Check for _mcp_server (used for event tracking and session management)
5154
if not hasattr(server, "_mcp_server"):
5255
return False
53-
56+
5457
return True
5558

59+
5660
def has_neccessary_attributes(server: Any) -> bool:
5761
"""Check if the server has necessary attributes for compatibility."""
5862
required_methods = ["list_tools", "call_tool"]
59-
63+
6064
# Check for core methods that both FastMCP and Server implementations have
6165
for method in required_methods:
6266
if not hasattr(server, method):
6367
return False
64-
68+
6569
# For FastMCP servers, verify all required attributes for monkey patching
6670
if is_fastmcp_server(server):
6771
# Use the comprehensive FastMCP validation
6872
if not has_required_fastmcp_attributes(server):
6973
return False
70-
74+
7175
# Additional checks for request handling
7276
# Use dir() to avoid triggering property getters that might raise exceptions
7377
if "request_context" not in dir(server._mcp_server):
@@ -90,7 +94,7 @@ def has_neccessary_attributes(server: Any) -> bool:
9094
return False
9195
if not isinstance(server.request_handlers, dict):
9296
return False
93-
97+
9498
return True
9599

96100

@@ -105,26 +109,29 @@ def get_mcp_compatible_error_message(error: Any) -> str:
105109
return str(error)
106110
return str(error)
107111

112+
108113
def is_mcp_error_response(response: ServerResult) -> tuple[bool, str]:
109114
"""Check if the response is an MCP error."""
110115
try:
111116
# ServerResult is a RootModel, so we need to access its root attribute
112-
if hasattr(response, 'root'):
117+
if hasattr(response, "root"):
113118
result = response.root
114119
# Check if it's a CallToolResult with an error
115-
if hasattr(result, 'isError') and result.isError:
120+
if hasattr(result, "isError") and result.isError:
116121
# Extract error message from content
117-
if hasattr(result, 'content') and result.content:
122+
if hasattr(result, "content") and result.content:
118123
# content is a list of TextContent/ImageContent/EmbeddedResource
119124
for content_item in result.content:
120125
# Check if it has a text attribute (TextContent)
121-
if hasattr(content_item, 'text'):
126+
if hasattr(content_item, "text"):
122127
return True, str(content_item.text)
123128
# Check if it has type and content attributes
124-
elif hasattr(content_item, 'type') and hasattr(content_item, 'content'):
125-
if content_item.type == 'text':
129+
elif hasattr(content_item, "type") and hasattr(
130+
content_item, "content"
131+
):
132+
if content_item.type == "text":
126133
return True, str(content_item.content)
127-
134+
128135
# If no text content found, stringify the first item
129136
if result.content and len(result.content) > 0:
130137
return True, str(result.content[0])
@@ -136,4 +143,4 @@ def is_mcp_error_response(response: ServerResult) -> tuple[bool, str]:
136143
return False, ""
137144
except Exception as e:
138145
# Log unexpected errors but still return a valid response
139-
return False, f"Error checking response: {str(e)}"
146+
return False, f"Error checking response: {str(e)}"

src/mcpcat/modules/context_parameters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def add_context_parameter_to_schema(schema: dict[str, Any]) -> dict[str, Any]:
3636
# Add context parameter
3737
modified_schema["properties"]["context"] = {
3838
"type": "string",
39-
"description": "Describe why you are calling this tool and how it fits into your overall task"
39+
"description": "Describe why you are calling this tool and how it fits into your overall task",
4040
}
4141

4242
# Add to required fields

src/mcpcat/modules/exporters/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ def export(self, event: Event) -> None:
1919
This method should handle all errors internally and never
2020
raise exceptions that could affect the main MCP server.
2121
"""
22-
pass
22+
pass

src/mcpcat/modules/exporters/otlp.py

Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,17 @@ def export(self, event: Event) -> None:
6767
{
6868
"scope": {
6969
"name": "mcpcat",
70-
"version": event.mcpcat_version or "0.1.0"
70+
"version": event.mcpcat_version or "0.1.0",
7171
},
72-
"spans": [span]
72+
"spans": [span],
7373
}
74-
]
74+
],
7575
}
7676
]
7777
}
7878

7979
# Send to OTLP collector
80-
response = self.session.post(
81-
self.endpoint,
82-
json=otlp_request,
83-
timeout=5
84-
)
80+
response = self.session.post(self.endpoint, json=otlp_request, timeout=5)
8581
response.raise_for_status()
8682

8783
write_to_log(f"Successfully exported event to OTLP: {event.id}")
@@ -121,8 +117,8 @@ def _convert_to_otlp_span(self, event: Event) -> Dict[str, Any]:
121117
"endTimeUnixNano": str(end_time_nanos),
122118
"attributes": self._get_span_attributes(event),
123119
"status": {
124-
"code": 2 if getattr(event, 'is_error', False) else 1 # ERROR : OK
125-
}
120+
"code": 2 if getattr(event, "is_error", False) else 1 # ERROR : OK
121+
},
126122
}
127123

128124
def _get_resource_attributes(self, event: Event) -> List[Dict[str, Any]]:
@@ -138,28 +134,30 @@ def _get_resource_attributes(self, event: Event) -> List[Dict[str, Any]]:
138134
attributes = []
139135

140136
if event.server_name:
141-
attributes.append({
142-
"key": "service.name",
143-
"value": {"stringValue": event.server_name}
144-
})
137+
attributes.append(
138+
{"key": "service.name", "value": {"stringValue": event.server_name}}
139+
)
145140

146141
if event.server_version:
147-
attributes.append({
148-
"key": "service.version",
149-
"value": {"stringValue": event.server_version}
150-
})
142+
attributes.append(
143+
{
144+
"key": "service.version",
145+
"value": {"stringValue": event.server_version},
146+
}
147+
)
151148

152149
# Add SDK information
153-
attributes.append({
154-
"key": "telemetry.sdk.name",
155-
"value": {"stringValue": "mcpcat-python"}
156-
})
150+
attributes.append(
151+
{"key": "telemetry.sdk.name", "value": {"stringValue": "mcpcat-python"}}
152+
)
157153

158154
if event.mcpcat_version:
159-
attributes.append({
160-
"key": "telemetry.sdk.version",
161-
"value": {"stringValue": event.mcpcat_version}
162-
})
155+
attributes.append(
156+
{
157+
"key": "telemetry.sdk.version",
158+
"value": {"stringValue": event.mcpcat_version},
159+
}
160+
)
163161

164162
return attributes
165163

@@ -177,63 +175,65 @@ def _get_span_attributes(self, event: Event) -> List[Dict[str, Any]]:
177175

178176
# Add MCP-specific attributes
179177
if event.event_type:
180-
attributes.append({
181-
"key": "mcp.event_type",
182-
"value": {"stringValue": event.event_type}
183-
})
178+
attributes.append(
179+
{"key": "mcp.event_type", "value": {"stringValue": event.event_type}}
180+
)
184181

185182
if event.session_id:
186-
attributes.append({
187-
"key": "mcp.session_id",
188-
"value": {"stringValue": event.session_id}
189-
})
183+
attributes.append(
184+
{"key": "mcp.session_id", "value": {"stringValue": event.session_id}}
185+
)
190186

191187
if event.project_id:
192-
attributes.append({
193-
"key": "mcp.project_id",
194-
"value": {"stringValue": event.project_id}
195-
})
188+
attributes.append(
189+
{"key": "mcp.project_id", "value": {"stringValue": event.project_id}}
190+
)
196191

197192
# Add resource name (for tools, prompts, resources)
198193
if event.resource_name:
199-
attributes.append({
200-
"key": "mcp.resource_name",
201-
"value": {"stringValue": event.resource_name}
202-
})
194+
attributes.append(
195+
{
196+
"key": "mcp.resource_name",
197+
"value": {"stringValue": event.resource_name},
198+
}
199+
)
203200

204201
# Add user intent if available
205202
if event.user_intent:
206-
attributes.append({
207-
"key": "mcp.user_intent",
208-
"value": {"stringValue": event.user_intent}
209-
})
203+
attributes.append(
204+
{"key": "mcp.user_intent", "value": {"stringValue": event.user_intent}}
205+
)
210206

211207
# Add actor information
212208
if event.identify_actor_given_id:
213-
attributes.append({
214-
"key": "mcp.actor_id",
215-
"value": {"stringValue": event.identify_actor_given_id}
216-
})
209+
attributes.append(
210+
{
211+
"key": "mcp.actor_id",
212+
"value": {"stringValue": event.identify_actor_given_id},
213+
}
214+
)
217215

218216
if event.identify_actor_name:
219-
attributes.append({
220-
"key": "mcp.actor_name",
221-
"value": {"stringValue": event.identify_actor_name}
222-
})
217+
attributes.append(
218+
{
219+
"key": "mcp.actor_name",
220+
"value": {"stringValue": event.identify_actor_name},
221+
}
222+
)
223223

224224
# Add client information
225225
if event.client_name:
226-
attributes.append({
227-
"key": "mcp.client_name",
228-
"value": {"stringValue": event.client_name}
229-
})
226+
attributes.append(
227+
{"key": "mcp.client_name", "value": {"stringValue": event.client_name}}
228+
)
230229

231230
if event.client_version:
232-
attributes.append({
233-
"key": "mcp.client_version",
234-
"value": {"stringValue": event.client_version}
235-
})
231+
attributes.append(
232+
{
233+
"key": "mcp.client_version",
234+
"value": {"stringValue": event.client_version},
235+
}
236+
)
236237

237238
# Filter out empty attributes
238239
return [attr for attr in attributes if attr["value"].get("stringValue")]
239-

0 commit comments

Comments
 (0)