ssePollingClient.js 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. /**
  4. * SSE Polling Example Client (SEP-1699)
  5. *
  6. * This example demonstrates client-side behavior during server-initiated
  7. * SSE stream disconnection and automatic reconnection.
  8. *
  9. * Key features demonstrated:
  10. * - Automatic reconnection when server closes SSE stream
  11. * - Event replay via Last-Event-ID header
  12. * - Resumption token tracking via onresumptiontoken callback
  13. *
  14. * Run with: npx tsx src/examples/client/ssePollingClient.ts
  15. * Requires: ssePollingExample.ts server running on port 3001
  16. */
  17. const index_js_1 = require("../../client/index.js");
  18. const streamableHttp_js_1 = require("../../client/streamableHttp.js");
  19. const types_js_1 = require("../../types.js");
  20. const SERVER_URL = 'http://localhost:3001/mcp';
  21. async function main() {
  22. console.log('SSE Polling Example Client');
  23. console.log('==========================');
  24. console.log(`Connecting to ${SERVER_URL}...`);
  25. console.log('');
  26. // Create transport with reconnection options
  27. const transport = new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(SERVER_URL), {
  28. // Use default reconnection options - SDK handles automatic reconnection
  29. });
  30. // Track the last event ID for debugging
  31. let lastEventId;
  32. // Set up transport error handler to observe disconnections
  33. // Filter out expected errors from SSE reconnection
  34. transport.onerror = error => {
  35. // Skip abort errors during intentional close
  36. if (error.message.includes('AbortError'))
  37. return;
  38. // Show SSE disconnect (expected when server closes stream)
  39. if (error.message.includes('Unexpected end of JSON')) {
  40. console.log('[Transport] SSE stream disconnected - client will auto-reconnect');
  41. return;
  42. }
  43. console.log(`[Transport] Error: ${error.message}`);
  44. };
  45. // Set up transport close handler
  46. transport.onclose = () => {
  47. console.log('[Transport] Connection closed');
  48. };
  49. // Create and connect client
  50. const client = new index_js_1.Client({
  51. name: 'sse-polling-client',
  52. version: '1.0.0'
  53. });
  54. // Set up notification handler to receive progress updates
  55. client.setNotificationHandler(types_js_1.LoggingMessageNotificationSchema, notification => {
  56. const data = notification.params.data;
  57. console.log(`[Notification] ${data}`);
  58. });
  59. try {
  60. await client.connect(transport);
  61. console.log('[Client] Connected successfully');
  62. console.log('');
  63. // Call the long-task tool
  64. console.log('[Client] Calling long-task tool...');
  65. console.log('[Client] Server will disconnect mid-task to demonstrate polling');
  66. console.log('');
  67. const result = await client.request({
  68. method: 'tools/call',
  69. params: {
  70. name: 'long-task',
  71. arguments: {}
  72. }
  73. }, types_js_1.CallToolResultSchema, {
  74. // Track resumption tokens for debugging
  75. onresumptiontoken: token => {
  76. lastEventId = token;
  77. console.log(`[Event ID] ${token}`);
  78. }
  79. });
  80. console.log('');
  81. console.log('[Client] Tool completed!');
  82. console.log(`[Result] ${JSON.stringify(result.content, null, 2)}`);
  83. console.log('');
  84. console.log(`[Debug] Final event ID: ${lastEventId}`);
  85. }
  86. catch (error) {
  87. console.error('[Error]', error);
  88. }
  89. finally {
  90. await transport.close();
  91. console.log('[Client] Disconnected');
  92. }
  93. }
  94. main().catch(console.error);
  95. //# sourceMappingURL=ssePollingClient.js.map