Skip to content

Commit b34ca81

Browse files
authored
Merge pull request modelcontextprotocol#10 from modelcontextprotocol/ashwin/promptargs
make prompts pass args
2 parents 219dada + 88df0cd commit b34ca81

File tree

4 files changed

+65
-23
lines changed

4 files changed

+65
-23
lines changed

client/src/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ const App = () => {
139139
sendWebSocketMessage({ type: "listPrompts" });
140140
};
141141

142-
const getPrompt = (name: string) => {
143-
sendWebSocketMessage({ type: "getPrompt", name });
142+
const getPrompt = (name: string, args: Record<string, unknown> = {}) => {
143+
sendWebSocketMessage({ type: "getPrompt", name, args });
144144
};
145145

146146
const listTools = () => {

client/src/components/PromptsTab.tsx

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
import { Send, AlertCircle } from "lucide-react";
1+
import { AlertCircle } from "lucide-react";
22
import { Button } from "@/components/ui/button";
33
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
44
import { TabsContent } from "@/components/ui/tabs";
55
import { Input } from "@/components/ui/input";
66
import { Textarea } from "@/components/ui/textarea";
7+
import { useState } from "react";
78

89
export type Prompt = {
9-
id: string;
1010
name: string;
11+
description?: string;
12+
arguments?: {
13+
name: string;
14+
description?: string;
15+
required?: boolean;
16+
}[];
1117
};
1218

1319
const PromptsTab = ({
@@ -21,12 +27,24 @@ const PromptsTab = ({
2127
}: {
2228
prompts: Prompt[];
2329
listPrompts: () => void;
24-
getPrompt: (name: string) => void;
30+
getPrompt: (name: string, args: Record<string, string>) => void;
2531
selectedPrompt: Prompt | null;
2632
setSelectedPrompt: (prompt: Prompt) => void;
2733
promptContent: string;
2834
error: string | null;
2935
}) => {
36+
const [promptArgs, setPromptArgs] = useState<Record<string, string>>({});
37+
38+
const handleInputChange = (argName: string, value: string) => {
39+
setPromptArgs((prev) => ({ ...prev, [argName]: value }));
40+
};
41+
42+
const handleGetPrompt = () => {
43+
if (selectedPrompt) {
44+
getPrompt(selectedPrompt.name, promptArgs);
45+
}
46+
};
47+
3048
return (
3149
<TabsContent value="prompts" className="grid grid-cols-2 gap-4">
3250
<div className="bg-white rounded-lg shadow">
@@ -44,11 +62,11 @@ const PromptsTab = ({
4462
<div className="space-y-2">
4563
{prompts.map((prompt) => (
4664
<div
47-
key={prompt.id}
65+
key={prompt.name}
4866
className="flex items-center p-2 rounded hover:bg-gray-50 cursor-pointer"
4967
onClick={() => {
5068
setSelectedPrompt(prompt);
51-
getPrompt(prompt.name);
69+
setPromptArgs({});
5270
}}
5371
>
5472
<span className="flex-1">{prompt.name}</span>
@@ -73,18 +91,40 @@ const PromptsTab = ({
7391
</Alert>
7492
) : selectedPrompt ? (
7593
<div className="space-y-4">
76-
<Textarea
77-
value={promptContent}
78-
readOnly
79-
className="h-64 font-mono"
80-
/>
81-
<div className="flex space-x-2">
82-
<Input placeholder="Enter your message" />
83-
<Button>
84-
<Send className="w-4 h-4 mr-2" />
85-
Send
86-
</Button>
87-
</div>
94+
{selectedPrompt.description && (
95+
<p className="text-sm text-gray-600">
96+
{selectedPrompt.description}
97+
</p>
98+
)}
99+
{selectedPrompt.arguments?.map((arg) => (
100+
<div key={arg.name}>
101+
<Input
102+
placeholder={`Enter ${arg.name}`}
103+
value={promptArgs[arg.name] || ""}
104+
onChange={(e) =>
105+
handleInputChange(arg.name, e.target.value)
106+
}
107+
/>
108+
{arg.description && (
109+
<p className="text-xs text-gray-500 mt-1">
110+
{arg.description}
111+
{arg.required && (
112+
<span className="text-xs mt-1 ml-1">(Required)</span>
113+
)}
114+
</p>
115+
)}
116+
</div>
117+
))}
118+
<Button onClick={handleGetPrompt} className="w-full">
119+
Get Prompt
120+
</Button>
121+
{promptContent && (
122+
<Textarea
123+
value={promptContent}
124+
readOnly
125+
className="h-64 font-mono"
126+
/>
127+
)}
88128
</div>
89129
) : (
90130
<Alert>

server/src/client.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,18 @@ export class McpClient {
8080
);
8181
}
8282

83-
async getPrompt(name: string): Promise<GetPromptResult> {
83+
async getPrompt(
84+
name: string,
85+
args?: Record<string, string>,
86+
): Promise<GetPromptResult> {
8487
return await this.client.request(
8588
{
8689
method: "prompts/get",
87-
params: { name },
90+
params: { name, arguments: args },
8891
},
8992
GetPromptResultSchema,
9093
);
9194
}
92-
9395
// Tool Operations
9496
async listTools(): Promise<ListToolsResult> {
9597
return await this.client.request(

server/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ wss.on("connection", (ws: WebSocket) => {
3535
const prompts = await mcpClient.listPrompts();
3636
ws.send(JSON.stringify({ type: "prompts", data: prompts }));
3737
} else if (command.type === "getPrompt" && command.name) {
38-
const prompt = await mcpClient.getPrompt(command.name);
38+
const prompt = await mcpClient.getPrompt(command.name, command.args);
3939
ws.send(JSON.stringify({ type: "prompt", data: prompt }));
4040
} else if (command.type === "listTools") {
4141
const tools = await mcpClient.listTools();

0 commit comments

Comments
 (0)