Skip to content

Commit 63b3560

Browse files
Add JSDoc @example tags with companion .examples.ts files
Create companion `.examples.ts` files for JSDoc `@example` tags: - `mcp.examples.ts` — `McpServer`, `registerTool()`, `registerResource()`, `registerPrompt()`, `connect()`, `sendLoggingMessage()`, and tool logging - `stdio.examples.ts` — `StdioServerTransport` - `completable.examples.ts` — `completable()` shown in prompt context - `streamableHttp.examples.ts` — `WebStandardStreamableHTTPServerTransport` (stateful, stateless, Hono, Workers) - `node/streamableHttp.examples.ts` — `NodeStreamableHTTPServerTransport` (stateful, stateless, Express) Add `@example` tags (with titles) to the source files for `McpServer`, `StdioServerTransport`, `completable()`, and both Streamable HTTP transport classes. Prose bullet lists on the transport classes are placed before `@example` block tags so TypeDoc renders them in the description section. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 796623d commit 63b3560

10 files changed

Lines changed: 511 additions & 45 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Type-checked examples for `streamableHttp.ts`.
3+
*
4+
* These examples are synced into JSDoc comments via the sync-snippets script.
5+
* Each function's region markers define the code snippet that appears in the docs.
6+
*
7+
* @module
8+
*/
9+
10+
import { randomUUID } from 'node:crypto';
11+
import type { IncomingMessage, ServerResponse } from 'node:http';
12+
13+
import { McpServer } from '@modelcontextprotocol/server';
14+
15+
import { NodeStreamableHTTPServerTransport } from './streamableHttp.js';
16+
17+
/**
18+
* Example: Stateful Streamable HTTP transport (Node.js).
19+
*/
20+
async function NodeStreamableHTTPServerTransport_stateful() {
21+
//#region NodeStreamableHTTPServerTransport_stateful
22+
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
23+
24+
const transport = new NodeStreamableHTTPServerTransport({
25+
sessionIdGenerator: () => randomUUID()
26+
});
27+
28+
await server.connect(transport);
29+
//#endregion NodeStreamableHTTPServerTransport_stateful
30+
}
31+
32+
/**
33+
* Example: Stateless Streamable HTTP transport (Node.js).
34+
*/
35+
async function NodeStreamableHTTPServerTransport_stateless() {
36+
//#region NodeStreamableHTTPServerTransport_stateless
37+
const transport = new NodeStreamableHTTPServerTransport({
38+
sessionIdGenerator: undefined
39+
});
40+
//#endregion NodeStreamableHTTPServerTransport_stateless
41+
return transport;
42+
}
43+
44+
// Stubs for Express-style app
45+
declare const app: { post(path: string, handler: (req: IncomingMessage & { body?: unknown }, res: ServerResponse) => void): void };
46+
47+
/**
48+
* Example: Using with a pre-parsed request body (e.g. Express).
49+
*/
50+
function NodeStreamableHTTPServerTransport_express(transport: NodeStreamableHTTPServerTransport) {
51+
//#region NodeStreamableHTTPServerTransport_express
52+
app.post('/mcp', (req, res) => {
53+
transport.handleRequest(req, res, req.body);
54+
});
55+
//#endregion NodeStreamableHTTPServerTransport_express
56+
}

