Skip to content

Commit 4e75554

Browse files
ochafikclaude
andcommitted
feat(examples): add configurable delays to simpleStreamableHttp handlers
Add environment variable controlled delays for testing purposes: - MCP_DELAY_LIST_TOOLS_MS: Delay tools/list requests - MCP_DELAY_CALL_TOOL_MS: Delay tools/call requests - MCP_DELAY_DCR_MS: Delay Dynamic Client Registration This enables testing timeout handling, async behavior, and auth flow timing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 4fb4d4d commit 4e75554

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

src/examples/server/demoInMemoryOAuthProvider.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ import { createOAuthMetadata, mcpAuthRouter } from '../../server/auth/router.js'
88
import { resourceUrlFromServerUrl } from '../../shared/auth-utils.js';
99
import { InvalidRequestError } from '../../server/auth/errors.js';
1010

11+
// Configurable delay for DCR registration (in milliseconds)
12+
const DELAY_DCR_MS = parseInt(process.env.MCP_DELAY_DCR_MS || '0', 10);
13+
14+
// Helper to introduce artificial delays
15+
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
16+
1117
export class DemoInMemoryClientsStore implements OAuthRegisteredClientsStore {
1218
private clients = new Map<string, OAuthClientInformationFull>();
1319

@@ -16,6 +22,10 @@ export class DemoInMemoryClientsStore implements OAuthRegisteredClientsStore {
1622
}
1723

1824
async registerClient(clientMetadata: OAuthClientInformationFull) {
25+
if (DELAY_DCR_MS > 0) {
26+
console.log(`Delaying DCR registration by ${DELAY_DCR_MS}ms`);
27+
await sleep(DELAY_DCR_MS);
28+
}
1929
this.clients.set(clientMetadata.client_id, clientMetadata);
2030
return clientMetadata;
2131
}

src/examples/server/simpleStreamableHttp.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,21 @@ import cors from 'cors';
2626
const useOAuth = process.argv.includes('--oauth');
2727
const strictOAuth = process.argv.includes('--oauth-strict');
2828

29+
// Configurable delays for testing (in milliseconds)
30+
const DELAY_LIST_TOOLS_MS = parseInt(process.env.MCP_DELAY_LIST_TOOLS_MS || '0', 10);
31+
const DELAY_CALL_TOOL_MS = parseInt(process.env.MCP_DELAY_CALL_TOOL_MS || '0', 10);
32+
33+
// Helper to introduce artificial delays
34+
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
35+
36+
// Check if a JSON-RPC request body contains a specific method
37+
const hasMethod = (body: unknown, method: string): boolean => {
38+
if (Array.isArray(body)) {
39+
return body.some(req => req?.method === method);
40+
}
41+
return (body as { method?: string })?.method === method;
42+
};
43+
2944
// Create shared task store for demonstration
3045
const taskStore = new InMemoryTaskStore();
3146

@@ -602,6 +617,17 @@ const mcpPostHandler = async (req: Request, res: Response) => {
602617
if (useOAuth && req.auth) {
603618
console.log('Authenticated user:', req.auth);
604619
}
620+
621+
// Apply configurable delays for testing
622+
if (DELAY_LIST_TOOLS_MS > 0 && hasMethod(req.body, 'tools/list')) {
623+
console.log(`Delaying tools/list by ${DELAY_LIST_TOOLS_MS}ms`);
624+
await sleep(DELAY_LIST_TOOLS_MS);
625+
}
626+
if (DELAY_CALL_TOOL_MS > 0 && hasMethod(req.body, 'tools/call')) {
627+
console.log(`Delaying tools/call by ${DELAY_CALL_TOOL_MS}ms`);
628+
await sleep(DELAY_CALL_TOOL_MS);
629+
}
630+
605631
try {
606632
let transport: StreamableHTTPServerTransport;
607633
if (sessionId && transports[sessionId]) {

0 commit comments

Comments
 (0)