simpleStatelessStreamableHttp.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. "use strict";
  2. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
  3. if (k2 === undefined) k2 = k;
  4. var desc = Object.getOwnPropertyDescriptor(m, k);
  5. if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
  6. desc = { enumerable: true, get: function() { return m[k]; } };
  7. }
  8. Object.defineProperty(o, k2, desc);
  9. }) : (function(o, m, k, k2) {
  10. if (k2 === undefined) k2 = k;
  11. o[k2] = m[k];
  12. }));
  13. var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
  14. Object.defineProperty(o, "default", { enumerable: true, value: v });
  15. }) : function(o, v) {
  16. o["default"] = v;
  17. });
  18. var __importStar = (this && this.__importStar) || function (mod) {
  19. if (mod && mod.__esModule) return mod;
  20. var result = {};
  21. if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
  22. __setModuleDefault(result, mod);
  23. return result;
  24. };
  25. Object.defineProperty(exports, "__esModule", { value: true });
  26. const mcp_js_1 = require("../../server/mcp.js");
  27. const streamableHttp_js_1 = require("../../server/streamableHttp.js");
  28. const z = __importStar(require("zod/v4"));
  29. const express_js_1 = require("../../server/express.js");
  30. const getServer = () => {
  31. // Create an MCP server with implementation details
  32. const server = new mcp_js_1.McpServer({
  33. name: 'stateless-streamable-http-server',
  34. version: '1.0.0'
  35. }, { capabilities: { logging: {} } });
  36. // Register a simple prompt
  37. server.registerPrompt('greeting-template', {
  38. description: 'A simple greeting prompt template',
  39. argsSchema: {
  40. name: z.string().describe('Name to include in greeting')
  41. }
  42. }, async ({ name }) => {
  43. return {
  44. messages: [
  45. {
  46. role: 'user',
  47. content: {
  48. type: 'text',
  49. text: `Please greet ${name} in a friendly manner.`
  50. }
  51. }
  52. ]
  53. };
  54. });
  55. // Register a tool specifically for testing resumability
  56. server.registerTool('start-notification-stream', {
  57. description: 'Starts sending periodic notifications for testing resumability',
  58. inputSchema: {
  59. interval: z.number().describe('Interval in milliseconds between notifications').default(100),
  60. count: z.number().describe('Number of notifications to send (0 for 100)').default(10)
  61. }
  62. }, async ({ interval, count }, extra) => {
  63. const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
  64. let counter = 0;
  65. while (count === 0 || counter < count) {
  66. counter++;
  67. try {
  68. await server.sendLoggingMessage({
  69. level: 'info',
  70. data: `Periodic notification #${counter} at ${new Date().toISOString()}`
  71. }, extra.sessionId);
  72. }
  73. catch (error) {
  74. console.error('Error sending notification:', error);
  75. }
  76. // Wait for the specified interval
  77. await sleep(interval);
  78. }
  79. return {
  80. content: [
  81. {
  82. type: 'text',
  83. text: `Started sending periodic notifications every ${interval}ms`
  84. }
  85. ]
  86. };
  87. });
  88. // Create a simple resource at a fixed URI
  89. server.registerResource('greeting-resource', 'https://example.com/greetings/default', { mimeType: 'text/plain' }, async () => {
  90. return {
  91. contents: [
  92. {
  93. uri: 'https://example.com/greetings/default',
  94. text: 'Hello, world!'
  95. }
  96. ]
  97. };
  98. });
  99. return server;
  100. };
  101. const app = (0, express_js_1.createMcpExpressApp)();
  102. app.post('/mcp', async (req, res) => {
  103. const server = getServer();
  104. try {
  105. const transport = new streamableHttp_js_1.StreamableHTTPServerTransport({
  106. sessionIdGenerator: undefined
  107. });
  108. await server.connect(transport);
  109. await transport.handleRequest(req, res, req.body);
  110. res.on('close', () => {
  111. console.log('Request closed');
  112. transport.close();
  113. server.close();
  114. });
  115. }
  116. catch (error) {
  117. console.error('Error handling MCP request:', error);
  118. if (!res.headersSent) {
  119. res.status(500).json({
  120. jsonrpc: '2.0',
  121. error: {
  122. code: -32603,
  123. message: 'Internal server error'
  124. },
  125. id: null
  126. });
  127. }
  128. }
  129. });
  130. app.get('/mcp', async (req, res) => {
  131. console.log('Received GET MCP request');
  132. res.writeHead(405).end(JSON.stringify({
  133. jsonrpc: '2.0',
  134. error: {
  135. code: -32000,
  136. message: 'Method not allowed.'
  137. },
  138. id: null
  139. }));
  140. });
  141. app.delete('/mcp', async (req, res) => {
  142. console.log('Received DELETE MCP request');
  143. res.writeHead(405).end(JSON.stringify({
  144. jsonrpc: '2.0',
  145. error: {
  146. code: -32000,
  147. message: 'Method not allowed.'
  148. },
  149. id: null
  150. }));
  151. });
  152. // Start the server
  153. const PORT = 3000;
  154. app.listen(PORT, error => {
  155. if (error) {
  156. console.error('Failed to start server:', error);
  157. process.exit(1);
  158. }
  159. console.log(`MCP Stateless Streamable HTTP Server listening on port ${PORT}`);
  160. });
  161. // Handle server shutdown
  162. process.on('SIGINT', async () => {
  163. console.log('Shutting down server...');
  164. process.exit(0);
  165. });
  166. //# sourceMappingURL=simpleStatelessStreamableHttp.js.map