typescript-sdk/examples/standalone-get/client.ts
Felix Weinberger 1823aae891
Implement MCP 2026-07-28 (#2286)
Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
Co-authored-by: Konstantin Konstantinov <KKonstantinov@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-26 14:01:10 +01:00

40 lines
1.5 KiB
TypeScript

/**
* Connects (2025-era), opens the standalone GET stream by registering a
* `listChanged` handler, calls `add_resource` to trigger a
* `notifications/resources/list_changed` over that stream, and asserts it
* arrived.
*/
import { check, parseExampleArgs } from '@mcp-examples/shared';
import { Client, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';
const { url } = parseExampleArgs();
let received = 0;
const client = new Client(
{ name: 'standalone-get-client', version: '1.0.0' },
{
// Explicitly the 2025 `initialize` handshake — the standalone GET
// stream is a sessionful-2025 transport feature, so this story is
// legacy-only by design (was reaching 2025 by fallback; pin it).
versionNegotiation: { mode: 'legacy' },
listChanged: { resources: { autoRefresh: false, debounceMs: 0, onChanged: () => void received++ } }
}
);
await client.connect(new StreamableHTTPClientTransport(new URL(url)));
const before = await client.listResources();
check.ok(before.resources.length > 0);
// Mutate on demand → server emits list_changed over the standalone GET stream.
await client.callTool({ name: 'add_resource', arguments: { content: 'hello' } });
const deadline = Date.now() + 5000;
while (received < 1) {
if (Date.now() > deadline) throw new Error('no listChanged within 5s');
await new Promise(r => setTimeout(r, 25));
}
check.ok(received >= 1);
const after = await client.listResources();
check.ok(after.resources.length > before.resources.length);
await client.close();