@ttoss/http-server-mcp 0.27.1 → 0.28.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/MIGRATIONS.md +35 -0
- package/README.md +123 -1
- package/dist/index.cjs +252 -37
- package/dist/index.d.cts +238 -4
- package/dist/index.d.mts +238 -4
- package/dist/index.mjs +251 -39
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
-
import { CallToolResult, McpServer, McpServer as McpServer$1 } from "@modelcontextprotocol/server";
|
|
3
|
+
import { CallToolResult, McpServer, McpServer as McpServer$1, McpServerFactory, RegisteredResource } from "@modelcontextprotocol/server";
|
|
4
4
|
import { Router } from "@ttoss/http-server";
|
|
5
5
|
import accepts from "accepts";
|
|
6
6
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -675,6 +675,197 @@ declare namespace Application {
|
|
|
675
675
|
*/
|
|
676
676
|
declare const getIdentity: <T = unknown>() => T | undefined;
|
|
677
677
|
//#endregion
|
|
678
|
+
//#region src/registerAppResource.d.ts
|
|
679
|
+
/**
|
|
680
|
+
* Identifier of the MCP Apps extension (`io.modelcontextprotocol/ui`), used as
|
|
681
|
+
* the key under `capabilities.extensions` on both sides of the handshake.
|
|
682
|
+
*
|
|
683
|
+
* A client declares Apps support with it; a server may advertise the same key
|
|
684
|
+
* so a host can discover the support without inspecting tool metadata:
|
|
685
|
+
*
|
|
686
|
+
* ```typescript
|
|
687
|
+
* new McpServer(
|
|
688
|
+
* { name: 'weather', version: '1.0.0' },
|
|
689
|
+
* {
|
|
690
|
+
* capabilities: {
|
|
691
|
+
* extensions: {
|
|
692
|
+
* [UI_EXTENSION_ID]: { mimeTypes: [UI_RESOURCE_MIME_TYPE] },
|
|
693
|
+
* },
|
|
694
|
+
* },
|
|
695
|
+
* }
|
|
696
|
+
* );
|
|
697
|
+
* ```
|
|
698
|
+
*/
|
|
699
|
+
declare const UI_EXTENSION_ID = "io.modelcontextprotocol/ui";
|
|
700
|
+
/** MIME type every MCP Apps HTML resource is served as. */
|
|
701
|
+
declare const UI_RESOURCE_MIME_TYPE = "text/html;profile=mcp-app";
|
|
702
|
+
/**
|
|
703
|
+
* Origins an app's view is allowed to reach, mapped by the host onto the
|
|
704
|
+
* iframe's Content Security Policy. Anything not declared is blocked: an
|
|
705
|
+
* omitted list is the restrictive default, not "no restriction".
|
|
706
|
+
*/
|
|
707
|
+
interface UiResourceCsp {
|
|
708
|
+
/** Origins for network requests (`connect-src`). */
|
|
709
|
+
connectDomains?: string[];
|
|
710
|
+
/**
|
|
711
|
+
* Origins for scripts, styles, images, fonts and media (`script-src`,
|
|
712
|
+
* `style-src`, `img-src`, `font-src`, `media-src`).
|
|
713
|
+
*/
|
|
714
|
+
resourceDomains?: string[];
|
|
715
|
+
/** Origins for nested iframes (`frame-src`). */
|
|
716
|
+
frameDomains?: string[];
|
|
717
|
+
/** Allowed document base URIs (`base-uri`). */
|
|
718
|
+
baseUriDomains?: string[];
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Browser capabilities the view asks for. A host *may* grant them, so a view
|
|
722
|
+
* should feature-detect rather than assume: each key is a request, not a
|
|
723
|
+
* guarantee.
|
|
724
|
+
*/
|
|
725
|
+
interface UiResourcePermissions {
|
|
726
|
+
camera?: Record<string, never>;
|
|
727
|
+
microphone?: Record<string, never>;
|
|
728
|
+
geolocation?: Record<string, never>;
|
|
729
|
+
clipboardWrite?: Record<string, never>;
|
|
730
|
+
}
|
|
731
|
+
/** Rendering and security configuration for an app's view (`_meta.ui`). */
|
|
732
|
+
interface UiResourceMeta {
|
|
733
|
+
/** Origins the view may reach; omitted means none. */
|
|
734
|
+
csp?: UiResourceCsp;
|
|
735
|
+
/** Browser capabilities requested for the view. */
|
|
736
|
+
permissions?: UiResourcePermissions;
|
|
737
|
+
/**
|
|
738
|
+
* Dedicated sandbox origin for the view, for cases needing a stable origin
|
|
739
|
+
* (OAuth callbacks, CORS, API key allowlists). The accepted format is
|
|
740
|
+
* host-specific; consult the host's documentation rather than deriving one.
|
|
741
|
+
*/
|
|
742
|
+
domain?: string;
|
|
743
|
+
/** Whether the host should draw a border and background around the view. */
|
|
744
|
+
prefersBorder?: boolean;
|
|
745
|
+
}
|
|
746
|
+
/** Who may reach a tool. Defaults to both when left unset. */
|
|
747
|
+
type UiToolVisibility = 'model' | 'app';
|
|
748
|
+
/** Parameters for {@link registerAppResource}. */
|
|
749
|
+
interface RegisterAppResourceParams {
|
|
750
|
+
/** The `McpServer` instance to register the app resource on. */
|
|
751
|
+
server: McpServer$1;
|
|
752
|
+
/** Resource name, as listed by `resources/list`. */
|
|
753
|
+
name: string;
|
|
754
|
+
/** Resource URI. Must use the `ui://` scheme. */
|
|
755
|
+
uri: string;
|
|
756
|
+
/** What the view does and when a host should render it. */
|
|
757
|
+
description?: string;
|
|
758
|
+
/**
|
|
759
|
+
* The view's HTML5 document, or a builder invoked per `resources/read`.
|
|
760
|
+
* A builder receives the requested URI so one registration can serve
|
|
761
|
+
* variants of a document.
|
|
762
|
+
*/
|
|
763
|
+
html: string | ((args: {
|
|
764
|
+
uri: URL;
|
|
765
|
+
}) => string | Promise<string>);
|
|
766
|
+
/** Rendering and security configuration relayed to the host as `_meta.ui`. */
|
|
767
|
+
ui?: UiResourceMeta;
|
|
768
|
+
}
|
|
769
|
+
/** Parameters for {@link RegisteredAppResource.toolMeta}. */
|
|
770
|
+
interface ToolMetaParams {
|
|
771
|
+
/**
|
|
772
|
+
* Who may reach the tool. Left unset, the spec's default applies — visible
|
|
773
|
+
* to the model *and* callable by the app.
|
|
774
|
+
*/
|
|
775
|
+
visibility?: UiToolVisibility[];
|
|
776
|
+
/** Further `_meta` entries to merge in, e.g. vendor-namespaced keys. */
|
|
777
|
+
_meta?: Record<string, unknown>;
|
|
778
|
+
}
|
|
779
|
+
/** An app resource registered by {@link registerAppResource}. */
|
|
780
|
+
interface RegisteredAppResource {
|
|
781
|
+
/** The URI tools link to. */
|
|
782
|
+
uri: string;
|
|
783
|
+
/** The SDK's registration handle, for `update`/`disable`/`remove`. */
|
|
784
|
+
resource: RegisteredResource;
|
|
785
|
+
/**
|
|
786
|
+
* Builds the `_meta` bag that links a tool to this view. Pass it to
|
|
787
|
+
* `registerTool`, {@link registerToolFromSchema}, or a `GatedToolDef` —
|
|
788
|
+
* whichever registration path the tool uses.
|
|
789
|
+
*/
|
|
790
|
+
toolMeta: (params?: ToolMetaParams) => Record<string, unknown>;
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Registers an MCP Apps view: a `ui://` resource a tool result is rendered
|
|
794
|
+
* with, per the `io.modelcontextprotocol/ui` extension.
|
|
795
|
+
*
|
|
796
|
+
* The extension asks nothing of the transport — a view is an ordinary MCP
|
|
797
|
+
* resource, and the tool linkage is ordinary tool `_meta` — so this is
|
|
798
|
+
* registration sugar over `registerResource`, not new protocol surface. What
|
|
799
|
+
* it owns is the part that is easy to get wrong: the `ui://` scheme, the exact
|
|
800
|
+
* MIME type, `_meta.ui` on both the declaration and the read result, and
|
|
801
|
+
* writing the deprecated flat linkage key alongside the current one.
|
|
802
|
+
*
|
|
803
|
+
* **Register the linkage unconditionally.** The extension's negotiation is
|
|
804
|
+
* per-request and only reliably readable on the `2026-07-28` revision; in this
|
|
805
|
+
* package's default stateless 2025-era mode there is no remembered
|
|
806
|
+
* `initialize` to read a client capability from. Gating registration on that
|
|
807
|
+
* capability would therefore silently drop the view for every 2025-era client.
|
|
808
|
+
* A host without Apps support simply ignores `_meta`, so keep each tool's
|
|
809
|
+
* `content` meaningful on its own and let the text result be the fallback.
|
|
810
|
+
*
|
|
811
|
+
* @example
|
|
812
|
+
* ```typescript
|
|
813
|
+
* import {
|
|
814
|
+
* McpServer,
|
|
815
|
+
* registerAppResource,
|
|
816
|
+
* UI_EXTENSION_ID,
|
|
817
|
+
* UI_RESOURCE_MIME_TYPE,
|
|
818
|
+
* z,
|
|
819
|
+
* } from '@ttoss/http-server-mcp';
|
|
820
|
+
*
|
|
821
|
+
* const server = new McpServer(
|
|
822
|
+
* { name: 'weather', version: '1.0.0' },
|
|
823
|
+
* {
|
|
824
|
+
* capabilities: {
|
|
825
|
+
* extensions: { [UI_EXTENSION_ID]: { mimeTypes: [UI_RESOURCE_MIME_TYPE] } },
|
|
826
|
+
* },
|
|
827
|
+
* }
|
|
828
|
+
* );
|
|
829
|
+
*
|
|
830
|
+
* const dashboard = registerAppResource({
|
|
831
|
+
* server,
|
|
832
|
+
* name: 'weather_dashboard',
|
|
833
|
+
* uri: 'ui://weather/dashboard',
|
|
834
|
+
* description: 'Interactive weather dashboard',
|
|
835
|
+
* html: dashboardHtml,
|
|
836
|
+
* ui: {
|
|
837
|
+
* csp: { connectDomains: ['https://api.openweathermap.org'] },
|
|
838
|
+
* prefersBorder: true,
|
|
839
|
+
* },
|
|
840
|
+
* });
|
|
841
|
+
*
|
|
842
|
+
* server.registerTool(
|
|
843
|
+
* 'get-weather',
|
|
844
|
+
* {
|
|
845
|
+
* description: 'Get the weather for a location',
|
|
846
|
+
* inputSchema: { location: z.string() },
|
|
847
|
+
* _meta: dashboard.toolMeta(),
|
|
848
|
+
* },
|
|
849
|
+
* async ({ location }) => {
|
|
850
|
+
* const forecast = await fetchForecast(location);
|
|
851
|
+
* return {
|
|
852
|
+
* // Text stays meaningful: it is what a host without Apps renders.
|
|
853
|
+
* content: [{ type: 'text', text: summarise(forecast) }],
|
|
854
|
+
* structuredContent: forecast,
|
|
855
|
+
* };
|
|
856
|
+
* }
|
|
857
|
+
* );
|
|
858
|
+
* ```
|
|
859
|
+
*/
|
|
860
|
+
declare const registerAppResource: ({
|
|
861
|
+
server,
|
|
862
|
+
name,
|
|
863
|
+
uri,
|
|
864
|
+
description,
|
|
865
|
+
html,
|
|
866
|
+
ui
|
|
867
|
+
}: RegisterAppResourceParams) => RegisteredAppResource;
|
|
868
|
+
//#endregion
|
|
678
869
|
//#region src/registerToolFromSchema.d.ts
|
|
679
870
|
/**
|
|
680
871
|
* A plain JSON Schema object (draft-07 compatible) describing the shape of a
|
|
@@ -721,6 +912,19 @@ interface RegisterToolFromSchemaParams {
|
|
|
721
912
|
* @default false
|
|
722
913
|
*/
|
|
723
914
|
validateArguments?: boolean;
|
|
915
|
+
/**
|
|
916
|
+
* Tool metadata forwarded verbatim on `tools/list`.
|
|
917
|
+
*
|
|
918
|
+
* The MCP Apps extension links a tool to the view its result is rendered
|
|
919
|
+
* with through this field; build the bag with `toolMeta()` from
|
|
920
|
+
* `registerAppResource` rather than writing the keys by hand.
|
|
921
|
+
*
|
|
922
|
+
* @example
|
|
923
|
+
* ```typescript
|
|
924
|
+
* _meta: dashboard.toolMeta({ visibility: ['app'] }),
|
|
925
|
+
* ```
|
|
926
|
+
*/
|
|
927
|
+
_meta?: Record<string, unknown>;
|
|
724
928
|
/**
|
|
725
929
|
* Tool handler invoked when the AI client calls the tool.
|
|
726
930
|
* Receives the request arguments, validated against `inputSchema` only when
|
|
@@ -744,7 +948,7 @@ interface RegisterToolFromSchemaParams {
|
|
|
744
948
|
*
|
|
745
949
|
* @param server - The `McpServer` instance to register the tool on.
|
|
746
950
|
* @param params - Tool configuration including name, description, inputSchema,
|
|
747
|
-
* validateArguments, and handler.
|
|
951
|
+
* validateArguments, `_meta`, and handler.
|
|
748
952
|
*
|
|
749
953
|
* @example
|
|
750
954
|
* ```typescript
|
|
@@ -801,7 +1005,12 @@ type GatedToolDef = {
|
|
|
801
1005
|
* Each gate receives the full {@link ToolCallContext} (identity + args).
|
|
802
1006
|
* Throw to reject the call; return (or resolve) to continue.
|
|
803
1007
|
*/
|
|
804
|
-
gates?: Array<(ctx: ToolCallContext) => void | Promise<void>>;
|
|
1008
|
+
gates?: Array<(ctx: ToolCallContext) => void | Promise<void>>;
|
|
1009
|
+
/**
|
|
1010
|
+
* Tool metadata forwarded verbatim on `tools/list` — how a gated tool links
|
|
1011
|
+
* to an MCP Apps view (`registerAppResource(...).toolMeta()`).
|
|
1012
|
+
*/
|
|
1013
|
+
_meta?: Record<string, unknown>; /** The tool handler. Receives merged call args + `buildContext` output. */
|
|
805
1014
|
method: (args: Record<string, unknown>) => Promise<unknown>;
|
|
806
1015
|
};
|
|
807
1016
|
/** Options for {@link createGatedToolRegistrar}. */
|
|
@@ -1101,6 +1310,31 @@ interface McpRouterOptions {
|
|
|
1101
1310
|
* served statelessly regardless of this option.
|
|
1102
1311
|
*/
|
|
1103
1312
|
sessionIdGenerator?: () => string;
|
|
1313
|
+
/**
|
|
1314
|
+
* Per-request factory for the `McpServer` serving one `2026-07-28` request.
|
|
1315
|
+
* Set it to serve that revision; without it, requests carrying its
|
|
1316
|
+
* per-request envelope get the unsupported-protocol-version error naming the
|
|
1317
|
+
* 2025-era revisions this endpoint does serve. Register the same tools here
|
|
1318
|
+
* as on `server`, so the two eras cannot drift apart.
|
|
1319
|
+
*
|
|
1320
|
+
* It cannot default to `server`: the negotiated revision is instance state,
|
|
1321
|
+
* so one instance serving both eras is pinned to `2026-07-28` by the first
|
|
1322
|
+
* client to speak it, and every 2025-era request after that is answered
|
|
1323
|
+
* `-32602 … missing the required _meta envelope` at HTTP 200. The SDK's own
|
|
1324
|
+
* serving entries take a factory and call it once per request.
|
|
1325
|
+
*
|
|
1326
|
+
* @example
|
|
1327
|
+
* ```typescript
|
|
1328
|
+
* const buildServer = () => {
|
|
1329
|
+
* const mcpServer = new McpServer({ name: 'my-server', version: '1.0.0' });
|
|
1330
|
+
* registerEverything(mcpServer);
|
|
1331
|
+
* return mcpServer;
|
|
1332
|
+
* };
|
|
1333
|
+
*
|
|
1334
|
+
* createMcpRouter(buildServer(), { createMcpServer: buildServer });
|
|
1335
|
+
* ```
|
|
1336
|
+
*/
|
|
1337
|
+
createMcpServer?: McpServerFactory;
|
|
1104
1338
|
/**
|
|
1105
1339
|
* Base URL prepended to relative paths passed to `apiCall` (paths starting
|
|
1106
1340
|
* with `/`). Tool handlers can then call `apiCall('GET', '/resource')` without
|
|
@@ -1210,4 +1444,4 @@ interface McpRouterOptions {
|
|
|
1210
1444
|
*/
|
|
1211
1445
|
declare const createMcpRouter: (server: McpServer$1, options?: McpRouterOptions) => Router<Application.DefaultState, Application.DefaultContext>;
|
|
1212
1446
|
//#endregion
|
|
1213
|
-
export { ApiCallOptions, CognitoUserPoolConfig, type CreateGatedToolRegistrarOptions, type GatedToolDef, type JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, type RegisterToolFromSchemaParams, type ToolCallContext, type ToolIdentity, apiCall, checkScopes, createGatedToolRegistrar, createMcpRouter, getIdentity, registerToolFromSchema, z };
|
|
1447
|
+
export { ApiCallOptions, CognitoUserPoolConfig, type CreateGatedToolRegistrarOptions, type GatedToolDef, type JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, type RegisterAppResourceParams, type RegisterToolFromSchemaParams, type RegisteredAppResource, type ToolCallContext, type ToolIdentity, type ToolMetaParams, UI_EXTENSION_ID, UI_RESOURCE_MIME_TYPE, type UiResourceCsp, type UiResourceMeta, type UiResourcePermissions, type UiToolVisibility, apiCall, checkScopes, createGatedToolRegistrar, createMcpRouter, getIdentity, registerAppResource, registerToolFromSchema, z };
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { Router } from "@ttoss/http-server";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
|
-
import { CallToolResult, McpServer, McpServer as McpServer$1 } from "@modelcontextprotocol/server";
|
|
5
|
+
import { CallToolResult, McpServer, McpServer as McpServer$1, McpServerFactory, RegisteredResource } from "@modelcontextprotocol/server";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import accepts from "accepts";
|
|
8
8
|
import { AsyncLocalStorage as AsyncLocalStorage$1 } from "async_hooks";
|
|
@@ -676,6 +676,197 @@ declare namespace Application {
|
|
|
676
676
|
*/
|
|
677
677
|
declare const getIdentity: <T = unknown>() => T | undefined;
|
|
678
678
|
//#endregion
|
|
679
|
+
//#region src/registerAppResource.d.ts
|
|
680
|
+
/**
|
|
681
|
+
* Identifier of the MCP Apps extension (`io.modelcontextprotocol/ui`), used as
|
|
682
|
+
* the key under `capabilities.extensions` on both sides of the handshake.
|
|
683
|
+
*
|
|
684
|
+
* A client declares Apps support with it; a server may advertise the same key
|
|
685
|
+
* so a host can discover the support without inspecting tool metadata:
|
|
686
|
+
*
|
|
687
|
+
* ```typescript
|
|
688
|
+
* new McpServer(
|
|
689
|
+
* { name: 'weather', version: '1.0.0' },
|
|
690
|
+
* {
|
|
691
|
+
* capabilities: {
|
|
692
|
+
* extensions: {
|
|
693
|
+
* [UI_EXTENSION_ID]: { mimeTypes: [UI_RESOURCE_MIME_TYPE] },
|
|
694
|
+
* },
|
|
695
|
+
* },
|
|
696
|
+
* }
|
|
697
|
+
* );
|
|
698
|
+
* ```
|
|
699
|
+
*/
|
|
700
|
+
declare const UI_EXTENSION_ID = "io.modelcontextprotocol/ui";
|
|
701
|
+
/** MIME type every MCP Apps HTML resource is served as. */
|
|
702
|
+
declare const UI_RESOURCE_MIME_TYPE = "text/html;profile=mcp-app";
|
|
703
|
+
/**
|
|
704
|
+
* Origins an app's view is allowed to reach, mapped by the host onto the
|
|
705
|
+
* iframe's Content Security Policy. Anything not declared is blocked: an
|
|
706
|
+
* omitted list is the restrictive default, not "no restriction".
|
|
707
|
+
*/
|
|
708
|
+
interface UiResourceCsp {
|
|
709
|
+
/** Origins for network requests (`connect-src`). */
|
|
710
|
+
connectDomains?: string[];
|
|
711
|
+
/**
|
|
712
|
+
* Origins for scripts, styles, images, fonts and media (`script-src`,
|
|
713
|
+
* `style-src`, `img-src`, `font-src`, `media-src`).
|
|
714
|
+
*/
|
|
715
|
+
resourceDomains?: string[];
|
|
716
|
+
/** Origins for nested iframes (`frame-src`). */
|
|
717
|
+
frameDomains?: string[];
|
|
718
|
+
/** Allowed document base URIs (`base-uri`). */
|
|
719
|
+
baseUriDomains?: string[];
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Browser capabilities the view asks for. A host *may* grant them, so a view
|
|
723
|
+
* should feature-detect rather than assume: each key is a request, not a
|
|
724
|
+
* guarantee.
|
|
725
|
+
*/
|
|
726
|
+
interface UiResourcePermissions {
|
|
727
|
+
camera?: Record<string, never>;
|
|
728
|
+
microphone?: Record<string, never>;
|
|
729
|
+
geolocation?: Record<string, never>;
|
|
730
|
+
clipboardWrite?: Record<string, never>;
|
|
731
|
+
}
|
|
732
|
+
/** Rendering and security configuration for an app's view (`_meta.ui`). */
|
|
733
|
+
interface UiResourceMeta {
|
|
734
|
+
/** Origins the view may reach; omitted means none. */
|
|
735
|
+
csp?: UiResourceCsp;
|
|
736
|
+
/** Browser capabilities requested for the view. */
|
|
737
|
+
permissions?: UiResourcePermissions;
|
|
738
|
+
/**
|
|
739
|
+
* Dedicated sandbox origin for the view, for cases needing a stable origin
|
|
740
|
+
* (OAuth callbacks, CORS, API key allowlists). The accepted format is
|
|
741
|
+
* host-specific; consult the host's documentation rather than deriving one.
|
|
742
|
+
*/
|
|
743
|
+
domain?: string;
|
|
744
|
+
/** Whether the host should draw a border and background around the view. */
|
|
745
|
+
prefersBorder?: boolean;
|
|
746
|
+
}
|
|
747
|
+
/** Who may reach a tool. Defaults to both when left unset. */
|
|
748
|
+
type UiToolVisibility = 'model' | 'app';
|
|
749
|
+
/** Parameters for {@link registerAppResource}. */
|
|
750
|
+
interface RegisterAppResourceParams {
|
|
751
|
+
/** The `McpServer` instance to register the app resource on. */
|
|
752
|
+
server: McpServer$1;
|
|
753
|
+
/** Resource name, as listed by `resources/list`. */
|
|
754
|
+
name: string;
|
|
755
|
+
/** Resource URI. Must use the `ui://` scheme. */
|
|
756
|
+
uri: string;
|
|
757
|
+
/** What the view does and when a host should render it. */
|
|
758
|
+
description?: string;
|
|
759
|
+
/**
|
|
760
|
+
* The view's HTML5 document, or a builder invoked per `resources/read`.
|
|
761
|
+
* A builder receives the requested URI so one registration can serve
|
|
762
|
+
* variants of a document.
|
|
763
|
+
*/
|
|
764
|
+
html: string | ((args: {
|
|
765
|
+
uri: URL;
|
|
766
|
+
}) => string | Promise<string>);
|
|
767
|
+
/** Rendering and security configuration relayed to the host as `_meta.ui`. */
|
|
768
|
+
ui?: UiResourceMeta;
|
|
769
|
+
}
|
|
770
|
+
/** Parameters for {@link RegisteredAppResource.toolMeta}. */
|
|
771
|
+
interface ToolMetaParams {
|
|
772
|
+
/**
|
|
773
|
+
* Who may reach the tool. Left unset, the spec's default applies — visible
|
|
774
|
+
* to the model *and* callable by the app.
|
|
775
|
+
*/
|
|
776
|
+
visibility?: UiToolVisibility[];
|
|
777
|
+
/** Further `_meta` entries to merge in, e.g. vendor-namespaced keys. */
|
|
778
|
+
_meta?: Record<string, unknown>;
|
|
779
|
+
}
|
|
780
|
+
/** An app resource registered by {@link registerAppResource}. */
|
|
781
|
+
interface RegisteredAppResource {
|
|
782
|
+
/** The URI tools link to. */
|
|
783
|
+
uri: string;
|
|
784
|
+
/** The SDK's registration handle, for `update`/`disable`/`remove`. */
|
|
785
|
+
resource: RegisteredResource;
|
|
786
|
+
/**
|
|
787
|
+
* Builds the `_meta` bag that links a tool to this view. Pass it to
|
|
788
|
+
* `registerTool`, {@link registerToolFromSchema}, or a `GatedToolDef` —
|
|
789
|
+
* whichever registration path the tool uses.
|
|
790
|
+
*/
|
|
791
|
+
toolMeta: (params?: ToolMetaParams) => Record<string, unknown>;
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Registers an MCP Apps view: a `ui://` resource a tool result is rendered
|
|
795
|
+
* with, per the `io.modelcontextprotocol/ui` extension.
|
|
796
|
+
*
|
|
797
|
+
* The extension asks nothing of the transport — a view is an ordinary MCP
|
|
798
|
+
* resource, and the tool linkage is ordinary tool `_meta` — so this is
|
|
799
|
+
* registration sugar over `registerResource`, not new protocol surface. What
|
|
800
|
+
* it owns is the part that is easy to get wrong: the `ui://` scheme, the exact
|
|
801
|
+
* MIME type, `_meta.ui` on both the declaration and the read result, and
|
|
802
|
+
* writing the deprecated flat linkage key alongside the current one.
|
|
803
|
+
*
|
|
804
|
+
* **Register the linkage unconditionally.** The extension's negotiation is
|
|
805
|
+
* per-request and only reliably readable on the `2026-07-28` revision; in this
|
|
806
|
+
* package's default stateless 2025-era mode there is no remembered
|
|
807
|
+
* `initialize` to read a client capability from. Gating registration on that
|
|
808
|
+
* capability would therefore silently drop the view for every 2025-era client.
|
|
809
|
+
* A host without Apps support simply ignores `_meta`, so keep each tool's
|
|
810
|
+
* `content` meaningful on its own and let the text result be the fallback.
|
|
811
|
+
*
|
|
812
|
+
* @example
|
|
813
|
+
* ```typescript
|
|
814
|
+
* import {
|
|
815
|
+
* McpServer,
|
|
816
|
+
* registerAppResource,
|
|
817
|
+
* UI_EXTENSION_ID,
|
|
818
|
+
* UI_RESOURCE_MIME_TYPE,
|
|
819
|
+
* z,
|
|
820
|
+
* } from '@ttoss/http-server-mcp';
|
|
821
|
+
*
|
|
822
|
+
* const server = new McpServer(
|
|
823
|
+
* { name: 'weather', version: '1.0.0' },
|
|
824
|
+
* {
|
|
825
|
+
* capabilities: {
|
|
826
|
+
* extensions: { [UI_EXTENSION_ID]: { mimeTypes: [UI_RESOURCE_MIME_TYPE] } },
|
|
827
|
+
* },
|
|
828
|
+
* }
|
|
829
|
+
* );
|
|
830
|
+
*
|
|
831
|
+
* const dashboard = registerAppResource({
|
|
832
|
+
* server,
|
|
833
|
+
* name: 'weather_dashboard',
|
|
834
|
+
* uri: 'ui://weather/dashboard',
|
|
835
|
+
* description: 'Interactive weather dashboard',
|
|
836
|
+
* html: dashboardHtml,
|
|
837
|
+
* ui: {
|
|
838
|
+
* csp: { connectDomains: ['https://api.openweathermap.org'] },
|
|
839
|
+
* prefersBorder: true,
|
|
840
|
+
* },
|
|
841
|
+
* });
|
|
842
|
+
*
|
|
843
|
+
* server.registerTool(
|
|
844
|
+
* 'get-weather',
|
|
845
|
+
* {
|
|
846
|
+
* description: 'Get the weather for a location',
|
|
847
|
+
* inputSchema: { location: z.string() },
|
|
848
|
+
* _meta: dashboard.toolMeta(),
|
|
849
|
+
* },
|
|
850
|
+
* async ({ location }) => {
|
|
851
|
+
* const forecast = await fetchForecast(location);
|
|
852
|
+
* return {
|
|
853
|
+
* // Text stays meaningful: it is what a host without Apps renders.
|
|
854
|
+
* content: [{ type: 'text', text: summarise(forecast) }],
|
|
855
|
+
* structuredContent: forecast,
|
|
856
|
+
* };
|
|
857
|
+
* }
|
|
858
|
+
* );
|
|
859
|
+
* ```
|
|
860
|
+
*/
|
|
861
|
+
declare const registerAppResource: ({
|
|
862
|
+
server,
|
|
863
|
+
name,
|
|
864
|
+
uri,
|
|
865
|
+
description,
|
|
866
|
+
html,
|
|
867
|
+
ui
|
|
868
|
+
}: RegisterAppResourceParams) => RegisteredAppResource;
|
|
869
|
+
//#endregion
|
|
679
870
|
//#region src/registerToolFromSchema.d.ts
|
|
680
871
|
/**
|
|
681
872
|
* A plain JSON Schema object (draft-07 compatible) describing the shape of a
|
|
@@ -722,6 +913,19 @@ interface RegisterToolFromSchemaParams {
|
|
|
722
913
|
* @default false
|
|
723
914
|
*/
|
|
724
915
|
validateArguments?: boolean;
|
|
916
|
+
/**
|
|
917
|
+
* Tool metadata forwarded verbatim on `tools/list`.
|
|
918
|
+
*
|
|
919
|
+
* The MCP Apps extension links a tool to the view its result is rendered
|
|
920
|
+
* with through this field; build the bag with `toolMeta()` from
|
|
921
|
+
* `registerAppResource` rather than writing the keys by hand.
|
|
922
|
+
*
|
|
923
|
+
* @example
|
|
924
|
+
* ```typescript
|
|
925
|
+
* _meta: dashboard.toolMeta({ visibility: ['app'] }),
|
|
926
|
+
* ```
|
|
927
|
+
*/
|
|
928
|
+
_meta?: Record<string, unknown>;
|
|
725
929
|
/**
|
|
726
930
|
* Tool handler invoked when the AI client calls the tool.
|
|
727
931
|
* Receives the request arguments, validated against `inputSchema` only when
|
|
@@ -745,7 +949,7 @@ interface RegisterToolFromSchemaParams {
|
|
|
745
949
|
*
|
|
746
950
|
* @param server - The `McpServer` instance to register the tool on.
|
|
747
951
|
* @param params - Tool configuration including name, description, inputSchema,
|
|
748
|
-
* validateArguments, and handler.
|
|
952
|
+
* validateArguments, `_meta`, and handler.
|
|
749
953
|
*
|
|
750
954
|
* @example
|
|
751
955
|
* ```typescript
|
|
@@ -802,7 +1006,12 @@ type GatedToolDef = {
|
|
|
802
1006
|
* Each gate receives the full {@link ToolCallContext} (identity + args).
|
|
803
1007
|
* Throw to reject the call; return (or resolve) to continue.
|
|
804
1008
|
*/
|
|
805
|
-
gates?: Array<(ctx: ToolCallContext) => void | Promise<void>>;
|
|
1009
|
+
gates?: Array<(ctx: ToolCallContext) => void | Promise<void>>;
|
|
1010
|
+
/**
|
|
1011
|
+
* Tool metadata forwarded verbatim on `tools/list` — how a gated tool links
|
|
1012
|
+
* to an MCP Apps view (`registerAppResource(...).toolMeta()`).
|
|
1013
|
+
*/
|
|
1014
|
+
_meta?: Record<string, unknown>; /** The tool handler. Receives merged call args + `buildContext` output. */
|
|
806
1015
|
method: (args: Record<string, unknown>) => Promise<unknown>;
|
|
807
1016
|
};
|
|
808
1017
|
/** Options for {@link createGatedToolRegistrar}. */
|
|
@@ -1102,6 +1311,31 @@ interface McpRouterOptions {
|
|
|
1102
1311
|
* served statelessly regardless of this option.
|
|
1103
1312
|
*/
|
|
1104
1313
|
sessionIdGenerator?: () => string;
|
|
1314
|
+
/**
|
|
1315
|
+
* Per-request factory for the `McpServer` serving one `2026-07-28` request.
|
|
1316
|
+
* Set it to serve that revision; without it, requests carrying its
|
|
1317
|
+
* per-request envelope get the unsupported-protocol-version error naming the
|
|
1318
|
+
* 2025-era revisions this endpoint does serve. Register the same tools here
|
|
1319
|
+
* as on `server`, so the two eras cannot drift apart.
|
|
1320
|
+
*
|
|
1321
|
+
* It cannot default to `server`: the negotiated revision is instance state,
|
|
1322
|
+
* so one instance serving both eras is pinned to `2026-07-28` by the first
|
|
1323
|
+
* client to speak it, and every 2025-era request after that is answered
|
|
1324
|
+
* `-32602 … missing the required _meta envelope` at HTTP 200. The SDK's own
|
|
1325
|
+
* serving entries take a factory and call it once per request.
|
|
1326
|
+
*
|
|
1327
|
+
* @example
|
|
1328
|
+
* ```typescript
|
|
1329
|
+
* const buildServer = () => {
|
|
1330
|
+
* const mcpServer = new McpServer({ name: 'my-server', version: '1.0.0' });
|
|
1331
|
+
* registerEverything(mcpServer);
|
|
1332
|
+
* return mcpServer;
|
|
1333
|
+
* };
|
|
1334
|
+
*
|
|
1335
|
+
* createMcpRouter(buildServer(), { createMcpServer: buildServer });
|
|
1336
|
+
* ```
|
|
1337
|
+
*/
|
|
1338
|
+
createMcpServer?: McpServerFactory;
|
|
1105
1339
|
/**
|
|
1106
1340
|
* Base URL prepended to relative paths passed to `apiCall` (paths starting
|
|
1107
1341
|
* with `/`). Tool handlers can then call `apiCall('GET', '/resource')` without
|
|
@@ -1211,4 +1445,4 @@ interface McpRouterOptions {
|
|
|
1211
1445
|
*/
|
|
1212
1446
|
declare const createMcpRouter: (server: McpServer$1, options?: McpRouterOptions) => Router<Application.DefaultState, Application.DefaultContext>;
|
|
1213
1447
|
//#endregion
|
|
1214
|
-
export { ApiCallOptions, CognitoUserPoolConfig, type CreateGatedToolRegistrarOptions, type GatedToolDef, type JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, type RegisterToolFromSchemaParams, type ToolCallContext, type ToolIdentity, apiCall, checkScopes, createGatedToolRegistrar, createMcpRouter, getIdentity, registerToolFromSchema, z };
|
|
1448
|
+
export { ApiCallOptions, CognitoUserPoolConfig, type CreateGatedToolRegistrarOptions, type GatedToolDef, type JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, type RegisterAppResourceParams, type RegisterToolFromSchemaParams, type RegisteredAppResource, type ToolCallContext, type ToolIdentity, type ToolMetaParams, UI_EXTENSION_ID, UI_RESOURCE_MIME_TYPE, type UiResourceCsp, type UiResourceMeta, type UiResourcePermissions, type UiToolVisibility, apiCall, checkScopes, createGatedToolRegistrar, createMcpRouter, getIdentity, registerAppResource, registerToolFromSchema, z };
|