packages/middleware/node/src/streamableHttp.ts

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,6 @@ export type StreamableHTTPServerTransportOptions = WebStandardStreamableHTTPServ
2828
* This is a wrapper around {@linkcode WebStandardStreamableHTTPServerTransport} that provides Node.js HTTP compatibility.
2929
* It uses the `@hono/node-server` library to convert between Node.js HTTP and Web Standard APIs.
3030
*
31-
* Usage example:
32-
*
33-
* ```typescript
34-
* // Stateful mode - server sets the session ID
35-
* const statefulTransport = new StreamableHTTPServerTransport({
36-
* sessionIdGenerator: () => randomUUID(),
37-
* });
38-
*
39-
* // Stateless mode - explicitly set session ID to undefined
40-
* const statelessTransport = new StreamableHTTPServerTransport({
41-
* sessionIdGenerator: undefined,
42-
* });
43-
*
44-
* // Using with pre-parsed request body
45-
* app.post('/mcp', (req, res) => {
46-
* transport.handleRequest(req, res, req.body);
47-
* });
48-
* ```
49-
*
5031
* In stateful mode:
5132
* - Session ID is generated and included in response headers
5233
* - Session ID is always included in initialization responses
@@ -57,6 +38,31 @@ export type StreamableHTTPServerTransportOptions = WebStandardStreamableHTTPServ
5738
* In stateless mode:
5839
* - No Session ID is included in any responses
5940
* - No session validation is performed
41+
*
42+
* @example Stateful setup
43+
* ```ts source="./streamableHttp.examples.ts#NodeStreamableHTTPServerTransport_stateful"
44+
* const server = new McpServer({ name: 'my-server', version: '1.0.0' });
45+
*
46+
* const transport = new NodeStreamableHTTPServerTransport({
47+
* sessionIdGenerator: () => randomUUID()
48+
* });
49+
*
50+
* await server.connect(transport);
51+
* ```
52+
*
53+
* @example Stateless setup
54+
* ```ts source="./streamableHttp.examples.ts#NodeStreamableHTTPServerTransport_stateless"
55+
* const transport = new NodeStreamableHTTPServerTransport({
56+
* sessionIdGenerator: undefined
57+
* });
58+
* ```
59+
*
60+
* @example Using with a pre-parsed request body (e.g. Express)
61+
* ```ts source="./streamableHttp.examples.ts#NodeStreamableHTTPServerTransport_express"
62+
* app.post('/mcp', (req, res) => {
63+
* transport.handleRequest(req, res, req.body);
64+
* });
65+
* ```
6066
*/
6167
export class NodeStreamableHTTPServerTransport implements Transport {
6268
private _webStandardTransport: WebStandardStreamableHTTPServerTransport;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Type-checked examples for `completable.ts`.
3+
*
4+
* These examples are synced into JSDoc comments via the sync-snippets script.
5+
* Each function's region markers define the code snippet that appears in the docs.
6+
*
7+
* @module
8+
*/
9+
10+
import * as z from 'zod/v4';
11+
12+
import { completable } from './completable.js';
13+
import { McpServer } from './mcp.js';
14+
15+
/**
16+
* Example: Using completable() in a prompt registration.
17+
*/
18+
function completable_basicUsage() {
19+
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
20+
21+
//#region completable_basicUsage
22+
server.registerPrompt(
23+
'review-code',
24+
{
25+
title: 'Code Review',
26+
argsSchema: z.object({
27+
language: completable(z.string().describe('Programming language'), value =>
28+
['typescript', 'javascript', 'python', 'rust', 'go'].filter(lang => lang.startsWith(value))
29+
)
30+
})
31+
},
32+
({ language }) => ({
33+
messages: [
34+
{
35+
role: 'user' as const,
36+
content: {
37+
type: 'text' as const,
38+
text: `Review this ${language} code.`
39+
}
40+
}
41+
]
42+
})
43+
);
44+
//#endregion completable_basicUsage
45+
return server;
46+
}

packages/server/src/server/completable.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,32 @@ export type CompletableSchema<T extends AnySchema> = T & {
2121
/**
2222
* Wraps a Zod type to provide autocompletion capabilities. Useful for, e.g., prompt arguments in MCP.
2323
*
24+
* @example
25+
* ```ts source="./completable.examples.ts#completable_basicUsage"
26+
* server.registerPrompt(
27+
* 'review-code',
28+
* {
29+
* title: 'Code Review',
30+
* argsSchema: z.object({
31+
* language: completable(z.string().describe('Programming language'), value =>
32+
* ['typescript', 'javascript', 'python', 'rust', 'go'].filter(lang => lang.startsWith(value))
33+
* )
34+
* })
35+
* },
36+
* ({ language }) => ({
37+
* messages: [
38+
* {
39+
* role: 'user' as const,
40+
* content: {
41+
* type: 'text' as const,
42+
* text: `Review this ${language} code.`
43+
* }
44+
* }
45+
* ]
46+
* })
47+
* );
48+
* ```
49+
*
2450
* @see {@linkcode server/mcp.McpServer.registerPrompt | McpServer.registerPrompt} for using completable schemas in prompt argument definitions
2551
*/
2652
export function completable<T extends AnySchema>(schema: T, complete: CompleteCallback<T>): CompletableSchema<T> {
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/**
2+
* Type-checked examples for `mcp.ts`.
3+
*
4+
* These examples are synced into JSDoc comments via the sync-snippets script.
5+
* Each function's region markers define the code snippet that appears in the docs.
6+
*
7+
* @module
8+
*/
9+
10+
import type { CallToolResult } from '@modelcontextprotocol/core';
11+
import * as z from 'zod/v4';
12+
13+
import { McpServer } from './mcp.js';
14+
import { StdioServerTransport } from './stdio.js';
15+
16+
/**
17+
* Example: Creating a new McpServer.
18+
*/
19+
function McpServer_basicUsage() {
20+
//#region McpServer_basicUsage
21+
const server = new McpServer({
22+
name: 'my-server',
23+
version: '1.0.0'
24+
});
25+
//#endregion McpServer_basicUsage
26+
return server;
27+
}
28+
29+
/**
30+
* Example: Registering a tool with inputSchema and outputSchema.
31+
*/
32+
function McpServer_registerTool_basic(server: McpServer) {
33+
//#region McpServer_registerTool_basic
34+
server.registerTool(
35+
'calculate-bmi',
36+
{
37+
title: 'BMI Calculator',
38+
description: 'Calculate Body Mass Index',
39+
inputSchema: z.object({
40+
weightKg: z.number(),
41+
heightM: z.number()
42+
}),
43+
outputSchema: z.object({ bmi: z.number() })
44+
},
45+
async ({ weightKg, heightM }) => {
46+
const output = { bmi: weightKg / (heightM * heightM) };
47+
return {
48+
content: [{ type: 'text', text: JSON.stringify(output) }],
49+
structuredContent: output
50+
};
51+
}
52+
);
53+
//#endregion McpServer_registerTool_basic
54+
}
55+
56+
/**
57+
* Example: Registering a static resource at a fixed URI.
58+
*/
59+
function McpServer_registerResource_static(server: McpServer) {
60+
//#region McpServer_registerResource_static
61+
server.registerResource(
62+
'config',
63+
'config://app',
64+
{
65+
title: 'Application Config',
66+
mimeType: 'text/plain'
67+
},
68+
async uri => ({
69+
contents: [{ uri: uri.href, text: 'App configuration here' }]
70+
})
71+
);
72+
//#endregion McpServer_registerResource_static
73+
}
74+
75+
/**
76+
* Example: Registering a prompt with an argument schema.
77+
*/
78+
function McpServer_registerPrompt_basic(server: McpServer) {
79+
//#region McpServer_registerPrompt_basic
80+
server.registerPrompt(
81+
'review-code',
82+
{
83+
title: 'Code Review',
84+
description: 'Review code for best practices',
85+
argsSchema: z.object({ code: z.string() })
86+
},
87+
({ code }) => ({
88+
messages: [
89+
{
90+
role: 'user' as const,
91+
content: {
92+
type: 'text' as const,
93+
text: `Please review this code:\n\n${code}`
94+
}
95+
}
96+
]
97+
})
98+
);
99+
//#endregion McpServer_registerPrompt_basic
100+
}
101+
102+
/**
103+
* Example: Connecting an McpServer to a stdio transport.
104+
*/
105+
async function McpServer_connect_stdio() {
106+
//#region McpServer_connect_stdio
107+
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
108+
const transport = new StdioServerTransport();
109+
await server.connect(transport);
110+
//#endregion McpServer_connect_stdio
111+
}
112+
113+
/**
114+
* Example: Sending a log message to the client.
115+
*/
116+
async function McpServer_sendLoggingMessage_basic(server: McpServer) {
117+
//#region McpServer_sendLoggingMessage_basic
118+
await server.sendLoggingMessage({
119+
level: 'info',
120+
data: 'Processing complete'
121+
});
122+
//#endregion McpServer_sendLoggingMessage_basic
123+
}
124+
125+
/**
126+
* Example: Logging from inside a tool handler via ctx.mcpReq.log().
127+
*/
128+
function McpServer_registerTool_logging(server: McpServer) {
129+
//#region McpServer_registerTool_logging
130+
server.registerTool(
131+
'fetch-data',
132+
{
133+
description: 'Fetch data from an API',
134+
inputSchema: z.object({ url: z.string() })
135+
},
136+
async ({ url }, ctx): Promise<CallToolResult> => {
137+
await ctx.mcpReq.log('info', `Fetching ${url}`);
138+
const res = await fetch(url);
139+
await ctx.mcpReq.log('debug', `Response status: ${res.status}`);
140+
const text = await res.text();
141+
return { content: [{ type: 'text', text }] };
142+
}
143+
);
144+
//#endregion McpServer_registerTool_logging
145+
}

0 commit comments

Comments
 (0)