Merge branch 'dev' into feat/add-prefix-from-discussion-25

This commit is contained in:
Your Full Name 2025-04-04 20:05:18 +02:00
commit 20d2e91bf9

View File

@ -1,18 +1,16 @@
from fastapi import FastAPI, Body, Depends
from fastapi.middleware.cors import CORSMiddleware
from starlette.routing import Mount
from pydantic import create_model
from contextlib import AsyncExitStack, asynccontextmanager
from mcp import ClientSession, StdioServerParameters, types
from mcp.client.stdio import stdio_client
from typing import Dict, Any, Optional
import uvicorn
import json
import os
from contextlib import AsyncExitStack, asynccontextmanager
from typing import Dict, Any, Optional
import uvicorn
from fastapi import FastAPI, Body, Depends
from fastapi.middleware.cors import CORSMiddleware
from mcp import ClientSession, StdioServerParameters, types
from mcp.client.stdio import stdio_client
from mcpo.utils.auth import get_verify_api_key
from pydantic import create_model
from starlette.routing import Mount
def get_python_type(param_type: str):
@ -42,9 +40,7 @@ async def create_dynamic_endpoints(app: FastAPI, api_dependency=None):
server_info = getattr(result, "serverInfo", None)
if server_info:
app.title = server_info.name or app.title
app.description = (
f"{server_info.name} MCP Server" if server_info.name else app.description
)
app.description = app.description
app.version = server_info.version or app.version
tools_result = await session.list_tools()
@ -58,7 +54,8 @@ async def create_dynamic_endpoints(app: FastAPI, api_dependency=None):
# Build Pydantic model
model_fields = {}
required_fields = schema.get("required", [])
for param_name, param_schema in schema["properties"].items():
properties = schema.get("properties", {})
for param_name, param_schema in properties.items():
param_type = param_schema.get("type", "string")
param_desc = param_schema.get("description", "")
python_type = get_python_type(param_type)
@ -139,13 +136,12 @@ async def lifespan(app: FastAPI):
async def run(
host: str = "127.0.0.1",
port: int = 8000,
api_key: Optional[str] = "",
cors_allow_origins=["*"],
**kwargs,
host: str = "127.0.0.1",
port: int = 8000,
api_key: Optional[str] = "",
cors_allow_origins=["*"],
**kwargs,
):
# Server API Key
api_dependency = get_verify_api_key(api_key) if api_key else None
@ -154,7 +150,7 @@ async def run(
server_command = kwargs.get("server_command")
name = kwargs.get("name") or "MCP OpenAPI Proxy"
description = (
kwargs.get("description") or "Automatically generated API from MCP Tool Schemas"
kwargs.get("description") or "Automatically generated API from MCP Tool Schemas"
)
version = kwargs.get("version") or "1.0"
ssl_certfile = kwargs.get("ssl_certfile")
@ -184,14 +180,13 @@ async def run(
with open(config_path, "r") as f:
config_data = json.load(f)
mcp_servers = config_data.get("mcpServers", {})
if not mcp_servers:
raise ValueError("No 'mcpServers' found in config file.")
main_app.description += "\n\n- **available tools**"
for server_name, server_cfg in mcp_servers.items():
sub_app = FastAPI(
title=f"{server_name}",
description=f"{server_name} MCP Server",
description=f"{server_name} MCP Server\n\n- [back to tool list](http://{host}:{port}/docs)",
version="1.0",
lifespan=lifespan,
)
@ -209,13 +204,12 @@ async def run(
sub_app.state.env = {**os.environ, **server_cfg.get("env", {})}
sub_app.state.api_dependency = api_dependency
main_app.mount(f"{path_prefix}{server_name}", sub_app)
main_app.description += f"\n - [{server_name}](http://{host}:{port}/{server_name}/docs)"
else:
raise ValueError("You must provide either server_command or config.")
config = uvicorn.Config(app=main_app, host=host, port=port, ssl_certfile=ssl_certfile , ssl_keyfile=ssl_keyfile ,log_level="info")
config = uvicorn.Config(app=main_app, host=host, port=port, ssl_certfile=ssl_certfile, ssl_keyfile=ssl_keyfile, log_level="info")
server = uvicorn.Server(config)
await server.serve()