@raeseoklee/mcp-workbench-demo-server 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # @raeseoklee/mcp-workbench-demo-server
2
+
3
+ A ready-to-use demo [MCP](https://modelcontextprotocol.io) server for **[MCP Workbench](https://github.com/raeseoklee/mcp-workbench)**.
4
+
5
+ Exposes sample tools, resources, and prompts — perfect for trying out MCP Workbench without writing any server code.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -g @raeseoklee/mcp-workbench-demo-server
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```bash
16
+ # Start the demo server (stdio transport)
17
+ mcp-workbench-demo
18
+
19
+ # Inspect with MCP Workbench
20
+ npm install -g @raeseoklee/mcp-workbench
21
+ mcp-workbench inspect --command mcp-workbench-demo
22
+
23
+ # Run the example test suite
24
+ mcp-workbench run examples/fixtures/demo-server.yaml --verbose
25
+ ```
26
+
27
+ ## What's included
28
+
29
+ | Capability | Examples |
30
+ |------------|----------|
31
+ | **Tools** | `get_weather` — returns weather for a city |
32
+ | **Resources** | Note resources with text content |
33
+ | **Prompts** | Greeting prompt with customizable name |
34
+
35
+ ## Built with
36
+
37
+ - [@modelcontextprotocol/sdk](https://www.npmjs.com/package/@modelcontextprotocol/sdk)
38
+ - MCP spec version `2025-11-25`
39
+
40
+ ## Links
41
+
42
+ - [MCP Workbench](https://github.com/raeseoklee/mcp-workbench) — the testing platform
43
+ - [Example test specs](https://github.com/raeseoklee/mcp-workbench/tree/develop/examples/fixtures)
44
+
45
+ ## License
46
+
47
+ [Apache-2.0](https://github.com/raeseoklee/mcp-workbench/blob/develop/LICENSE)
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Demo MCP server using the official @modelcontextprotocol/sdk.
3
+ * Provides a simple weather tool, a note resource, and a greeting prompt —
4
+ * just enough to exercise all of MCP Workbench's features.
5
+ */
6
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
7
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
9
+ const CITIES = {
10
+ Seoul: { temp: 18, condition: "Partly cloudy" },
11
+ Tokyo: { temp: 22, condition: "Sunny" },
12
+ London: { temp: 12, condition: "Rainy" },
13
+ New_York: { temp: 20, condition: "Clear" },
14
+ };
15
+ const NOTES = {
16
+ "note://welcome": "Welcome to MCP Workbench! This is a demo note resource.",
17
+ "note://readme": "# Demo Server\n\nThis server is part of the MCP Workbench examples.",
18
+ };
19
+ const server = new Server({ name: "demo-mcp-server", version: "0.1.0" }, {
20
+ capabilities: {
21
+ tools: { listChanged: false },
22
+ resources: { subscribe: false, listChanged: false },
23
+ prompts: { listChanged: false },
24
+ },
25
+ });
26
+ // ─── Tool: list-roots (exercises client roots capability) ────────────────────
27
+ // This tool asks the client for its roots list, then returns them as text.
28
+ // It demonstrates the server→client roots/list call pattern.
29
+ // ─── Tools ───────────────────────────────────────────────────────────────────
30
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
31
+ tools: [
32
+ {
33
+ name: "list_roots",
34
+ description: "Ask the client for its workspace roots (exercises roots capability)",
35
+ inputSchema: { type: "object", properties: {} },
36
+ annotations: { readOnlyHint: true, title: "List Roots" },
37
+ },
38
+ {
39
+ name: "get_weather",
40
+ description: "Get current weather for a city",
41
+ inputSchema: {
42
+ type: "object",
43
+ properties: {
44
+ city: {
45
+ type: "string",
46
+ description: "City name (Seoul, Tokyo, London, New_York)",
47
+ },
48
+ },
49
+ required: ["city"],
50
+ },
51
+ annotations: {
52
+ readOnlyHint: true,
53
+ title: "Get Weather",
54
+ },
55
+ },
56
+ {
57
+ name: "create_note",
58
+ description: "Create a new note (destructive example)",
59
+ inputSchema: {
60
+ type: "object",
61
+ properties: {
62
+ id: { type: "string" },
63
+ content: { type: "string" },
64
+ },
65
+ required: ["id", "content"],
66
+ },
67
+ annotations: {
68
+ destructiveHint: true,
69
+ title: "Create Note",
70
+ },
71
+ },
72
+ ],
73
+ }));
74
+ server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
75
+ const { name, arguments: args = {} } = request.params;
76
+ if (name === "list_roots") {
77
+ try {
78
+ // Ask the client for its roots via the session
79
+ const result = await extra.sendRequest({ method: "roots/list", params: {} },
80
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
81
+ {});
82
+ const lines = result.roots.map((r) => `${r.uri}${r.name ? ` (${r.name})` : ""}`);
83
+ return {
84
+ content: [{
85
+ type: "text",
86
+ text: lines.length ? `Roots:\n${lines.join("\n")}` : "No roots provided by client",
87
+ }],
88
+ };
89
+ }
90
+ catch {
91
+ return {
92
+ isError: true,
93
+ content: [{ type: "text", text: "Client does not support roots/list" }],
94
+ };
95
+ }
96
+ }
97
+ if (name === "get_weather") {
98
+ const city = args["city"];
99
+ if (!city || typeof city !== "string") {
100
+ return {
101
+ isError: true,
102
+ content: [{ type: "text", text: "Error: city must be a string" }],
103
+ };
104
+ }
105
+ const weather = CITIES[city];
106
+ if (!weather) {
107
+ return {
108
+ isError: true,
109
+ content: [
110
+ {
111
+ type: "text",
112
+ text: `Error: unknown city "${city}". Known cities: ${Object.keys(CITIES).join(", ")}`,
113
+ },
114
+ ],
115
+ };
116
+ }
117
+ return {
118
+ content: [
119
+ {
120
+ type: "text",
121
+ text: `Weather in ${city}: ${weather.temp}°C, ${weather.condition}`,
122
+ },
123
+ ],
124
+ };
125
+ }
126
+ if (name === "create_note") {
127
+ const id = args["id"];
128
+ const content = args["content"];
129
+ NOTES[`note://${id}`] = content;
130
+ return {
131
+ content: [{ type: "text", text: `Note created: note://${id}` }],
132
+ };
133
+ }
134
+ return {
135
+ isError: true,
136
+ content: [{ type: "text", text: `Unknown tool: ${name}` }],
137
+ };
138
+ });
139
+ // ─── Resources ───────────────────────────────────────────────────────────────
140
+ server.setRequestHandler(ListResourcesRequestSchema, async () => ({
141
+ resources: Object.keys(NOTES).map((uri) => ({
142
+ uri,
143
+ name: uri.replace("note://", ""),
144
+ mimeType: "text/plain",
145
+ })),
146
+ }));
147
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
148
+ const { uri } = request.params;
149
+ const content = NOTES[uri];
150
+ if (!content) {
151
+ throw new Error(`Resource not found: ${uri}`);
152
+ }
153
+ return {
154
+ contents: [{ uri, mimeType: "text/plain", text: content }],
155
+ };
156
+ });
157
+ // ─── Prompts ─────────────────────────────────────────────────────────────────
158
+ server.setRequestHandler(ListPromptsRequestSchema, async () => ({
159
+ prompts: [
160
+ {
161
+ name: "greet",
162
+ description: "Generate a greeting message",
163
+ arguments: [
164
+ { name: "name", description: "Person to greet", required: true },
165
+ { name: "style", description: "formal | casual", required: false },
166
+ ],
167
+ },
168
+ ],
169
+ }));
170
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
171
+ const { name, arguments: args = {} } = request.params;
172
+ if (name !== "greet")
173
+ throw new Error(`Unknown prompt: ${name}`);
174
+ const personName = args["name"] ?? "World";
175
+ const style = args["style"] ?? "casual";
176
+ const greeting = style === "formal"
177
+ ? `Good day, ${personName}. How may I assist you?`
178
+ : `Hey ${personName}! What's up?`;
179
+ return {
180
+ description: "A greeting message",
181
+ messages: [
182
+ { role: "user", content: { type: "text", text: greeting } },
183
+ ],
184
+ };
185
+ });
186
+ // ─── Start ───────────────────────────────────────────────────────────────────
187
+ const transport = new StdioServerTransport();
188
+ await server.connect(transport);
189
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@raeseoklee/mcp-workbench-demo-server",
3
+ "version": "0.1.0",
4
+ "description": "Demo MCP server for MCP Workbench — tools, resources, and prompts out of the box",
5
+ "type": "module",
6
+ "license": "Apache-2.0",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/raeseoklee/mcp-workbench.git"
10
+ },
11
+ "homepage": "https://github.com/raeseoklee/mcp-workbench#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/raeseoklee/mcp-workbench/issues"
14
+ },
15
+ "keywords": [
16
+ "mcp",
17
+ "model-context-protocol",
18
+ "mcp-server",
19
+ "demo",
20
+ "example",
21
+ "mcp-workbench"
22
+ ],
23
+ "engines": {
24
+ "node": ">=20.0.0"
25
+ },
26
+ "main": "./dist/index.js",
27
+ "bin": {
28
+ "mcp-workbench-demo": "dist/index.js"
29
+ },
30
+ "files": [
31
+ "dist"
32
+ ],
33
+ "scripts": {
34
+ "build": "tsc",
35
+ "start": "node dist/index.js",
36
+ "dev": "tsc --watch"
37
+ },
38
+ "dependencies": {
39
+ "@modelcontextprotocol/sdk": "^1.0.0"
40
+ },
41
+ "devDependencies": {
42
+ "typescript": "^5.6.0",
43
+ "@types/node": "^22.0.0"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ }
48
+ }