mcp-use 1.2.1 → 1.2.2-canary.1
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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/chunk-3RJENWH4.js +248 -0
- package/dist/{chunk-MGUO7HXB.js → chunk-7UX634PO.js} +307 -1066
- package/dist/chunk-KLIBVJ3Z.js +759 -0
- package/dist/chunk-MZLETWQQ.js +250 -0
- package/dist/chunk-RSGKBEHH.js +1411 -0
- package/dist/index.cjs +880 -541
- package/dist/index.d.ts +24 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +92 -33
- package/dist/{langfuse-6AJGHMAV.js → langfuse-LCJ6VJEP.js} +2 -1
- package/dist/src/adapters/base.d.ts +2 -2
- package/dist/src/adapters/base.d.ts.map +1 -1
- package/dist/src/adapters/index.d.ts +2 -2
- package/dist/src/adapters/index.d.ts.map +1 -1
- package/dist/src/adapters/langchain_adapter.d.ts +4 -4
- package/dist/src/adapters/langchain_adapter.d.ts.map +1 -1
- package/dist/src/agents/base.d.ts +1 -1
- package/dist/src/agents/base.d.ts.map +1 -1
- package/dist/src/agents/index.d.ts +3 -3
- package/dist/src/agents/index.d.ts.map +1 -1
- package/dist/src/agents/mcp_agent.d.ts +12 -12
- package/dist/src/agents/mcp_agent.d.ts.map +1 -1
- package/dist/src/agents/prompts/system_prompt_builder.d.ts +2 -2
- package/dist/src/agents/prompts/system_prompt_builder.d.ts.map +1 -1
- package/dist/src/agents/prompts/templates.d.ts.map +1 -1
- package/dist/src/agents/remote.d.ts +2 -2
- package/dist/src/agents/remote.d.ts.map +1 -1
- package/dist/src/agents/types.d.ts +1 -1
- package/dist/src/agents/types.d.ts.map +1 -1
- package/dist/src/agents/utils/ai_sdk.d.ts +1 -1
- package/dist/src/agents/utils/ai_sdk.d.ts.map +1 -1
- package/dist/src/agents/utils/index.d.ts +1 -1
- package/dist/src/agents/utils/index.d.ts.map +1 -1
- package/dist/src/auth/browser-provider.d.ts +2 -2
- package/dist/src/auth/browser-provider.d.ts.map +1 -1
- package/dist/src/auth/callback.d.ts.map +1 -1
- package/dist/src/auth/index.d.ts +3 -3
- package/dist/src/auth/index.d.ts.map +1 -1
- package/dist/src/auth/types.d.ts +1 -1
- package/dist/src/auth/types.d.ts.map +1 -1
- package/dist/src/browser.cjs +573 -219
- package/dist/src/browser.d.ts +17 -17
- package/dist/src/browser.d.ts.map +1 -1
- package/dist/src/browser.js +17 -46
- package/dist/src/client/base.d.ts +2 -2
- package/dist/src/client/base.d.ts.map +1 -1
- package/dist/src/client/browser.d.ts +2 -2
- package/dist/src/client/browser.d.ts.map +1 -1
- package/dist/src/client.d.ts +2 -2
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/config.d.ts +1 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/connectors/base.d.ts +51 -9
- package/dist/src/connectors/base.d.ts.map +1 -1
- package/dist/src/connectors/http.d.ts +3 -3
- package/dist/src/connectors/http.d.ts.map +1 -1
- package/dist/src/connectors/index.d.ts +4 -4
- package/dist/src/connectors/index.d.ts.map +1 -1
- package/dist/src/connectors/stdio.d.ts +3 -3
- package/dist/src/connectors/stdio.d.ts.map +1 -1
- package/dist/src/connectors/websocket.d.ts +4 -7
- package/dist/src/connectors/websocket.d.ts.map +1 -1
- package/dist/src/logging.d.ts +4 -4
- package/dist/src/logging.d.ts.map +1 -1
- package/dist/src/managers/index.d.ts +2 -2
- package/dist/src/managers/index.d.ts.map +1 -1
- package/dist/src/managers/server_manager.d.ts +4 -4
- package/dist/src/managers/server_manager.d.ts.map +1 -1
- package/dist/src/managers/tools/acquire_active_mcp_server.d.ts +3 -3
- package/dist/src/managers/tools/acquire_active_mcp_server.d.ts.map +1 -1
- package/dist/src/managers/tools/add_server_from_config.d.ts +3 -3
- package/dist/src/managers/tools/add_server_from_config.d.ts.map +1 -1
- package/dist/src/managers/tools/base.d.ts +6 -6
- package/dist/src/managers/tools/base.d.ts.map +1 -1
- package/dist/src/managers/tools/connect_mcp_server.d.ts +4 -4
- package/dist/src/managers/tools/connect_mcp_server.d.ts.map +1 -1
- package/dist/src/managers/tools/index.d.ts +5 -5
- package/dist/src/managers/tools/index.d.ts.map +1 -1
- package/dist/src/managers/tools/list_mcp_servers.d.ts +3 -3
- package/dist/src/managers/tools/list_mcp_servers.d.ts.map +1 -1
- package/dist/src/managers/tools/release_mcp_server_connection.d.ts +3 -3
- package/dist/src/managers/tools/release_mcp_server_connection.d.ts.map +1 -1
- package/dist/src/managers/types.d.ts +3 -3
- package/dist/src/managers/types.d.ts.map +1 -1
- package/dist/src/oauth-helper.d.ts.map +1 -1
- package/dist/src/observability/index.d.ts +3 -3
- package/dist/src/observability/index.d.ts.map +1 -1
- package/dist/src/observability/langfuse.d.ts +1 -1
- package/dist/src/observability/langfuse.d.ts.map +1 -1
- package/dist/src/observability/manager.d.ts +1 -1
- package/dist/src/observability/manager.d.ts.map +1 -1
- package/dist/src/observability/types.d.ts +1 -1
- package/dist/src/observability/types.d.ts.map +1 -1
- package/dist/src/react/index.cjs +1571 -321
- package/dist/src/react/index.d.ts +6 -6
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/react/index.js +3 -2
- package/dist/src/react/types.d.ts +27 -5
- package/dist/src/react/types.d.ts.map +1 -1
- package/dist/src/react/useMcp.d.ts +32 -1
- package/dist/src/react/useMcp.d.ts.map +1 -1
- package/dist/src/react/useWidget.d.ts +5 -2
- package/dist/src/react/useWidget.d.ts.map +1 -1
- package/dist/src/react/widget-types.d.ts +3 -3
- package/dist/src/react/widget-types.d.ts.map +1 -1
- package/dist/src/server/adapters/mcp-ui-adapter.d.ts +3 -3
- package/dist/src/server/adapters/mcp-ui-adapter.d.ts.map +1 -1
- package/dist/src/server/index.cjs +170 -50
- package/dist/src/server/index.d.ts +4 -4
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +174 -51
- package/dist/src/server/logging.d.ts +1 -1
- package/dist/src/server/logging.d.ts.map +1 -1
- package/dist/src/server/mcp-server.d.ts +29 -29
- package/dist/src/server/mcp-server.d.ts.map +1 -1
- package/dist/src/server/types/common.d.ts +2 -2
- package/dist/src/server/types/common.d.ts.map +1 -1
- package/dist/src/server/types/index.d.ts +4 -4
- package/dist/src/server/types/index.d.ts.map +1 -1
- package/dist/src/server/types/prompt.d.ts +2 -2
- package/dist/src/server/types/prompt.d.ts.map +1 -1
- package/dist/src/server/types/resource.d.ts +24 -24
- package/dist/src/server/types/resource.d.ts.map +1 -1
- package/dist/src/server/types/tool.d.ts +3 -3
- package/dist/src/server/types/tool.d.ts.map +1 -1
- package/dist/src/server/types/widget.d.ts +1 -1
- package/dist/src/server/types.d.ts +1 -1
- package/dist/src/server/types.d.ts.map +1 -1
- package/dist/src/session.d.ts +1 -1
- package/dist/src/session.d.ts.map +1 -1
- package/dist/src/task_managers/base.d.ts.map +1 -1
- package/dist/src/task_managers/index.d.ts +5 -5
- package/dist/src/task_managers/index.d.ts.map +1 -1
- package/dist/src/task_managers/sse.d.ts +3 -3
- package/dist/src/task_managers/sse.d.ts.map +1 -1
- package/dist/src/task_managers/stdio.d.ts +4 -4
- package/dist/src/task_managers/stdio.d.ts.map +1 -1
- package/dist/src/task_managers/streamable_http.d.ts +3 -3
- package/dist/src/task_managers/streamable_http.d.ts.map +1 -1
- package/dist/src/task_managers/websocket.d.ts +2 -2
- package/dist/src/task_managers/websocket.d.ts.map +1 -1
- package/dist/src/telemetry/events.d.ts.map +1 -1
- package/dist/src/telemetry/index.d.ts +4 -4
- package/dist/src/telemetry/index.d.ts.map +1 -1
- package/dist/src/telemetry/telemetry.d.ts +1 -1
- package/dist/src/telemetry/telemetry.d.ts.map +1 -1
- package/dist/src/telemetry/utils.d.ts +1 -1
- package/dist/src/telemetry/utils.d.ts.map +1 -1
- package/dist/tsup.config.d.ts.map +1 -1
- package/dist/vitest.config.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-62GFHYCL.js +0 -300
- package/dist/chunk-JV7HAYUT.js +0 -860
- package/dist/chunk-ZUEQQ6YK.js +0 -444
package/dist/src/server/index.js
CHANGED
|
@@ -3,7 +3,10 @@ import {
|
|
|
3
3
|
} from "../../chunk-SHUYVCID.js";
|
|
4
4
|
|
|
5
5
|
// src/server/mcp-server.ts
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
McpServer as OfficialMcpServer,
|
|
8
|
+
ResourceTemplate
|
|
9
|
+
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
10
|
import { z } from "zod";
|
|
8
11
|
import express from "express";
|
|
9
12
|
import cors from "cors";
|
|
@@ -183,11 +186,21 @@ var McpServer = class {
|
|
|
183
186
|
});
|
|
184
187
|
this.app = express();
|
|
185
188
|
this.app.use(express.json());
|
|
186
|
-
this.app.use(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
this.app.use(
|
|
190
|
+
cors({
|
|
191
|
+
origin: "*",
|
|
192
|
+
methods: ["GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
193
|
+
allowedHeaders: [
|
|
194
|
+
"Content-Type",
|
|
195
|
+
"Accept",
|
|
196
|
+
"Authorization",
|
|
197
|
+
"mcp-protocol-version",
|
|
198
|
+
"mcp-session-id",
|
|
199
|
+
"X-Proxy-Token",
|
|
200
|
+
"X-Target-URL"
|
|
201
|
+
]
|
|
202
|
+
})
|
|
203
|
+
);
|
|
191
204
|
this.app.use(requestLogger);
|
|
192
205
|
return new Proxy(this, {
|
|
193
206
|
get(target, prop) {
|
|
@@ -460,7 +473,7 @@ var McpServer = class {
|
|
|
460
473
|
* ```typescript
|
|
461
474
|
* // Simple usage - auto-loads from generated schema
|
|
462
475
|
* server.uiResource('display-weather')
|
|
463
|
-
*
|
|
476
|
+
*
|
|
464
477
|
* // Legacy MCP-UI widget
|
|
465
478
|
* server.uiResource({
|
|
466
479
|
* type: 'externalUrl',
|
|
@@ -521,7 +534,9 @@ var McpServer = class {
|
|
|
521
534
|
mimeType = "text/html+skybridge";
|
|
522
535
|
break;
|
|
523
536
|
default:
|
|
524
|
-
throw new Error(
|
|
537
|
+
throw new Error(
|
|
538
|
+
`Unsupported UI resource type. Must be one of: externalUrl, rawHtml, remoteDom, appsSdk`
|
|
539
|
+
);
|
|
525
540
|
}
|
|
526
541
|
this.resource({
|
|
527
542
|
name: definition.name,
|
|
@@ -586,7 +601,10 @@ var McpServer = class {
|
|
|
586
601
|
if (definition.type === "appsSdk") {
|
|
587
602
|
const randomId = Math.random().toString(36).substring(2, 15);
|
|
588
603
|
const uniqueUri = `ui://widget/${definition.name}-${randomId}.html`;
|
|
589
|
-
const uniqueToolMetadata = {
|
|
604
|
+
const uniqueToolMetadata = {
|
|
605
|
+
...toolMetadata,
|
|
606
|
+
"openai/outputTemplate": uniqueUri
|
|
607
|
+
};
|
|
590
608
|
return {
|
|
591
609
|
_meta: uniqueToolMetadata,
|
|
592
610
|
content: [
|
|
@@ -714,7 +732,7 @@ var McpServer = class {
|
|
|
714
732
|
}
|
|
715
733
|
/**
|
|
716
734
|
* Check if server is running in production mode
|
|
717
|
-
*
|
|
735
|
+
*
|
|
718
736
|
* @private
|
|
719
737
|
* @returns true if in production mode, false otherwise
|
|
720
738
|
*/
|
|
@@ -723,13 +741,17 @@ var McpServer = class {
|
|
|
723
741
|
}
|
|
724
742
|
/**
|
|
725
743
|
* Read build manifest file
|
|
726
|
-
*
|
|
744
|
+
*
|
|
727
745
|
* @private
|
|
728
746
|
* @returns Build manifest or null if not found
|
|
729
747
|
*/
|
|
730
748
|
readBuildManifest() {
|
|
731
749
|
try {
|
|
732
|
-
const manifestPath = join(
|
|
750
|
+
const manifestPath = join(
|
|
751
|
+
process.cwd(),
|
|
752
|
+
"dist",
|
|
753
|
+
".mcp-use-manifest.json"
|
|
754
|
+
);
|
|
733
755
|
const content = readFileSync(manifestPath, "utf8");
|
|
734
756
|
return JSON.parse(content);
|
|
735
757
|
} catch {
|
|
@@ -775,7 +797,9 @@ var McpServer = class {
|
|
|
775
797
|
try {
|
|
776
798
|
await fs.access(srcDir);
|
|
777
799
|
} catch (error) {
|
|
778
|
-
console.log(
|
|
800
|
+
console.log(
|
|
801
|
+
`[WIDGETS] No ${resourcesDir}/ directory found - skipping widget serving`
|
|
802
|
+
);
|
|
779
803
|
return;
|
|
780
804
|
}
|
|
781
805
|
let entries = [];
|
|
@@ -810,7 +834,10 @@ var McpServer = class {
|
|
|
810
834
|
await fs.mkdir(widgetTempDir, { recursive: true });
|
|
811
835
|
const resourcesPath = join(process.cwd(), resourcesDir);
|
|
812
836
|
const { relative } = await import("path");
|
|
813
|
-
const relativeResourcesPath = relative(
|
|
837
|
+
const relativeResourcesPath = relative(
|
|
838
|
+
widgetTempDir,
|
|
839
|
+
resourcesPath
|
|
840
|
+
).replace(/\\/g, "/");
|
|
814
841
|
const cssContent = `@import "tailwindcss";
|
|
815
842
|
|
|
816
843
|
/* Configure Tailwind to scan the resources directory */
|
|
@@ -840,11 +867,21 @@ if (container && Component) {
|
|
|
840
867
|
<script type="module" src="${baseRoute}/${widget.name}/entry.tsx"></script>
|
|
841
868
|
</body>
|
|
842
869
|
</html>`;
|
|
843
|
-
await fs.writeFile(
|
|
844
|
-
|
|
870
|
+
await fs.writeFile(
|
|
871
|
+
join(widgetTempDir, "entry.tsx"),
|
|
872
|
+
entryContent,
|
|
873
|
+
"utf8"
|
|
874
|
+
);
|
|
875
|
+
await fs.writeFile(
|
|
876
|
+
join(widgetTempDir, "index.html"),
|
|
877
|
+
htmlContent,
|
|
878
|
+
"utf8"
|
|
879
|
+
);
|
|
845
880
|
}
|
|
846
881
|
const serverOrigin = this.serverBaseUrl || `http://${this.serverHost}:${this.serverPort}`;
|
|
847
|
-
console.log(
|
|
882
|
+
console.log(
|
|
883
|
+
`[WIDGETS] Serving ${entries.length} widget(s) with shared Vite dev server and HMR`
|
|
884
|
+
);
|
|
848
885
|
const viteServer = await createServer({
|
|
849
886
|
root: tempDir,
|
|
850
887
|
base: baseRoute + "/",
|
|
@@ -876,7 +913,9 @@ if (container && Component) {
|
|
|
876
913
|
});
|
|
877
914
|
this.app.use(baseRoute, viteServer.middlewares);
|
|
878
915
|
widgets.forEach((widget) => {
|
|
879
|
-
console.log(
|
|
916
|
+
console.log(
|
|
917
|
+
`[WIDGET] ${widget.name} mounted at ${baseRoute}/${widget.name}`
|
|
918
|
+
);
|
|
880
919
|
});
|
|
881
920
|
for (const widget of widgets) {
|
|
882
921
|
const type = "appsSdk";
|
|
@@ -892,12 +931,18 @@ if (container && Component) {
|
|
|
892
931
|
try {
|
|
893
932
|
props = metadata.inputs.shape || {};
|
|
894
933
|
} catch (error) {
|
|
895
|
-
console.warn(
|
|
934
|
+
console.warn(
|
|
935
|
+
`[WIDGET] Failed to extract props schema for ${widget.name}:`,
|
|
936
|
+
error
|
|
937
|
+
);
|
|
896
938
|
}
|
|
897
939
|
}
|
|
898
940
|
}
|
|
899
941
|
} catch (error) {
|
|
900
|
-
console.warn(
|
|
942
|
+
console.warn(
|
|
943
|
+
`[WIDGET] Failed to load metadata for ${widget.name}:`,
|
|
944
|
+
error
|
|
945
|
+
);
|
|
901
946
|
}
|
|
902
947
|
console.log("[WIDGET dev] Metadata:", metadata);
|
|
903
948
|
let html = "";
|
|
@@ -910,22 +955,40 @@ if (container && Component) {
|
|
|
910
955
|
if (baseTagRegex.test(htmlWithoutComments)) {
|
|
911
956
|
const actualBaseTagMatch = html.match(/<base\s+[^>]*\/?>/i);
|
|
912
957
|
if (actualBaseTagMatch) {
|
|
913
|
-
html = html.replace(
|
|
958
|
+
html = html.replace(
|
|
959
|
+
actualBaseTagMatch[0],
|
|
960
|
+
`<base href="${mcpUrl}" />`
|
|
961
|
+
);
|
|
914
962
|
}
|
|
915
963
|
} else {
|
|
916
964
|
const headTagRegex = /<head[^>]*>/i;
|
|
917
965
|
if (headTagRegex.test(html)) {
|
|
918
|
-
html = html.replace(
|
|
919
|
-
|
|
966
|
+
html = html.replace(
|
|
967
|
+
headTagRegex,
|
|
968
|
+
(match) => `${match}
|
|
969
|
+
<base href="${mcpUrl}" />`
|
|
970
|
+
);
|
|
920
971
|
}
|
|
921
972
|
}
|
|
922
973
|
}
|
|
923
|
-
html = html.replace(
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
974
|
+
html = html.replace(
|
|
975
|
+
/src="\/mcp-use\/widgets\/([^"]+)"/g,
|
|
976
|
+
`src="${this.serverBaseUrl}/mcp-use/widgets/$1"`
|
|
977
|
+
);
|
|
978
|
+
html = html.replace(
|
|
979
|
+
/href="\/mcp-use\/widgets\/([^"]+)"/g,
|
|
980
|
+
`href="${this.serverBaseUrl}/mcp-use/widgets/$1"`
|
|
981
|
+
);
|
|
982
|
+
html = html.replace(
|
|
983
|
+
/<head[^>]*>/i,
|
|
984
|
+
`<head>
|
|
985
|
+
<script>window.__getFile = (filename) => { return "${this.serverBaseUrl}/mcp-use/widgets/${widget.name}/"+filename }</script>`
|
|
986
|
+
);
|
|
927
987
|
} catch (error) {
|
|
928
|
-
console.error(
|
|
988
|
+
console.error(
|
|
989
|
+
`Failed to read html template for widget ${widget.name}`,
|
|
990
|
+
error
|
|
991
|
+
);
|
|
929
992
|
}
|
|
930
993
|
this.uiResource({
|
|
931
994
|
name: widget.name,
|
|
@@ -987,7 +1050,9 @@ if (container && Component) {
|
|
|
987
1050
|
const baseRoute = options?.baseRoute || "/mcp-use/widgets";
|
|
988
1051
|
const widgetsDir = join(process.cwd(), "dist", "resources", "widgets");
|
|
989
1052
|
if (!existsSync(widgetsDir)) {
|
|
990
|
-
console.log(
|
|
1053
|
+
console.log(
|
|
1054
|
+
"[WIDGETS] No dist/resources/widgets/ directory found - skipping widget serving"
|
|
1055
|
+
);
|
|
991
1056
|
return;
|
|
992
1057
|
}
|
|
993
1058
|
this.setupWidgetRoutes();
|
|
@@ -997,10 +1062,14 @@ if (container && Component) {
|
|
|
997
1062
|
return existsSync(indexPath);
|
|
998
1063
|
});
|
|
999
1064
|
if (widgets.length === 0) {
|
|
1000
|
-
console.log(
|
|
1065
|
+
console.log(
|
|
1066
|
+
"[WIDGETS] No built widgets found in dist/resources/widgets/"
|
|
1067
|
+
);
|
|
1001
1068
|
return;
|
|
1002
1069
|
}
|
|
1003
|
-
console.log(
|
|
1070
|
+
console.log(
|
|
1071
|
+
`[WIDGETS] Serving ${widgets.length} pre-built widget(s) from dist/resources/widgets/`
|
|
1072
|
+
);
|
|
1004
1073
|
for (const widgetName of widgets) {
|
|
1005
1074
|
const widgetPath = join(widgetsDir, widgetName);
|
|
1006
1075
|
const indexPath = join(widgetPath, "index.html");
|
|
@@ -1015,22 +1084,40 @@ if (container && Component) {
|
|
|
1015
1084
|
if (baseTagRegex.test(htmlWithoutComments)) {
|
|
1016
1085
|
const actualBaseTagMatch = html.match(/<base\s+[^>]*\/?>/i);
|
|
1017
1086
|
if (actualBaseTagMatch) {
|
|
1018
|
-
html = html.replace(
|
|
1087
|
+
html = html.replace(
|
|
1088
|
+
actualBaseTagMatch[0],
|
|
1089
|
+
`<base href="${mcpUrl}" />`
|
|
1090
|
+
);
|
|
1019
1091
|
}
|
|
1020
1092
|
} else {
|
|
1021
1093
|
const headTagRegex = /<head[^>]*>/i;
|
|
1022
1094
|
if (headTagRegex.test(html)) {
|
|
1023
|
-
html = html.replace(
|
|
1024
|
-
|
|
1095
|
+
html = html.replace(
|
|
1096
|
+
headTagRegex,
|
|
1097
|
+
(match) => `${match}
|
|
1098
|
+
<base href="${mcpUrl}" />`
|
|
1099
|
+
);
|
|
1025
1100
|
}
|
|
1026
1101
|
}
|
|
1027
|
-
html = html.replace(
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1102
|
+
html = html.replace(
|
|
1103
|
+
/src="\/mcp-use\/widgets\/([^"]+)"/g,
|
|
1104
|
+
`src="${this.serverBaseUrl}/mcp-use/widgets/$1"`
|
|
1105
|
+
);
|
|
1106
|
+
html = html.replace(
|
|
1107
|
+
/href="\/mcp-use\/widgets\/([^"]+)"/g,
|
|
1108
|
+
`href="${this.serverBaseUrl}/mcp-use/widgets/$1"`
|
|
1109
|
+
);
|
|
1110
|
+
html = html.replace(
|
|
1111
|
+
/<head[^>]*>/i,
|
|
1112
|
+
`<head>
|
|
1113
|
+
<script>window.__getFile = (filename) => { return "${this.serverBaseUrl}/mcp-use/widgets/${widgetName}/"+filename }</script>`
|
|
1114
|
+
);
|
|
1031
1115
|
}
|
|
1032
1116
|
} catch (error) {
|
|
1033
|
-
console.error(
|
|
1117
|
+
console.error(
|
|
1118
|
+
`[WIDGET] Failed to read ${widgetName}/index.html:`,
|
|
1119
|
+
error
|
|
1120
|
+
);
|
|
1034
1121
|
continue;
|
|
1035
1122
|
}
|
|
1036
1123
|
let metadata = {};
|
|
@@ -1046,7 +1133,9 @@ if (container && Component) {
|
|
|
1046
1133
|
props = metadata.inputs;
|
|
1047
1134
|
}
|
|
1048
1135
|
} catch (error) {
|
|
1049
|
-
console.log(
|
|
1136
|
+
console.log(
|
|
1137
|
+
`[WIDGET] No metadata found for ${widgetName}, using defaults`
|
|
1138
|
+
);
|
|
1050
1139
|
}
|
|
1051
1140
|
this.uiResource({
|
|
1052
1141
|
name: widgetName,
|
|
@@ -1089,7 +1178,9 @@ if (container && Component) {
|
|
|
1089
1178
|
}
|
|
1090
1179
|
}
|
|
1091
1180
|
});
|
|
1092
|
-
console.log(
|
|
1181
|
+
console.log(
|
|
1182
|
+
`[WIDGET] ${widgetName} mounted at ${baseRoute}/${widgetName}`
|
|
1183
|
+
);
|
|
1093
1184
|
}
|
|
1094
1185
|
}
|
|
1095
1186
|
/**
|
|
@@ -1185,8 +1276,12 @@ if (container && Component) {
|
|
|
1185
1276
|
await this.mountMcp();
|
|
1186
1277
|
this.mountInspector();
|
|
1187
1278
|
this.app.listen(this.serverPort, () => {
|
|
1188
|
-
console.log(
|
|
1189
|
-
|
|
1279
|
+
console.log(
|
|
1280
|
+
`[SERVER] Listening on http://${this.serverHost}:${this.serverPort}`
|
|
1281
|
+
);
|
|
1282
|
+
console.log(
|
|
1283
|
+
`[MCP] Endpoints: http://${this.serverHost}:${this.serverPort}/mcp`
|
|
1284
|
+
);
|
|
1190
1285
|
});
|
|
1191
1286
|
}
|
|
1192
1287
|
/**
|
|
@@ -1216,14 +1311,18 @@ if (container && Component) {
|
|
|
1216
1311
|
if (this.isProductionMode()) {
|
|
1217
1312
|
const manifest = this.readBuildManifest();
|
|
1218
1313
|
if (!manifest?.includeInspector) {
|
|
1219
|
-
console.log(
|
|
1314
|
+
console.log(
|
|
1315
|
+
"[INSPECTOR] Skipped in production (use --with-inspector flag during build)"
|
|
1316
|
+
);
|
|
1220
1317
|
return;
|
|
1221
1318
|
}
|
|
1222
1319
|
}
|
|
1223
1320
|
import("@mcp-use/inspector").then(({ mountInspector }) => {
|
|
1224
1321
|
mountInspector(this.app);
|
|
1225
1322
|
this.inspectorMounted = true;
|
|
1226
|
-
console.log(
|
|
1323
|
+
console.log(
|
|
1324
|
+
`[INSPECTOR] UI available at http://${this.serverHost}:${this.serverPort}/inspector`
|
|
1325
|
+
);
|
|
1227
1326
|
}).catch(() => {
|
|
1228
1327
|
});
|
|
1229
1328
|
}
|
|
@@ -1252,7 +1351,15 @@ if (container && Component) {
|
|
|
1252
1351
|
this.app.get("/mcp-use/widgets/:widget/assets/*", (req, res, next) => {
|
|
1253
1352
|
const widget = req.params.widget;
|
|
1254
1353
|
const assetFile = req.params[0];
|
|
1255
|
-
const assetPath = join(
|
|
1354
|
+
const assetPath = join(
|
|
1355
|
+
process.cwd(),
|
|
1356
|
+
"dist",
|
|
1357
|
+
"resources",
|
|
1358
|
+
"widgets",
|
|
1359
|
+
widget,
|
|
1360
|
+
"assets",
|
|
1361
|
+
assetFile
|
|
1362
|
+
);
|
|
1256
1363
|
res.sendFile(assetPath, (err) => err ? next() : void 0);
|
|
1257
1364
|
});
|
|
1258
1365
|
this.app.get("/mcp-use/widgets/assets/*", (req, res, next) => {
|
|
@@ -1272,12 +1379,28 @@ if (container && Component) {
|
|
|
1272
1379
|
}
|
|
1273
1380
|
});
|
|
1274
1381
|
this.app.get("/mcp-use/widgets/:widget", (req, res, next) => {
|
|
1275
|
-
const filePath = join(
|
|
1382
|
+
const filePath = join(
|
|
1383
|
+
process.cwd(),
|
|
1384
|
+
"dist",
|
|
1385
|
+
"resources",
|
|
1386
|
+
"widgets",
|
|
1387
|
+
req.params.widget,
|
|
1388
|
+
"index.html"
|
|
1389
|
+
);
|
|
1276
1390
|
let html = readFileSync(filePath, "utf8");
|
|
1277
|
-
html = html.replace(
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1391
|
+
html = html.replace(
|
|
1392
|
+
/src="\/mcp-use\/widgets\/([^"]+)"/g,
|
|
1393
|
+
`src="${this.serverBaseUrl}/mcp-use/widgets/$1"`
|
|
1394
|
+
);
|
|
1395
|
+
html = html.replace(
|
|
1396
|
+
/href="\/mcp-use\/widgets\/([^"]+)"/g,
|
|
1397
|
+
`href="${this.serverBaseUrl}/mcp-use/widgets/$1"`
|
|
1398
|
+
);
|
|
1399
|
+
html = html.replace(
|
|
1400
|
+
/<head[^>]*>/i,
|
|
1401
|
+
`<head>
|
|
1402
|
+
<script>window.__getFile = (filename) => { return "${this.serverBaseUrl}/mcp-use/widgets/${req.params.widget}/"+filename }</script>`
|
|
1403
|
+
);
|
|
1281
1404
|
res.send(html);
|
|
1282
1405
|
});
|
|
1283
1406
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../src/server/logging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../src/server/logging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CAkCN"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { PromptDefinition, ResourceDefinition, ResourceTemplateDefinition, ServerConfig, ToolDefinition, UIResourceDefinition } from
|
|
2
|
-
import { type Express } from
|
|
1
|
+
import type { PromptDefinition, ResourceDefinition, ResourceTemplateDefinition, ServerConfig, ToolDefinition, UIResourceDefinition } from "./types/index.js";
|
|
2
|
+
import { type Express } from "express";
|
|
3
3
|
export declare class McpServer {
|
|
4
4
|
private server;
|
|
5
5
|
private config;
|
|
@@ -524,33 +524,33 @@ export type McpServerInstance = Omit<McpServer, keyof Express> & Express;
|
|
|
524
524
|
* Create a new MCP server instance
|
|
525
525
|
*
|
|
526
526
|
* @param name - Server name
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
527
|
+
* @param config - Optional server configuration
|
|
528
|
+
* @param config.version - Server version (defaults to '1.0.0')
|
|
529
|
+
* @param config.description - Server description
|
|
530
|
+
* @param config.host - Hostname for widget URLs and server endpoints (defaults to 'localhost')
|
|
531
|
+
* @param config.baseUrl - Full base URL (e.g., 'https://myserver.com') - overrides host:port for widget URLs
|
|
532
|
+
* @returns McpServerInstance with both MCP and Express methods
|
|
533
|
+
*
|
|
534
|
+
* @example
|
|
535
|
+
* ```typescript
|
|
536
|
+
* // Basic usage
|
|
537
|
+
* const server = createMCPServer('my-server', {
|
|
538
|
+
* version: '1.0.0',
|
|
539
|
+
* description: 'My MCP server'
|
|
540
|
+
* })
|
|
541
|
+
*
|
|
542
|
+
* // With custom host (e.g., for Docker or remote access)
|
|
543
|
+
* const server = createMCPServer('my-server', {
|
|
544
|
+
* version: '1.0.0',
|
|
545
|
+
* host: '0.0.0.0' // or 'myserver.com'
|
|
546
|
+
* })
|
|
547
|
+
*
|
|
548
|
+
* // With full base URL (e.g., behind a proxy or custom domain)
|
|
549
|
+
* const server = createMCPServer('my-server', {
|
|
550
|
+
* version: '1.0.0',
|
|
551
|
+
* baseUrl: 'https://myserver.com' // or process.env.MCP_URL
|
|
552
|
+
* })
|
|
553
|
+
* ```
|
|
554
554
|
*/
|
|
555
555
|
export declare function createMCPServer(name: string, config?: Partial<ServerConfig>): McpServerInstance;
|
|
556
556
|
//# sourceMappingURL=mcp-server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../../src/server/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACZ,cAAc,EACd,oBAAoB,EAIrB,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../../src/server/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACZ,cAAc,EACd,oBAAoB,EAIrB,MAAM,kBAAkB,CAAC;AAM1B,OAAgB,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAgBhD,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAC,CAAS;IAE/B;;;;;;;;;OASG;gBACS,MAAM,EAAE,YAAY;IA6ChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;IACH,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI;IAmBtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,gBAAgB,CACd,0BAA0B,EAAE,0BAA0B,GACrD,IAAI;IAiDP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;IACH,IAAI,CAAC,cAAc,EAAE,cAAc,GAAG,IAAI;IAmB1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI;IAgBhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkEG;IACH,UAAU,CAAC,UAAU,EAAE,oBAAoB,GAAG,IAAI;IA0JlD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,sBAAsB;IA2B9B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;IAsBtB;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;;;;;;;;;OAUG;IACG,YAAY,CAAC,OAAO,CAAC,EAAE;QAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjB;;;;;;;;;;;;OAYG;YACW,eAAe;IA4T7B;;;;;;;;;;;OAWG;YACW,sBAAsB;IAyKpC;;;;;;;;;;;;;;;;;;;OAmBG;YACW,QAAQ;IA2DtB;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B1C;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,OAAO,CAAC,cAAc;IAiCtB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,iBAAiB;IAsEzB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,kBAAkB;IA+C1B;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,sBAAsB;IAqC9B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,qBAAqB;IAK7B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,gBAAgB;CA4BzB;AAED,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM,GACjC,iBAAiB,CASnB"}
|
|
@@ -10,7 +10,7 @@ export interface ServerConfig {
|
|
|
10
10
|
}
|
|
11
11
|
export interface InputDefinition {
|
|
12
12
|
name: string;
|
|
13
|
-
type:
|
|
13
|
+
type: "string" | "number" | "boolean" | "object" | "array";
|
|
14
14
|
description?: string;
|
|
15
15
|
required?: boolean;
|
|
16
16
|
default?: any;
|
|
@@ -20,7 +20,7 @@ export interface InputDefinition {
|
|
|
20
20
|
*/
|
|
21
21
|
export interface ResourceAnnotations {
|
|
22
22
|
/** Intended audience(s) for this resource */
|
|
23
|
-
audience?: (
|
|
23
|
+
audience?: ("user" | "assistant")[];
|
|
24
24
|
/** Priority from 0.0 (least important) to 1.0 (most important) */
|
|
25
25
|
priority?: number;
|
|
26
26
|
/** ISO 8601 formatted timestamp of last modification */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/server/types/common.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/server/types/common.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC;IACpC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Centralized type exports for MCP server
|
|
3
3
|
*/
|
|
4
|
-
export { ServerConfig, InputDefinition, ResourceAnnotations } from
|
|
5
|
-
export { ReadResourceCallback, ReadResourceTemplateCallback, ResourceTemplateConfig, ResourceTemplateDefinition, ResourceDefinition, UIResourceContent, WidgetProps, UIEncoding, RemoteDomFramework, UIResourceDefinition, ExternalUrlUIResource, RawHtmlUIResource, RemoteDomUIResource, AppsSdkUIResource, WidgetConfig, WidgetManifest, DiscoverWidgetsOptions, AppsSdkMetadata, AppsSdkToolMetadata } from
|
|
6
|
-
export { ToolCallback, ToolDefinition } from
|
|
7
|
-
export { PromptCallback, PromptDefinition } from
|
|
4
|
+
export { ServerConfig, InputDefinition, ResourceAnnotations, } from "./common.js";
|
|
5
|
+
export { ReadResourceCallback, ReadResourceTemplateCallback, ResourceTemplateConfig, ResourceTemplateDefinition, ResourceDefinition, UIResourceContent, WidgetProps, UIEncoding, RemoteDomFramework, UIResourceDefinition, ExternalUrlUIResource, RawHtmlUIResource, RemoteDomUIResource, AppsSdkUIResource, WidgetConfig, WidgetManifest, DiscoverWidgetsOptions, AppsSdkMetadata, AppsSdkToolMetadata, } from "./resource.js";
|
|
6
|
+
export { ToolCallback, ToolDefinition } from "./tool.js";
|
|
7
|
+
export { PromptCallback, PromptDefinition } from "./prompt.js";
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,YAAY,EACZ,eAAe,EACf,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,YAAY,EACZ,eAAe,EACf,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAElB,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,sBAAsB,EAEtB,eAAe,EACf,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { GetPromptResult, GetPromptRequest } from
|
|
2
|
-
import type { InputDefinition } from
|
|
1
|
+
import type { GetPromptResult, GetPromptRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import type { InputDefinition } from "./common.js";
|
|
3
3
|
export type PromptCallback = (params: GetPromptRequest) => Promise<GetPromptResult>;
|
|
4
4
|
export interface PromptDefinition {
|
|
5
5
|
/** Unique identifier for the prompt */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../src/server/types/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../src/server/types/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,MAAM,cAAc,GAAG,CAC3B,MAAM,EAAE,gBAAgB,KACrB,OAAO,CAAC,eAAe,CAAC,CAAC;AAE9B,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,eAAe,EAAE,CAAC;IACzB,wDAAwD;IACxD,EAAE,EAAE,cAAc,CAAC;CACpB"}
|