Skip to content

Commit 3d36432

Browse files
committed
code cleanups
1 parent 291f06d commit 3d36432

File tree

2 files changed

+30
-27
lines changed

2 files changed

+30
-27
lines changed

fastapi_mcp/http_tools.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ def create_mcp_tools_from_openapi(
5353
routes=app.routes,
5454
)
5555

56+
# Resolve all references in the schema at once
57+
openapi_schema = resolve_schema_references(openapi_schema, openapi_schema)
58+
5659
if not base_url:
5760
# Try to determine the base URL from FastAPI config
5861
if hasattr(app, "root_path") and app.root_path:
@@ -197,17 +200,14 @@ def create_http_tool(
197200
schema = content_data["schema"]
198201
response_info += f"\nContent-Type: {content_type}"
199202

200-
# Resolve any schema references
201-
resolved_schema = resolve_schema_references(schema, openapi_schema)
202-
203203
# Clean the schema for display
204-
display_schema = clean_schema_for_display(resolved_schema)
204+
display_schema = clean_schema_for_display(schema)
205205

206206
# Get model name if it's a referenced model
207207
model_name = None
208208
model_examples = None
209209
items_model_name = None
210-
if "$ref" in schema:
210+
if "$ref" in schema: # This check is now just for information
211211
ref_path = schema["$ref"]
212212
if ref_path.startswith("#/components/schemas/"):
213213
model_name = ref_path.split("/")[-1]

fastapi_mcp/openapi_utils.py

+25-22
Original file line numberDiff line numberDiff line change
@@ -147,44 +147,47 @@ def parse_parameters_for_args_schema(parameters: List[Dict[str, Any]]) -> Dict[s
147147

148148
return args_schema
149149

150-
def resolve_schema_references(schema: Dict[str, Any], openapi_schema: Dict[str, Any]) -> Dict[str, Any]:
150+
def resolve_schema_references(schema_part: Dict[str, Any], reference_schema: Dict[str, Any]) -> Dict[str, Any]:
151151
"""
152152
Resolve schema references in OpenAPI schemas.
153153
154154
Args:
155-
schema: The schema that may contain references
156-
openapi_schema: The full OpenAPI schema to resolve references from
155+
schema_part: The part of the schema being processed that may contain references
156+
reference_schema: The complete schema used to resolve references from
157157
158158
Returns:
159159
The schema with references resolved
160160
"""
161161
# Make a copy to avoid modifying the input schema
162-
schema = schema.copy()
162+
schema_part = schema_part.copy()
163163

164164
# Handle $ref directly in the schema
165-
if "$ref" in schema:
166-
ref_path = schema["$ref"]
165+
if "$ref" in schema_part:
166+
ref_path = schema_part["$ref"]
167167
# Standard OpenAPI references are in the format "#/components/schemas/ModelName"
168168
if ref_path.startswith("#/components/schemas/"):
169169
model_name = ref_path.split("/")[-1]
170-
if "components" in openapi_schema and "schemas" in openapi_schema["components"]:
171-
if model_name in openapi_schema["components"]["schemas"]:
170+
if "components" in reference_schema and "schemas" in reference_schema["components"]:
171+
if model_name in reference_schema["components"]["schemas"]:
172172
# Replace with the resolved schema
173-
ref_schema = openapi_schema["components"]["schemas"][model_name].copy()
173+
ref_schema = reference_schema["components"]["schemas"][model_name].copy()
174174
# Remove the $ref key and merge with the original schema
175-
schema.pop("$ref")
176-
schema.update(ref_schema)
177-
178-
# Handle array items
179-
if "type" in schema and schema["type"] == "array" and "items" in schema:
180-
schema["items"] = resolve_schema_references(schema["items"], openapi_schema)
181-
182-
# Handle object properties
183-
if "properties" in schema:
184-
for prop_name, prop_schema in schema["properties"].items():
185-
schema["properties"][prop_name] = resolve_schema_references(prop_schema, openapi_schema)
186-
187-
return schema
175+
schema_part.pop("$ref")
176+
schema_part.update(ref_schema)
177+
178+
# Recursively resolve references in all dictionary values
179+
for key, value in schema_part.items():
180+
if isinstance(value, dict):
181+
schema_part[key] = resolve_schema_references(value, reference_schema)
182+
elif isinstance(value, list):
183+
# Only process list items that are dictionaries since only they can contain refs
184+
schema_part[key] = [
185+
resolve_schema_references(item, reference_schema) if isinstance(item, dict)
186+
else item
187+
for item in value
188+
]
189+
190+
return schema_part
188191

189192
def clean_schema_for_display(schema: Dict[str, Any]) -> Dict[str, Any]:
190193
"""

0 commit comments

Comments
 (0)