mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
fix(mcp): resolve \$ref params in OpenAPI preview endpoint (test/tools/list)
The _preview_openapi_tools function (called by the UI add-server form to show connection status and available tools) had the same bug as _register_openapi_tools: it accessed param["name"] directly without resolving \$ref parameters or merging path-level parameters from the path item. This caused "Failed to load OpenAPI spec: 'name'" for any spec that uses component-level parameter references (e.g. GitHub's official REST API spec). Apply the same fix: resolve \$ref against components/parameters and merge path-level params (with operation-level taking priority) before building schemas.
This commit is contained in:
parent
50b24774b4
commit
af45006111
1 changed files with 20 additions and 1 deletions
|
|
@ -671,16 +671,35 @@ if MCP_AVAILABLE:
|
|||
try:
|
||||
spec = await load_openapi_spec_async(spec_path)
|
||||
paths = spec.get("paths", {})
|
||||
components = spec.get("components", {})
|
||||
tools: List[dict] = []
|
||||
for path, path_item in paths.items():
|
||||
for method in ("get", "post", "put", "patch", "delete"):
|
||||
operation = path_item.get(method)
|
||||
if operation is None:
|
||||
continue
|
||||
|
||||
# Resolve $ref params and merge path-level params (same logic as
|
||||
# _register_openapi_tools) so large specs like GitHub's work correctly.
|
||||
def _resolve_ref(p: dict) -> dict:
|
||||
ref = p.get("$ref", "")
|
||||
if ref.startswith("#/components/parameters/"):
|
||||
param_name = ref.split("/")[-1]
|
||||
return components.get("parameters", {}).get(param_name, p)
|
||||
return p
|
||||
|
||||
path_level = [_resolve_ref(p) for p in path_item.get("parameters", [])]
|
||||
op_level = [_resolve_ref(p) for p in operation.get("parameters", [])]
|
||||
op_keys = {(p.get("name"), p.get("in")) for p in op_level}
|
||||
merged = [p for p in path_level if (p.get("name"), p.get("in")) not in op_keys] + op_level
|
||||
|
||||
resolved_op = dict(operation)
|
||||
resolved_op["parameters"] = merged
|
||||
|
||||
op_id = operation.get("operationId", f"{method}_{path}")
|
||||
summary = operation.get("summary", "")
|
||||
description = operation.get("description", summary)
|
||||
input_schema = build_input_schema(operation)
|
||||
input_schema = build_input_schema(resolved_op)
|
||||
tools.append(
|
||||
{
|
||||
"name": op_id,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue