mcp-use 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +98 -1
  2. package/dist/index.cjs +118 -689
  3. package/dist/index.d.ts +10 -2
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +118 -54
  6. package/dist/src/agents/mcp_agent.d.ts +1 -1
  7. package/dist/src/agents/mcp_agent.d.ts.map +1 -1
  8. package/dist/src/server/adapters/mcp-ui-adapter.d.ts +66 -0
  9. package/dist/src/server/adapters/mcp-ui-adapter.d.ts.map +1 -0
  10. package/dist/src/server/index.cjs +292 -14
  11. package/dist/src/server/index.d.ts +4 -2
  12. package/dist/src/server/index.d.ts.map +1 -1
  13. package/dist/src/server/index.js +913 -4
  14. package/dist/src/server/mcp-server.d.ts +91 -2
  15. package/dist/src/server/mcp-server.d.ts.map +1 -1
  16. package/dist/src/server/types/common.d.ts +27 -0
  17. package/dist/src/server/types/common.d.ts.map +1 -0
  18. package/dist/src/server/types/index.d.ts +8 -0
  19. package/dist/src/server/types/index.d.ts.map +1 -0
  20. package/dist/src/server/types/prompt.d.ts +14 -0
  21. package/dist/src/server/types/prompt.d.ts.map +1 -0
  22. package/dist/src/server/types/resource.d.ts +155 -0
  23. package/dist/src/server/types/resource.d.ts.map +1 -0
  24. package/dist/src/server/types/tool.d.ts +14 -0
  25. package/dist/src/server/types/tool.d.ts.map +1 -0
  26. package/dist/src/server/types.d.ts +3 -76
  27. package/dist/src/server/types.d.ts.map +1 -1
  28. package/dist/tests/helpers/widget-generators.d.ts +24 -0
  29. package/dist/tests/helpers/widget-generators.d.ts.map +1 -0
  30. package/dist/tests/mcp-ui-adapter.test.d.ts +8 -0
  31. package/dist/tests/mcp-ui-adapter.test.d.ts.map +1 -0
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +33 -36
  34. package/dist/chunk-MZPKOZE4.js +0 -644
@@ -31,7 +31,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/server/index.ts
32
32
  var server_exports = {};
33
33
  __export(server_exports, {
34
- createMCPServer: () => createMCPServer
34
+ buildWidgetUrl: () => buildWidgetUrl,
35
+ createExternalUrlResource: () => createExternalUrlResource,
36
+ createMCPServer: () => createMCPServer,
37
+ createRawHtmlResource: () => createRawHtmlResource,
38
+ createRemoteDomResource: () => createRemoteDomResource,
39
+ createUIResourceFromDefinition: () => createUIResourceFromDefinition
35
40
  });
36
41
  module.exports = __toCommonJS(server_exports);
37
42
 
@@ -72,6 +77,71 @@ function requestLogger(req, res, next) {
72
77
  }
73
78
  __name(requestLogger, "requestLogger");
74
79
 
80
+ // src/server/adapters/mcp-ui-adapter.ts
81
+ var import_server = require("@mcp-ui/server");
82
+ function buildWidgetUrl(widget, props, config) {
83
+ const url = new URL(
84
+ `/mcp-use/widgets/${widget}`,
85
+ `${config.baseUrl}:${config.port}`
86
+ );
87
+ if (props) {
88
+ Object.entries(props).forEach(([key, value]) => {
89
+ if (value !== void 0 && value !== null) {
90
+ const stringValue = typeof value === "object" ? JSON.stringify(value) : String(value);
91
+ url.searchParams.set(key, stringValue);
92
+ }
93
+ });
94
+ }
95
+ return url.toString();
96
+ }
97
+ __name(buildWidgetUrl, "buildWidgetUrl");
98
+ function createExternalUrlResource(uri, iframeUrl, encoding = "text") {
99
+ return (0, import_server.createUIResource)({
100
+ uri,
101
+ content: { type: "externalUrl", iframeUrl },
102
+ encoding
103
+ });
104
+ }
105
+ __name(createExternalUrlResource, "createExternalUrlResource");
106
+ function createRawHtmlResource(uri, htmlString, encoding = "text") {
107
+ return (0, import_server.createUIResource)({
108
+ uri,
109
+ content: { type: "rawHtml", htmlString },
110
+ encoding
111
+ });
112
+ }
113
+ __name(createRawHtmlResource, "createRawHtmlResource");
114
+ function createRemoteDomResource(uri, script, framework = "react", encoding = "text") {
115
+ return (0, import_server.createUIResource)({
116
+ uri,
117
+ content: { type: "remoteDom", script, framework },
118
+ encoding
119
+ });
120
+ }
121
+ __name(createRemoteDomResource, "createRemoteDomResource");
122
+ function createUIResourceFromDefinition(definition, params, config) {
123
+ const uri = `ui://widget/${definition.name}`;
124
+ const encoding = definition.encoding || "text";
125
+ switch (definition.type) {
126
+ case "externalUrl": {
127
+ const widgetUrl = buildWidgetUrl(definition.widget, params, config);
128
+ return createExternalUrlResource(uri, widgetUrl, encoding);
129
+ }
130
+ case "rawHtml": {
131
+ return createRawHtmlResource(uri, definition.htmlContent, encoding);
132
+ }
133
+ case "remoteDom": {
134
+ const framework = definition.framework || "react";
135
+ return createRemoteDomResource(uri, definition.script, framework, encoding);
136
+ }
137
+ default: {
138
+ const _exhaustive = definition;
139
+ throw new Error(`Unknown UI resource type: ${_exhaustive.type}`);
140
+ }
141
+ }
142
+ }
143
+ __name(createUIResourceFromDefinition, "createUIResourceFromDefinition");
144
+
75
145
  // src/server/mcp-server.ts
76
146
  var McpServer = class {
77
147
  static {
@@ -104,7 +174,7 @@ var McpServer = class {
104
174
  this.app.use((req, res, next) => {
105
175
  res.header("Access-Control-Allow-Origin", "*");
106
176
  res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
107
- res.header("Access-Control-Allow-Headers", "Content-Type");
177
+ res.header("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, mcp-protocol-version, mcp-session-id, X-Proxy-Token, X-Target-URL");
108
178
  next();
109
179
  });
110
180
  this.app.use(requestLogger);
@@ -335,12 +405,196 @@ var McpServer = class {
335
405
  );
336
406
  return this;
337
407
  }
408
+ /**
409
+ * Register a UI widget as both a tool and a resource
410
+ *
411
+ * Creates a unified interface for MCP-UI compatible widgets that can be accessed
412
+ * either as tools (with parameters) or as resources (static access). The tool
413
+ * allows dynamic parameter passing while the resource provides discoverable access.
414
+ *
415
+ * @param definition - Configuration for the UI widget
416
+ * @param definition.name - Unique identifier for the resource
417
+ * @param definition.widget - Widget name (matches directory in dist/resources/mcp-use/widgets)
418
+ * @param definition.title - Human-readable title for the widget
419
+ * @param definition.description - Description of the widget's functionality
420
+ * @param definition.props - Widget properties configuration with types and defaults
421
+ * @param definition.size - Preferred iframe size [width, height] (e.g., ['800px', '600px'])
422
+ * @param definition.annotations - Resource annotations for discovery
423
+ * @returns The server instance for method chaining
424
+ *
425
+ * @example
426
+ * ```typescript
427
+ * server.uiResource({
428
+ * name: 'kanban-board',
429
+ * widget: 'kanban-board',
430
+ * title: 'Kanban Board',
431
+ * description: 'Interactive task management board',
432
+ * props: {
433
+ * initialTasks: {
434
+ * type: 'array',
435
+ * description: 'Initial tasks to display',
436
+ * required: false
437
+ * },
438
+ * theme: {
439
+ * type: 'string',
440
+ * default: 'light'
441
+ * }
442
+ * },
443
+ * size: ['900px', '600px']
444
+ * })
445
+ * ```
446
+ */
447
+ uiResource(definition) {
448
+ const toolName = definition.type === "externalUrl" ? `ui_${definition.widget}` : `ui_${definition.name}`;
449
+ const displayName = definition.title || definition.name;
450
+ let resourceUri;
451
+ let mimeType;
452
+ switch (definition.type) {
453
+ case "externalUrl":
454
+ resourceUri = `ui://widget/${definition.widget}`;
455
+ mimeType = "text/uri-list";
456
+ break;
457
+ case "rawHtml":
458
+ resourceUri = `ui://widget/${definition.name}`;
459
+ mimeType = "text/html";
460
+ break;
461
+ case "remoteDom":
462
+ resourceUri = `ui://widget/${definition.name}`;
463
+ mimeType = "application/vnd.mcp-ui.remote-dom+javascript";
464
+ break;
465
+ default:
466
+ throw new Error(`Unsupported UI resource type. Must be one of: externalUrl, rawHtml, remoteDom`);
467
+ }
468
+ this.resource({
469
+ name: definition.name,
470
+ uri: resourceUri,
471
+ title: definition.title,
472
+ description: definition.description,
473
+ mimeType,
474
+ annotations: definition.annotations,
475
+ fn: /* @__PURE__ */ __name(async () => {
476
+ const params = definition.type === "externalUrl" ? this.applyDefaultProps(definition.props) : {};
477
+ const uiResource = this.createWidgetUIResource(definition, params);
478
+ return {
479
+ contents: [uiResource.resource]
480
+ };
481
+ }, "fn")
482
+ });
483
+ this.tool({
484
+ name: toolName,
485
+ description: definition.description || `Display ${displayName}`,
486
+ inputs: this.convertPropsToInputs(definition.props),
487
+ fn: /* @__PURE__ */ __name(async (params) => {
488
+ const uiResource = this.createWidgetUIResource(definition, params);
489
+ return {
490
+ content: [
491
+ {
492
+ type: "text",
493
+ text: `Displaying ${displayName}`,
494
+ description: `Show MCP-UI widget for ${displayName}`
495
+ },
496
+ uiResource
497
+ ]
498
+ };
499
+ }, "fn")
500
+ });
501
+ return this;
502
+ }
503
+ /**
504
+ * Create a UIResource object for a widget with the given parameters
505
+ *
506
+ * This method is shared between tool and resource handlers to avoid duplication.
507
+ * It creates a consistent UIResource structure that can be rendered by MCP-UI
508
+ * compatible clients.
509
+ *
510
+ * @private
511
+ * @param definition - UIResource definition
512
+ * @param params - Parameters to pass to the widget via URL
513
+ * @returns UIResource object compatible with MCP-UI
514
+ */
515
+ createWidgetUIResource(definition, params) {
516
+ const urlConfig = {
517
+ baseUrl: "http://localhost",
518
+ port: this.serverPort || 3001
519
+ };
520
+ return createUIResourceFromDefinition(definition, params, urlConfig);
521
+ }
522
+ /**
523
+ * Build a complete URL for a widget including query parameters
524
+ *
525
+ * Constructs the full URL to access a widget's iframe, encoding any provided
526
+ * parameters as query string parameters. Complex objects are JSON-stringified
527
+ * for transmission.
528
+ *
529
+ * @private
530
+ * @param widget - Widget name/identifier
531
+ * @param params - Parameters to encode in the URL
532
+ * @returns Complete URL with encoded parameters
533
+ */
534
+ buildWidgetUrl(widget, params) {
535
+ const baseUrl = `http://localhost:${this.serverPort}/mcp-use/widgets/${widget}`;
536
+ if (Object.keys(params).length === 0) {
537
+ return baseUrl;
538
+ }
539
+ const queryParams = new URLSearchParams();
540
+ for (const [key, value] of Object.entries(params)) {
541
+ if (value !== void 0 && value !== null) {
542
+ if (typeof value === "object") {
543
+ queryParams.append(key, JSON.stringify(value));
544
+ } else {
545
+ queryParams.append(key, String(value));
546
+ }
547
+ }
548
+ }
549
+ return `${baseUrl}?${queryParams.toString()}`;
550
+ }
551
+ /**
552
+ * Convert widget props definition to tool input schema
553
+ *
554
+ * Transforms the widget props configuration into the format expected by
555
+ * the tool registration system, mapping types and handling defaults.
556
+ *
557
+ * @private
558
+ * @param props - Widget props configuration
559
+ * @returns Array of InputDefinition objects for tool registration
560
+ */
561
+ convertPropsToInputs(props) {
562
+ if (!props) return [];
563
+ return Object.entries(props).map(([name, prop]) => ({
564
+ name,
565
+ type: prop.type,
566
+ description: prop.description,
567
+ required: prop.required,
568
+ default: prop.default
569
+ }));
570
+ }
571
+ /**
572
+ * Apply default values to widget props
573
+ *
574
+ * Extracts default values from the props configuration to use when
575
+ * the resource is accessed without parameters.
576
+ *
577
+ * @private
578
+ * @param props - Widget props configuration
579
+ * @returns Object with default values for each prop
580
+ */
581
+ applyDefaultProps(props) {
582
+ if (!props) return {};
583
+ const defaults = {};
584
+ for (const [key, prop] of Object.entries(props)) {
585
+ if (prop.default !== void 0) {
586
+ defaults[key] = prop.default;
587
+ }
588
+ }
589
+ return defaults;
590
+ }
338
591
  /**
339
592
  * Mount MCP server endpoints at /mcp
340
593
  *
341
594
  * Sets up the HTTP transport layer for the MCP server, creating endpoints for
342
595
  * Server-Sent Events (SSE) streaming, POST message handling, and DELETE session cleanup.
343
- * Uses stateless mode for session management, making it suitable for stateless deployments.
596
+ * Each request gets its own transport instance to prevent state conflicts between
597
+ * concurrent client connections.
344
598
  *
345
599
  * This method is called automatically when the server starts listening and ensures
346
600
  * that MCP clients can communicate with the server over HTTP.
@@ -357,20 +611,39 @@ var McpServer = class {
357
611
  async mountMcp() {
358
612
  if (this.mcpMounted) return;
359
613
  const { StreamableHTTPServerTransport } = await import("@modelcontextprotocol/sdk/server/streamableHttp.js");
360
- const httpTransport = new StreamableHTTPServerTransport({
361
- sessionIdGenerator: void 0
362
- // Stateless mode
363
- });
364
- await this.server.connect(httpTransport);
365
614
  const endpoint = "/mcp";
366
- this.app.get(endpoint, async (req, res) => {
367
- await httpTransport.handleRequest(req, res);
368
- });
369
615
  this.app.post(endpoint, import_express.default.json(), async (req, res) => {
370
- await httpTransport.handleRequest(req, res, req.body);
616
+ const transport = new StreamableHTTPServerTransport({
617
+ sessionIdGenerator: void 0,
618
+ enableJsonResponse: true
619
+ });
620
+ res.on("close", () => {
621
+ transport.close();
622
+ });
623
+ await this.server.connect(transport);
624
+ await transport.handleRequest(req, res, req.body);
625
+ });
626
+ this.app.get(endpoint, async (req, res) => {
627
+ const transport = new StreamableHTTPServerTransport({
628
+ sessionIdGenerator: void 0,
629
+ enableJsonResponse: true
630
+ });
631
+ res.on("close", () => {
632
+ transport.close();
633
+ });
634
+ await this.server.connect(transport);
635
+ await transport.handleRequest(req, res);
371
636
  });
372
637
  this.app.delete(endpoint, async (req, res) => {
373
- await httpTransport.handleRequest(req, res);
638
+ const transport = new StreamableHTTPServerTransport({
639
+ sessionIdGenerator: void 0,
640
+ enableJsonResponse: true
641
+ });
642
+ res.on("close", () => {
643
+ transport.close();
644
+ });
645
+ await this.server.connect(transport);
646
+ await transport.handleRequest(req, res);
374
647
  });
375
648
  this.mcpMounted = true;
376
649
  console.log(`[MCP] Server mounted at ${endpoint}`);
@@ -673,5 +946,10 @@ function createMCPServer(name, config = {}) {
673
946
  __name(createMCPServer, "createMCPServer");
674
947
  // Annotate the CommonJS export names for ESM import in node:
675
948
  0 && (module.exports = {
676
- createMCPServer
949
+ buildWidgetUrl,
950
+ createExternalUrlResource,
951
+ createMCPServer,
952
+ createRawHtmlResource,
953
+ createRemoteDomResource,
954
+ createUIResourceFromDefinition
677
955
  });
@@ -1,3 +1,5 @@
1
- export { createMCPServer } from './mcp-server.js';
2
- export type { InputDefinition, PromptDefinition, PromptHandler, ResourceDefinition, ResourceHandler, ServerConfig, ToolDefinition, ToolHandler, } from './types.js';
1
+ export { createMCPServer, type McpServerInstance } from './mcp-server.js';
2
+ export * from './types/index.js';
3
+ export { buildWidgetUrl, createExternalUrlResource, createRawHtmlResource, createRemoteDomResource, createUIResourceFromDefinition, type UrlConfig } from './adapters/mcp-ui-adapter.js';
4
+ export type { InputDefinition, PromptDefinition, PromptHandler, ResourceDefinition, ResourceHandler, ServerConfig, ToolDefinition, ToolHandler, UIResourceDefinition, ExternalUrlUIResource, RawHtmlUIResource, RemoteDomUIResource, WidgetProps, WidgetConfig, WidgetManifest, DiscoverWidgetsOptions, } from './types/index.js';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAChB,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAA;AAExB,cAAc,kBAAkB,CAAA;AAGhC,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EACvB,8BAA8B,EAC9B,KAAK,SAAS,EACf,MAAM,8BAA8B,CAAA;AAErC,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,cAAc,EACd,WAAW,EAEX,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,sBAAsB,GACvB,MAAM,kBAAkB,CAAA"}