|
|
"""Functions which rely on gradio components io and change the interface""" |
|
|
|
|
|
import json |
|
|
|
|
|
from jsonschema import validate, ValidationError |
|
|
|
|
|
|
|
|
def validate_mcp_file(mcp_file_content: str, token: str) -> str: |
|
|
"""Validates the user uploaded MCP file |
|
|
|
|
|
The JSON file should follow this structure (we only allow SSE type for the demo, |
|
|
but if you run locally you can add stdio to your json file): |
|
|
|
|
|
```json |
|
|
{ |
|
|
"mcpServers": { |
|
|
"app-name-1": { |
|
|
"type": "sse", |
|
|
"url": "https://api.example.com/mcp", |
|
|
"headers": { |
|
|
"Authorization": "Bearer your-token-here" |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
``` |
|
|
""" |
|
|
|
|
|
mcp_schema = { |
|
|
"$schema": "https://json-schema.org/draft/2020-12/json-schema-core.html", |
|
|
"type": "object", |
|
|
"properties": { |
|
|
"mcpServers": { |
|
|
"type": "object", |
|
|
"patternProperties": { |
|
|
"^[\w-]+$": { |
|
|
"type": "object", |
|
|
"properties": { |
|
|
"type": {"type": "string", "enum": ["sse"]}, |
|
|
"url": {"type": "string", "format": "uri"}, |
|
|
"headers": { |
|
|
"type": "object", |
|
|
"patternProperties": {"^[\w-]+$": {"type": "string"}}, |
|
|
"additionalProperties": False, |
|
|
}, |
|
|
}, |
|
|
"required": ["type", "url"], |
|
|
"additionalProperties": False, |
|
|
} |
|
|
}, |
|
|
"additionalProperties": False, |
|
|
"minProperties": 1, |
|
|
} |
|
|
}, |
|
|
"required": ["mcpServers"], |
|
|
"additionalProperties": False, |
|
|
} |
|
|
|
|
|
try: |
|
|
mcp_data = json.loads(mcp_file_content) |
|
|
validate(instance=mcp_data, schema=mcp_schema) |
|
|
|
|
|
for server in mcp_data.get("mcpServers", {}).values(): |
|
|
try: |
|
|
if "HF_TOKEN" in server["headers"]["Authorization"]: |
|
|
server["headers"]["Authorization"] = server["headers"][ |
|
|
"Authorization" |
|
|
].replace("HF_TOKEN", token or "") |
|
|
except KeyError: |
|
|
continue |
|
|
|
|
|
return mcp_data |
|
|
|
|
|
except json.JSONDecodeError as e: |
|
|
raise ValueError(f"Invalid JSON format: {str(e)}") |
|
|
except ValidationError as e: |
|
|
|
|
|
error_path = " -> ".join(str(p) for p in e.path) if e.path else "root" |
|
|
raise ValueError(f"Invalid MCP file structure at {error_path}: {e.message}") |
|
|
except Exception as e: |
|
|
raise ValueError(f"Error validating MCP file: {str(e)}") |
|
|
|