Skip to content

Commit 360fd62

Browse files
committed
custom-mcp-servers
1 parent a7aee07 commit 360fd62

File tree

1 file changed

+59
-19
lines changed

1 file changed

+59
-19
lines changed

src/mcp_server_metatool/server.py

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import httpx
99
import os
1010
import re
11+
import tempfile
1112

1213

1314
def sanitize_name(name: str) -> str:
@@ -25,23 +26,62 @@ def sanitize_name(name: str) -> str:
2526

2627

2728
async def get_mcp_servers() -> list[StdioServerParameters]:
28-
async with httpx.AsyncClient() as client:
29-
"""Get MCP servers from the API."""
30-
headers = {"Authorization": f"Bearer {os.environ['METATOOL_API_KEY']}"}
31-
response = await client.get(
32-
f"{METATOOL_API_BASE_URL}/api/mcp-servers", headers=headers
33-
)
34-
response.raise_for_status()
35-
data = response.json()
36-
server_params = []
37-
for params in data:
38-
# Convert empty lists and dicts to None
39-
if "args" in params and not params["args"]:
40-
params["args"] = None
41-
if "env" in params and not params["env"]:
42-
params["env"] = None
43-
server_params.append(StdioServerParameters(**params))
44-
return server_params
29+
try:
30+
async with httpx.AsyncClient() as client:
31+
"""Get MCP servers from the API."""
32+
headers = {"Authorization": f"Bearer {os.environ['METATOOL_API_KEY']}"}
33+
response = await client.get(
34+
f"{METATOOL_API_BASE_URL}/api/mcp-servers", headers=headers
35+
)
36+
response.raise_for_status()
37+
data = response.json()
38+
server_params = []
39+
for params in data:
40+
# Convert empty lists and dicts to None
41+
if "args" in params and not params["args"]:
42+
params["args"] = None
43+
if "env" in params and not params["env"]:
44+
params["env"] = None
45+
server_params.append(StdioServerParameters(**params))
46+
return server_params
47+
except Exception:
48+
return []
49+
50+
51+
async def get_custom_mcp_servers() -> list[StdioServerParameters]:
52+
try:
53+
async with httpx.AsyncClient() as client:
54+
headers = {"Authorization": f"Bearer {os.environ['METATOOL_API_KEY']}"}
55+
response = await client.get(
56+
f"{METATOOL_API_BASE_URL}/api/custom-mcp-servers", headers=headers
57+
)
58+
response.raise_for_status()
59+
data = response.json()
60+
server_params = []
61+
for params in data:
62+
if "code" not in params or "code_uuid" not in params:
63+
continue
64+
code_uuid = params["code_uuid"]
65+
with tempfile.NamedTemporaryFile(
66+
mode="w", suffix=f"_{code_uuid}.py", delete=False
67+
) as temp_file:
68+
temp_file.write(params["code"])
69+
params["command"] = "uv"
70+
params["args"] = ["run", temp_file.name] + params.get(
71+
"additionalArgs", []
72+
)
73+
if "env" in params and not params["env"]:
74+
params["env"] = None
75+
server_params.append(StdioServerParameters(**params))
76+
return server_params
77+
except Exception:
78+
return []
79+
80+
81+
async def get_all_mcp_servers() -> list[StdioServerParameters]:
82+
server_params = await get_mcp_servers()
83+
custom_server_params = await get_custom_mcp_servers()
84+
return server_params + custom_server_params
4585

4686

4787
async def initialize_session(session: ClientSession) -> dict:
@@ -57,7 +97,7 @@ async def initialize_session(session: ClientSession) -> dict:
5797
@server.list_tools()
5898
async def handle_list_tools() -> list[types.Tool]:
5999
# Reload MCP servers
60-
remote_server_params = await get_mcp_servers()
100+
remote_server_params = await get_all_mcp_servers()
61101

62102
# Combine with default servers
63103
all_server_params = remote_server_params
@@ -94,7 +134,7 @@ async def handle_call_tool(
94134
)
95135

96136
# Get all server parameters
97-
remote_server_params = await get_mcp_servers()
137+
remote_server_params = await get_all_mcp_servers()
98138

99139
# Find the matching server parameters
100140
for params in remote_server_params:

0 commit comments

Comments
 (0)