-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
96 lines (79 loc) · 3.12 KB
/
Copy pathserver.py
File metadata and controls
96 lines (79 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import asyncio
import os
from mcp.server import Server, InitializationOptions
from mcp.types import Tool, TextContent, ServerCapabilities
from mcp.server.stdio import stdio_server
SERVER_NAME = "GenPlan"
TOOL_NAME = "pipeline"
server = Server(SERVER_NAME)
# Example of initialization
# {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"my-client","version":"0.1"}}}
# Example of request
# {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"pipeline","arguments":{"args":["--text","house"]}}}
@server.list_tools()
async def list_tools():
current_dir = os.getcwd()
return [
Tool(
name=TOOL_NAME,
description="Launches the Docker container and returns stdout/stderr",
inputSchema={
"type": "object",
"properties": {
"args": {
"type": "array",
"items": {"type": "string"},
"description": "Command line arguments passed to the container. Examples of args in README.md file.",
"default": [],
},
"image": {
"type": "string",
"description": "Docker image.",
"default": "egor0ba/gen-plan-api:latest",
},
"result_folder": {
"type": "string",
"description": "Result folder.",
"default": f"{current_dir}/results",
},
},
"required": ["args"],
},
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name != TOOL_NAME:
raise ValueError(f"Unknown tool: {name}")
current_dir = os.getcwd()
image = arguments.get("image", "egor0ba/gen-plan-api:latest")
result_folder = arguments.get("result_folder", f"{current_dir}/results")
container_args = arguments.get("args", []) or []
cmd = ["docker", "run", "--rm", "-v", f"{result_folder}:/GenPlan/results", image]
cmd += container_args
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
out, err = await proc.communicate()
stdout = out.decode("utf-8", "ignore")
stderr = err.decode("utf-8", "ignore")
if proc.returncode != 0:
return [
TextContent(
type="text",
text=f"ERROR (exit={proc.returncode})\nCMD: {' '.join(cmd)}\n\nSTDERR:\n{stderr}\n\nSTDOUT:\n{stdout}",
)
]
return [TextContent(type="text", text=result_folder)]
async def main():
async with stdio_server() as (read_stream, write_stream):
initialization_options = InitializationOptions(
server_name=SERVER_NAME,
server_version="0.0.1",
capabilities=ServerCapabilities(),
)
await server.run(read_stream, write_stream, initialization_options)
if __name__ == "__main__":
asyncio.run(main())