Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 65 additions & 32 deletions examples/servers/typescript/everything-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,42 +439,75 @@ function createMcpServer() {
inputSchema: {} // Empty schema so callback gets (args, extra) instead of just (extra)
},
async (_args, { sendNotification, _meta }) => {
const progressToken = _meta?.progressToken ?? 0;
console.log('???? Progress token:', progressToken);
await sendNotification({
method: 'notifications/progress',
params: {
progressToken,
progress: 0,
total: 100,
message: `Completed step ${0} of ${100}`
}
});
await new Promise((resolve) => setTimeout(resolve, 50));
const progressToken = _meta?.progressToken;
if (progressToken !== undefined) {
await sendNotification({
method: 'notifications/progress',
params: {
progressToken,
progress: 0,
total: 100,
message: `Completed step ${0} of ${100}`
}
});
await new Promise((resolve) => setTimeout(resolve, 50));

await sendNotification({
method: 'notifications/progress',
params: {
progressToken,
progress: 50,
total: 100,
message: `Completed step ${50} of ${100}`
}
});
await new Promise((resolve) => setTimeout(resolve, 50));

await sendNotification({
method: 'notifications/progress',
params: {
progressToken,
progress: 100,
total: 100,
message: `Completed step ${100} of ${100}`
}
});
}

await sendNotification({
method: 'notifications/progress',
params: {
progressToken,
progress: 50,
total: 100,
message: `Completed step ${50} of ${100}`
}
});
await new Promise((resolve) => setTimeout(resolve, 50));
return {
content: [{ type: 'text', text: String(progressToken ?? 'no-token') }]
};
}
);

await sendNotification({
method: 'notifications/progress',
params: {
progressToken,
progress: 100,
total: 100,
message: `Completed step ${100} of ${100}`
}
});
// Slow tool for cancellation testing
mcpServer.registerTool(
'test_tool_slow',
{
description:
'Sleeps for the specified duration (durationMs, default 5000) before returning. Used for cancellation testing.',
inputSchema: {}
},
async (args) => {
const duration = (args as { durationMs?: number }).durationMs ?? 5000;
await new Promise((resolve) => setTimeout(resolve, duration));
return {
content: [{ type: 'text', text: `Slept for ${duration}ms` }]
};
}
);

// Fast tool for health-check after cancellation
mcpServer.registerTool(
'test_tool_fast',
{
description:
'Returns immediately. Used as a health check after cancellation tests.',
inputSchema: {}
},
async () => {
return {
content: [{ type: 'text', text: String(progressToken) }]
content: [{ type: 'text', text: 'Fast response' }]
};
}
);
Expand Down
10 changes: 10 additions & 0 deletions src/scenarios/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ import {
PromptsGetWithImageScenario
} from './server/prompts';

import { CancellationScenario } from './server/cancellation';
import { ProgressNotificationsScenario } from './server/progress-notifications';
import { DNSRebindingProtectionScenario } from './server/dns-rebinding';
import { CachingScenario } from './server/caching';

Expand Down Expand Up @@ -123,6 +125,12 @@ import { JsonSchema2020_12PreservationScenario } from './client/json-schema-2020

// Pending client scenarios (not yet fully tested/implemented)
const pendingClientScenariosList: ClientScenario[] = [
// Cancellation and progress scenarios require test_tool_slow, test_tool_fast,
// and the progressToken guard fix in the everything-server. These additions
// are included in this branch but not yet merged to the server's main.
new CancellationScenario(),
new ProgressNotificationsScenario(),

// JSON Schema 2020-12 (SEP-1613)
// This test is pending until the SDK includes PR #1135 which preserves
// $schema, $defs, and additionalProperties fields in tool schemas.
Expand Down Expand Up @@ -165,6 +173,8 @@ const allClientScenariosList: ClientScenario[] = [
new LoggingSetLevelScenario(),
new PingScenario(),
new CompletionCompleteScenario(),
new CancellationScenario(),
new ProgressNotificationsScenario(),

// Tools scenarios
new ToolsListScenario(),
Expand Down
Loading