Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitef4e4ee

Browse files
Merge pull request#17 from Danielpeter-99/main
feat(mcp): enhance MCP server creation with tool discovery and async handling
2 parents25db7e8 +7a9d3e1 commitef4e4ee

File tree

4 files changed

+70
-5
lines changed

4 files changed

+70
-5
lines changed

‎src/api/mcp_server_routes.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"""
2929

3030
fromfastapiimportAPIRouter,Depends,HTTPException,status
31+
fromstarlette.concurrencyimportrun_in_threadpool
3132
fromsqlalchemy.ormimportSession
3233
fromsrc.config.databaseimportget_db
3334
fromtypingimportList
@@ -54,7 +55,7 @@
5455
responses={404: {"description":"Not found"}},
5556
)
5657

57-
58+
# Last edited by Arley Peter on 2025-05-17
5859
@router.post("/",response_model=MCPServer,status_code=status.HTTP_201_CREATED)
5960
asyncdefcreate_mcp_server(
6061
server:MCPServerCreate,
@@ -64,7 +65,7 @@ async def create_mcp_server(
6465
# Only administrators can create MCP servers
6566
awaitverify_admin(payload)
6667

67-
returnmcp_server_service.create_mcp_server(db,server)
68+
returnawaitrun_in_threadpool(mcp_server_service.create_mcp_server,db,server)
6869

6970

7071
@router.get("/",response_model=List[MCPServer])

‎src/schemas/schemas.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,14 @@ class ToolConfig(BaseModel):
262262
inputModes:List[str]=Field(default_factory=list)
263263
outputModes:List[str]=Field(default_factory=list)
264264

265-
265+
# Last edited by Arley Peter on 2025-05-17
266266
classMCPServerBase(BaseModel):
267267
name:str
268268
description:Optional[str]=None
269269
config_type:str=Field(default="studio")
270270
config_json:Dict[str,Any]=Field(default_factory=dict)
271271
environments:Dict[str,Any]=Field(default_factory=dict)
272-
tools:List[ToolConfig]=Field(default_factory=list)
272+
tools:Optional[List[ToolConfig]]=Field(default_factory=list)
273273
type:str=Field(default="official")
274274

275275

‎src/services/mcp_server_service.py‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
fromfastapiimportHTTPException,status
3333
fromsrc.models.modelsimportMCPServer
3434
fromsrc.schemas.schemasimportMCPServerCreate
35+
fromsrc.utils.mcp_discoveryimportdiscover_mcp_tools
3536
fromtypingimportList,Optional
3637
importuuid
3738
importlogging
@@ -72,8 +73,16 @@ def create_mcp_server(db: Session, server: MCPServerCreate) -> MCPServer:
7273
try:
7374
# Convert tools to JSON serializable format
7475
server_data=server.model_dump()
75-
server_data["tools"]= [tool.model_dump()fortoolinserver.tools]
7676

77+
# Last edited by Arley Peter on 2025-05-17
78+
supplied_tools=server_data.pop("tools", [])
79+
ifnotsupplied_tools:
80+
discovered=discover_mcp_tools(server_data["config_json"])
81+
print(f"🔍 Found{len(discovered)} tools.")
82+
server_data["tools"]=discovered
83+
84+
else:
85+
server_data["tools"]= [tool.model_dump()fortoolinsupplied_tools]
7786
db_server=MCPServer(**server_data)
7887
db.add(db_server)
7988
db.commit()

‎src/utils/mcp_discovery.py‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""
2+
┌──────────────────────────────────────────────────────────────────────────────┐
3+
│ @author: Arley Peter │
4+
│ @file: mcp_discovery.py │
5+
│ Developed by: Arley Peter │
6+
│ Creation date: May 05, 2025 │
7+
├──────────────────────────────────────────────────────────────────────────────┤
8+
│ @copyright © Evolution API 2025. All rights reserved. │
9+
│ Licensed under the Apache License, Version 2.0 │
10+
│ │
11+
│ You may not use this file except in compliance with the License. │
12+
│ You may obtain a copy of the License at │
13+
│ │
14+
│ http://www.apache.org/licenses/LICENSE-2.0 │
15+
│ │
16+
│ Unless required by applicable law or agreed to in writing, software │
17+
│ distributed under the License is distributed on an "AS IS" BASIS, │
18+
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
19+
│ See the License for the specific language governing permissions and │
20+
│ limitations under the License. │
21+
├──────────────────────────────────────────────────────────────────────────────┤
22+
│ @important │
23+
│ For any future changes to the code in this file, it is recommended to │
24+
│ include, together with the modification, the information of the developer │
25+
│ who changed it and the date of modification. │
26+
└──────────────────────────────────────────────────────────────────────────────┘
27+
"""
28+
29+
fromtypingimportList,Dict,Any
30+
importasyncio
31+
32+
asyncdef_discover_async(config_json:Dict[str,Any])->List[Dict[str,Any]]:
33+
"""Return a list[dict] with the tool metadata advertised by the MCP server."""
34+
35+
fromsrc.services.mcp_serviceimportMCPService
36+
37+
service=MCPService()
38+
tools,exit_stack=awaitservice._connect_to_mcp_server(config_json)
39+
serialised= [t.to_dict()ifhasattr(t,"to_dict")else {
40+
"id":t.name,
41+
"name":t.name,
42+
"description":getattr(t,"description",t.name),
43+
"tags":getattr(t,"tags", []),
44+
"examples":getattr(t,"examples", []),
45+
"inputModes":getattr(t,"input_modes", ["text"]),
46+
"outputModes":getattr(t,"output_modes", ["text"]),
47+
}fortintools]
48+
ifexit_stack:
49+
awaitexit_stack.aclose()
50+
returnserialised
51+
52+
53+
defdiscover_mcp_tools(config_json:Dict[str,Any])->List[Dict[str,Any]]:
54+
"""Sync wrapper so we can call it from a sync service function."""
55+
returnasyncio.run(_discover_async(config_json))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp