-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Expand file tree
/
Copy pathserver.py
More file actions
133 lines (112 loc) · 3.85 KB
/
server.py
File metadata and controls
133 lines (112 loc) · 3.85 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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import anyio
import click
import mcp.types as types
from mcp.server.lowlevel import Server
def create_messages(
context: str | None = None, topic: str | None = None
) -> list[types.PromptMessage]:
"""Create the messages for the prompt."""
messages = []
# Add context if provided
if context:
messages.append(
types.PromptMessage(
role="user",
content=types.TextContent(
type="text", text=f"Here is some relevant context: {context}"
),
)
)
# Add the main prompt
prompt = "Please help me with "
if topic:
prompt += f"the following topic: {topic}"
else:
prompt += "whatever questions I may have."
messages.append(
types.PromptMessage(
role="user", content=types.TextContent(type="text", text=prompt)
)
)
return messages
@click.command()
@click.option("--port", default=8000, help="Port to listen on for SSE")
@click.option(
"--transport",
type=click.Choice(["stdio", "sse"]),
default="stdio",
help="Transport type",
)
def main(port: int, transport: str) -> int:
app = Server("mcp-simple-prompt")
@app.list_prompts()
async def list_prompts() -> list[types.Prompt]:
return [
types.Prompt(
name="simple",
description="A simple prompt that can take optional context and topic "
"arguments",
arguments=[
types.PromptArgument(
name="context",
description="Additional context to consider",
required=False,
),
types.PromptArgument(
name="topic",
description="Specific topic to focus on",
required=False,
),
],
)
]
@app.get_prompt()
async def get_prompt(
name: str, arguments: dict[str, str] | None = None
) -> types.GetPromptResult:
if name != "simple":
raise ValueError(f"Unknown prompt: {name}")
if arguments is None:
arguments = {}
return types.GetPromptResult(
messages=create_messages(
context=arguments.get("context"), topic=arguments.get("topic")
),
description="A simple prompt with optional context and topic arguments",
)
if transport == "sse":
from mcp.server.sse import SseServerTransport
from starlette.applications import Starlette
from starlette.responses import Response
from starlette.routing import Mount, Route
sse = SseServerTransport("/messages/")
async def handle_sse(request):
with anyio.CancelScope() as cancel_scope:
async with sse.connect_sse(
request.scope,
request.receive,
request._send,
lambda: cancel_scope.cancel(),
) as streams:
await app.run(
streams[0], streams[1], app.create_initialization_options()
)
return Response(status_code=200)
starlette_app = Starlette(
debug=True,
routes=[
Route("/sse", endpoint=handle_sse),
Mount("/messages/", app=sse.handle_post_message),
],
)
import uvicorn
uvicorn.run(starlette_app, host="0.0.0.0", port=port)
else:
from mcp.server.stdio import stdio_server
async def arun():
async with stdio_server() as streams:
await app.run(
streams[0], streams[1], app.create_initialization_options()
)
anyio.run(arun)
return 0