skybridge 0.0.0-dev.f57f202 → 0.0.0-dev.f58ff90
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/README.md +9 -9
- package/dist/cli/build-helpers.d.ts +1 -1
- package/dist/cli/build-helpers.js +9 -1
- package/dist/cli/build-helpers.js.map +1 -1
- package/dist/cli/build-helpers.test.js +24 -0
- package/dist/cli/build-helpers.test.js.map +1 -1
- package/dist/cli/build-steps.js +16 -5
- package/dist/cli/build-steps.js.map +1 -1
- package/dist/cli/build-steps.test.js +20 -0
- package/dist/cli/build-steps.test.js.map +1 -1
- package/dist/cli/resolve-skybridge-config.d.ts +1 -0
- package/dist/cli/resolve-skybridge-config.js +11 -1
- package/dist/cli/resolve-skybridge-config.js.map +1 -1
- package/dist/cli/use-typescript-check.js +4 -2
- package/dist/cli/use-typescript-check.js.map +1 -1
- package/dist/server/app.d.ts +22 -5
- package/dist/server/app.js +24 -13
- package/dist/server/app.js.map +1 -1
- package/dist/server/app.test.js +81 -0
- package/dist/server/app.test.js.map +1 -1
- package/dist/server/events.d.ts +113 -0
- package/dist/server/events.js +318 -0
- package/dist/server/events.js.map +1 -0
- package/dist/server/events.test.d.ts +1 -0
- package/dist/server/events.test.js +172 -0
- package/dist/server/events.test.js.map +1 -0
- package/dist/server/express.d.ts +3 -2
- package/dist/server/express.js +17 -11
- package/dist/server/express.js.map +1 -1
- package/dist/server/express.test.js +45 -0
- package/dist/server/express.test.js.map +1 -1
- package/dist/server/form-input.d.ts +120 -0
- package/dist/server/form-input.js +89 -0
- package/dist/server/form-input.js.map +1 -0
- package/dist/server/index.d.ts +4 -2
- package/dist/server/index.js +3 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp-errors.test.js +188 -0
- package/dist/server/mcp-errors.test.js.map +1 -1
- package/dist/server/metric.d.ts +5 -3
- package/dist/server/metric.js +5 -5
- package/dist/server/metric.js.map +1 -1
- package/dist/server/register-tool.test.js +153 -0
- package/dist/server/register-tool.test.js.map +1 -1
- package/dist/server/server.d.ts +179 -10
- package/dist/server/server.js +247 -23
- package/dist/server/server.js.map +1 -1
- package/dist/server/templateHelper.d.ts +1 -0
- package/dist/server/templateHelper.js.map +1 -1
- package/dist/server/templates.generated.js +26 -12
- package/dist/server/templates.generated.js.map +1 -1
- package/dist/server/tool-extra.test.js +79 -0
- package/dist/server/tool-extra.test.js.map +1 -1
- package/dist/server/view-resource-resolution.test.js +35 -0
- package/dist/server/view-resource-resolution.test.js.map +1 -1
- package/dist/web/bridges/adaptor.d.ts +9 -2
- package/dist/web/bridges/adaptor.js +113 -10
- package/dist/web/bridges/adaptor.js.map +1 -1
- package/dist/web/bridges/adaptor.test.js +66 -5
- package/dist/web/bridges/adaptor.test.js.map +1 -1
- package/dist/web/bridges/apps-sdk/bridge.js +1 -1
- package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
- package/dist/web/bridges/apps-sdk/types.d.ts +3 -4
- package/dist/web/bridges/apps-sdk/types.js.map +1 -1
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +3 -3
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +3 -3
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
- package/dist/web/bridges/mcp-app/types.d.ts +5 -13
- package/dist/web/bridges/mcp-app/types.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
- package/dist/web/bridges/types.d.ts +45 -6
- package/dist/web/bridges/types.js +1 -1
- package/dist/web/bridges/types.js.map +1 -1
- package/dist/web/hooks/index.d.ts +2 -0
- package/dist/web/hooks/index.js +2 -0
- package/dist/web/hooks/index.js.map +1 -1
- package/dist/web/hooks/openai-extensions.test.js +1 -8
- package/dist/web/hooks/openai-extensions.test.js.map +1 -1
- package/dist/web/hooks/use-call-tool.js +1 -1
- package/dist/web/hooks/use-call-tool.js.map +1 -1
- package/dist/web/hooks/use-call-tool.test.js +6 -2
- package/dist/web/hooks/use-call-tool.test.js.map +1 -1
- package/dist/web/hooks/use-deep-link.js +1 -27
- package/dist/web/hooks/use-deep-link.js.map +1 -1
- package/dist/web/hooks/use-file-resource.d.ts +37 -0
- package/dist/web/hooks/use-file-resource.js +98 -0
- package/dist/web/hooks/use-file-resource.js.map +1 -0
- package/dist/web/hooks/use-file-resource.test.d.ts +1 -0
- package/dist/web/hooks/use-file-resource.test.js +65 -0
- package/dist/web/hooks/use-file-resource.test.js.map +1 -0
- package/dist/web/hooks/use-host.d.ts +3 -3
- package/dist/web/hooks/use-host.js +4 -4
- package/dist/web/hooks/use-host.js.map +1 -1
- package/dist/web/hooks/use-model-context.js +3 -5
- package/dist/web/hooks/use-model-context.js.map +1 -1
- package/dist/web/hooks/use-open-file.d.ts +20 -0
- package/dist/web/hooks/use-open-file.js +25 -0
- package/dist/web/hooks/use-open-file.js.map +1 -0
- package/dist/web/hooks/use-register-view-tool.d.ts +1 -1
- package/dist/web/hooks/use-register-view-tool.js +1 -1
- package/dist/web/hooks/use-register-view-tool.js.map +1 -1
- package/dist/web/hooks/use-send-follow-up-message.d.ts +8 -2
- package/dist/web/hooks/use-send-follow-up-message.js +6 -0
- package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
- package/dist/web/mount-view.js +3 -5
- package/dist/web/mount-view.js.map +1 -1
- package/package.json +4 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-tool.test.js","sourceRoot":"","sources":["../../src/server/register-tool.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Client, InMemoryTransport } from \"@modelcontextprotocol/client\";\nimport { describe, expect, it } from \"vitest\";\nimport { z } from \"zod\";\nimport { Skybridge } from \"./app.js\";\n\ndescribe(\"registerTool handler invocation\", () => {\n it(\"passes empty args and a usable extra to a schema-less tool handler\", async () => {\n let received: { args: unknown; extra: unknown } | undefined;\n const app = new Skybridge({\n name: \"test\",\n version: \"1.0.0\",\n handler: (server) =>\n server.registerTool(\n { name: \"no-input\", description: \"no-input\" },\n async (args, extra) => {\n received = { args, extra };\n return { content: [{ type: \"text\", text: \"ok\" }] };\n },\n ),\n });\n const instance = await app.createServerInstance();\n\n const client = new Client({ name: \"client\", version: \"1.0.0\" });\n const [clientTransport, serverTransport] =\n InMemoryTransport.createLinkedPair();\n await instance.connect(serverTransport);\n await client.connect(clientTransport);\n\n await client.callTool({ name: \"no-input\" });\n\n expect(received?.args).toEqual({});\n expect(received?.extra).toHaveProperty(\"mcpReq.send\");\n\n await client.close();\n await instance.close();\n });\n\n it(\"emits openai options as openai/ui metadata on the tool and its view\", async () => {\n const app = new Skybridge({\n name: \"test\",\n version: \"1.0.0\",\n handler: (server) =>\n server.registerTool(\n {\n name: \"library\",\n description: \"library\",\n view: { component: \"widget\" },\n openai: {\n entrypoints: [\n { type: \"global\" },\n { type: \"file\", extensions: [\".stl\"] },\n ],\n availableDisplayModes: [\"inline\", \"fullscreen\"],\n preferredDisplayMode: \"fullscreen\",\n },\n },\n async () => ({ content: \"ok\" }),\n ),\n });\n const instance = await app.createServerInstance();\n const client = new Client({ name: \"client\", version: \"1.0.0\" });\n const [clientTransport, serverTransport] =\n InMemoryTransport.createLinkedPair();\n await instance.connect(serverTransport);\n await client.connect(clientTransport);\n\n const { tools } = await client.listTools();\n const { resources } = await client.listResources();\n\n expect(tools[0]?._meta?.[\"openai/ui\"]).toEqual({\n entrypoints: [{ type: \"global\" }, { type: \"file\", extensions: [\".stl\"] }],\n });\n expect(resources[0]?._meta?.[\"openai/ui\"]).toEqual({\n availableDisplayModes: [\"inline\", \"fullscreen\"],\n preferredDisplayMode: \"fullscreen\",\n });\n\n await client.close();\n await instance.close();\n });\n\n it(\"rejects a global entrypoint on a tool that requires input\", async () => {\n const app = new Skybridge({\n name: \"test\",\n version: \"1.0.0\",\n handler: (server) =>\n server.registerTool(\n {\n name: \"search\",\n description: \"search\",\n inputSchema: { query: z.string() },\n view: { component: \"widget\" },\n openai: { entrypoints: [{ type: \"global\" }] },\n },\n async () => ({ content: \"ok\" }),\n ),\n });\n\n await expect(app.createServerInstance()).rejects.toThrow(/rejects `\\{\\}`/);\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"register-tool.test.js","sourceRoot":"","sources":["../../src/server/register-tool.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Client, InMemoryTransport } from \"@modelcontextprotocol/client\";\nimport { describe, expect, it } from \"vitest\";\nimport { z } from \"zod\";\nimport { Skybridge } from \"./app.js\";\n\ndescribe(\"registerTool handler invocation\", () => {\n it(\"passes empty args and a usable extra to a schema-less tool handler\", async () => {\n let received: { args: unknown; extra: unknown } | undefined;\n const app = new Skybridge({\n name: \"test\",\n version: \"1.0.0\",\n handler: (server) =>\n server.registerTool(\n { name: \"no-input\", description: \"no-input\" },\n async (args, extra) => {\n received = { args, extra };\n return { content: [{ type: \"text\", text: \"ok\" }] };\n },\n ),\n });\n const instance = await app.createServerInstance();\n\n const client = new Client({ name: \"client\", version: \"1.0.0\" });\n const [clientTransport, serverTransport] =\n InMemoryTransport.createLinkedPair();\n await instance.connect(serverTransport);\n await client.connect(clientTransport);\n\n await client.callTool({ name: \"no-input\" });\n\n expect(received?.args).toEqual({});\n expect(received?.extra).toHaveProperty(\"mcpReq.send\");\n\n await client.close();\n await instance.close();\n });\n\n it(\"emits openai options as openai/ui metadata on the tool and its view\", async () => {\n const app = new Skybridge({\n name: \"test\",\n version: \"1.0.0\",\n handler: (server) =>\n server.registerTool(\n {\n name: \"library\",\n description: \"library\",\n view: { component: \"widget\" },\n openai: {\n entrypoints: [\n { type: \"global\" },\n { type: \"file\", extensions: [\".stl\"] },\n ],\n availableDisplayModes: [\"inline\", \"fullscreen\"],\n preferredDisplayMode: \"fullscreen\",\n },\n },\n async () => ({ content: \"ok\" }),\n ),\n });\n const instance = await app.createServerInstance();\n const client = new Client({ name: \"client\", version: \"1.0.0\" });\n const [clientTransport, serverTransport] =\n InMemoryTransport.createLinkedPair();\n await instance.connect(serverTransport);\n await client.connect(clientTransport);\n\n const { tools } = await client.listTools();\n const { resources } = await client.listResources();\n\n expect(tools[0]?._meta?.[\"openai/ui\"]).toEqual({\n entrypoints: [{ type: \"global\" }, { type: \"file\", extensions: [\".stl\"] }],\n });\n expect(resources[0]?._meta?.[\"openai/ui\"]).toEqual({\n availableDisplayModes: [\"inline\", \"fullscreen\"],\n preferredDisplayMode: \"fullscreen\",\n });\n\n await client.close();\n await instance.close();\n });\n\n it(\"rejects a global entrypoint on a tool that requires input\", async () => {\n const app = new Skybridge({\n name: \"test\",\n version: \"1.0.0\",\n handler: (server) =>\n server.registerTool(\n {\n name: \"search\",\n description: \"search\",\n inputSchema: { query: z.string() },\n view: { component: \"widget\" },\n openai: { entrypoints: [{ type: \"global\" }] },\n },\n async () => ({ content: \"ok\" }),\n ),\n });\n\n await expect(app.createServerInstance()).rejects.toThrow(/rejects `\\{\\}`/);\n });\n\n it(\"registers mention search as an app-only tool advertising the extension\", async () => {\n const app = new Skybridge({\n name: \"test\",\n version: \"1.0.0\",\n handler: (server) =>\n server.registerMentions({\n name: \"search_parts\",\n handler: async ({ query }) => ({\n items: [\n { type: \"resource_link\", uri: `parts://${query}`, name: query },\n ],\n }),\n }),\n });\n const instance = await app.createServerInstance();\n const client = new Client({ name: \"client\", version: \"1.0.0\" });\n const [clientTransport, serverTransport] =\n InMemoryTransport.createLinkedPair();\n await instance.connect(serverTransport);\n await client.connect(clientTransport);\n\n const { tools } = await client.listTools();\n expect(tools[0]?._meta).toMatchObject({\n \"openai/extensions\": { \"mentions/search\": {} },\n ui: { visibility: [\"app\"] },\n });\n const result = await client.callTool({\n name: \"search_parts\",\n arguments: { query: \"bolt\" },\n });\n expect(result.structuredContent).toEqual({\n items: [{ type: \"resource_link\", uri: \"parts://bolt\", name: \"bolt\" }],\n });\n\n await client.close();\n await instance.close();\n });\n\n it(\"registers settings tools and advertises the settings capability\", async () => {\n let stored = { units: \"mm\" as \"mm\" | \"in\", zoom: 3 };\n const fields = {\n units: { title: \"Units\", schema: z.enum([\"mm\", \"in\"]) },\n zoom: { title: \"Zoom\", schema: z.number() },\n };\n const app = new Skybridge({\n name: \"test\",\n version: \"1.0.0\",\n handler: (server) =>\n server.registerSettings({\n fields,\n layout: [\n {\n kind: \"group\",\n title: \"Display\",\n items: [{ kind: \"property\", property: \"units\" }],\n },\n ],\n read: () => stored,\n update: (set) => {\n stored = { ...stored, ...set };\n return stored;\n },\n }),\n });\n const instance = await app.createServerInstance();\n const client = new Client({ name: \"client\", version: \"1.0.0\" });\n const [clientTransport, serverTransport] =\n InMemoryTransport.createLinkedPair();\n await instance.connect(serverTransport);\n await client.connect(clientTransport);\n\n const capability = {\n readTool: \"settings.read\",\n updateTool: \"settings.update\",\n };\n expect(client.getServerCapabilities()).toMatchObject({\n extensions: { \"openai/settings\": capability },\n experimental: { \"openai/settings\": capability },\n });\n const { tools } = await client.listTools();\n expect(tools).toMatchObject([\n {\n name: \"settings.read\",\n annotations: { readOnlyHint: true },\n outputSchema: { required: [\"schema\", \"values\"] },\n },\n {\n name: \"settings.update\",\n inputSchema: {\n properties: {\n set: { additionalProperties: false, minProperties: 1 },\n },\n },\n },\n ]);\n const read = await client.callTool({\n name: \"settings.read\",\n arguments: {},\n });\n expect(read.structuredContent).toMatchObject({\n schema: {\n type: \"object\",\n properties: {\n units: { type: \"string\", enum: [\"mm\", \"in\"], title: \"Units\" },\n zoom: { type: \"number\", title: \"Zoom\" },\n },\n required: [\"units\", \"zoom\"],\n },\n values: { units: \"mm\", zoom: 3 },\n layout: [{ kind: \"group\", title: \"Display\" }],\n });\n const updated = await client.callTool({\n name: \"settings.update\",\n arguments: { set: { units: \"in\" } },\n });\n expect(updated.structuredContent).toEqual({\n values: { units: \"in\", zoom: 3 },\n });\n const empty = await client.callTool({\n name: \"settings.update\",\n arguments: { set: {} },\n });\n expect(empty.isError).toBe(true);\n\n await client.close();\n await instance.close();\n\n const withDefault = new Skybridge({\n name: \"test\",\n version: \"1.0.0\",\n handler: (server) =>\n server.registerSettings({\n fields: {\n grid: { title: \"Grid\", schema: z.boolean().prefault(true) },\n },\n read: () => ({ grid: true }),\n update: () => ({ grid: true }),\n }),\n });\n await expect(withDefault.createServerInstance()).rejects.toThrow(\n /declares a default/,\n );\n });\n\n it(\"registers a file viewer with the file input and a file entrypoint\", async () => {\n const app = new Skybridge({\n name: \"test\",\n version: \"1.0.0\",\n handler: (server) =>\n server.registerFileViewer(\n {\n name: \"part-viewer\",\n extensions: [\".stl\"],\n view: { component: \"widget\" },\n },\n async ({ file }) => ({ content: file.name }),\n ),\n });\n const instance = await app.createServerInstance();\n const client = new Client({ name: \"client\", version: \"1.0.0\" });\n const [clientTransport, serverTransport] =\n InMemoryTransport.createLinkedPair();\n await instance.connect(serverTransport);\n await client.connect(clientTransport);\n\n const { tools } = await client.listTools();\n expect(tools[0]?._meta?.[\"openai/ui\"]).toEqual({\n entrypoints: [{ type: \"file\", extensions: [\".stl\"] }],\n });\n expect(tools[0]?.inputSchema.required).toEqual([\"file\"]);\n\n await client.close();\n await instance.close();\n });\n});\n"]}
|
package/dist/server/server.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { McpUiToolMeta } from "@modelcontextprotocol/ext-apps";
|
|
2
|
-
import { type ContentBlock, type Icon, type Implementation, McpServer as McpServerBase, type RequestMeta, type ServerOptions, type ServerResult, type StandardSchemaV1, type StandardSchemaWithJSON, type ToolAnnotations } from "@modelcontextprotocol/server";
|
|
2
|
+
import { type ContentBlock, type Icon, type Implementation, type InputRequiredResult, McpServer as McpServerBase, type RequestMeta, type ResourceLink, type ServerOptions, type ServerResult, type StandardSchemaV1, type StandardSchemaWithJSON, type ToolAnnotations } from "@modelcontextprotocol/server";
|
|
3
3
|
import type express from "express";
|
|
4
|
+
import { z } from "zod/v4";
|
|
4
5
|
import type { ResourceMetadataUrlResolver } from "./auth/setup.js";
|
|
5
6
|
import type { ExtraClaims } from "./auth.js";
|
|
7
|
+
import { type EventConfig, type EventHooks, type InferEventSchema } from "./events.js";
|
|
6
8
|
import type { McpExtra, McpExtraFor, McpMethodString, McpMiddlewareEntry, McpMiddlewareFilter, McpMiddlewareFn, McpResultFor, McpTypedMiddlewareFn, McpWildcard } from "./middleware.js";
|
|
7
9
|
import { type SkillsManifest } from "./skills.js";
|
|
8
10
|
/**
|
|
@@ -27,7 +29,7 @@ export interface ViewCsp {
|
|
|
27
29
|
resourceDomains?: string[];
|
|
28
30
|
/** Origins the view may contact via fetch/XHR. */
|
|
29
31
|
connectDomains?: string[];
|
|
30
|
-
/** Origins allowed for iframe embeds (opts into stricter
|
|
32
|
+
/** Origins allowed for iframe embeds (opts into stricter plugin review). */
|
|
31
33
|
frameDomains?: string[];
|
|
32
34
|
/** Origins that can receive openExternal redirects without the safe-link modal. */
|
|
33
35
|
redirectDomains?: string[];
|
|
@@ -171,16 +173,16 @@ export interface SkybridgeServerOptions {
|
|
|
171
173
|
* Well-known keys recognized by host runtimes when set on a tool's `_meta`.
|
|
172
174
|
* Use {@link ToolMeta} to also pass arbitrary custom metadata alongside these.
|
|
173
175
|
*
|
|
174
|
-
* @see https://developers.openai.com/
|
|
176
|
+
* @see https://developers.openai.com/plugins/reference#tool-descriptor-parameters
|
|
175
177
|
*/
|
|
176
178
|
export interface KnownToolMeta {
|
|
177
|
-
/**
|
|
179
|
+
/** ChatGPT: allow the rendered view to call this tool from inside its iframe. */
|
|
178
180
|
"openai/widgetAccessible"?: boolean;
|
|
179
|
-
/**
|
|
181
|
+
/** ChatGPT: status text shown while the tool is running (e.g. `"Searching trips"`). */
|
|
180
182
|
"openai/toolInvocation/invoking"?: string;
|
|
181
|
-
/**
|
|
183
|
+
/** ChatGPT: status text shown once the tool returns (e.g. `"Found 3 trips"`). */
|
|
182
184
|
"openai/toolInvocation/invoked"?: string;
|
|
183
|
-
/**
|
|
185
|
+
/** ChatGPT: input parameters that hold file references — the host attaches uploaded files to them. */
|
|
184
186
|
"openai/fileParams"?: string[];
|
|
185
187
|
/** MCP Apps: control whether the tool is exposed to the model, the app, or both. */
|
|
186
188
|
ui?: Pick<McpUiToolMeta, "visibility">;
|
|
@@ -264,11 +266,27 @@ type ToolAuthConfig = {
|
|
|
264
266
|
securitySchemes?: SecurityScheme[];
|
|
265
267
|
};
|
|
266
268
|
type ToolConfig<TInput extends Record<string, StandardSchemaWithJSON> | StandardSchemaWithJSON> = ToolConfigBase<TInput> & ToolAuthConfig;
|
|
269
|
+
declare const fileEntrypointInput: {
|
|
270
|
+
file: z.ZodObject<{
|
|
271
|
+
name: z.ZodString;
|
|
272
|
+
resourceUri: z.ZodString;
|
|
273
|
+
}, z.core.$strip>;
|
|
274
|
+
};
|
|
275
|
+
type FileEntrypointInput = typeof fileEntrypointInput;
|
|
276
|
+
/** A ChatGPT file viewer, registered with `server.registerFileViewer`. */
|
|
277
|
+
export type OpenAIFileViewerConfig<TName extends string = string> = Omit<ToolConfigBase<FileEntrypointInput>, "inputSchema" | "openai" | "view"> & ToolAuthConfig & {
|
|
278
|
+
name: TName;
|
|
279
|
+
/** File extensions the viewer opens, each starting with `.`. */
|
|
280
|
+
extensions: string[];
|
|
281
|
+
view: ViewConfig;
|
|
282
|
+
/** Display modes. The file entrypoint is set from `extensions`. */
|
|
283
|
+
openai?: Omit<OpenAIToolConfig, "entrypoints">;
|
|
284
|
+
};
|
|
267
285
|
/**
|
|
268
286
|
* Optional client-supplied hints attached to `params._meta` on every tool call
|
|
269
|
-
* by the
|
|
287
|
+
* by the ChatGPT host. Hints only: never use for authorization, and tolerate
|
|
270
288
|
* absence.
|
|
271
|
-
* @see https://developers.openai.com/
|
|
289
|
+
* @see https://developers.openai.com/plugins/reference#_meta-fields-the-client-provides
|
|
272
290
|
*/
|
|
273
291
|
export interface ClientHintsMeta {
|
|
274
292
|
/** Requested locale (BCP-47, e.g. `"en-US"`). */
|
|
@@ -307,11 +325,62 @@ type ToolHandlerExtra<TAuthExtra extends ExtraClaims = ExtraClaims> = Omit<McpEx
|
|
|
307
325
|
_meta?: RequestMeta & ClientHintsMeta;
|
|
308
326
|
};
|
|
309
327
|
};
|
|
328
|
+
/** Composer at-mention search, registered with `server.registerMentions`. */
|
|
329
|
+
export interface OpenAIMentionsConfig<TAuthExtra extends ExtraClaims = ExtraClaims> {
|
|
330
|
+
/** Name of the tool ChatGPT calls for each search. */
|
|
331
|
+
name: string;
|
|
332
|
+
description?: string;
|
|
333
|
+
/** Returns the items matching the typed text, which may be empty. */
|
|
334
|
+
handler: (params: {
|
|
335
|
+
query: string;
|
|
336
|
+
}, extra: ToolHandlerExtra<TAuthExtra>) => Promise<{
|
|
337
|
+
items: ResourceLink[];
|
|
338
|
+
}> | {
|
|
339
|
+
items: ResourceLink[];
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
/** One setting, registered with `server.registerSettings`. */
|
|
343
|
+
export interface OpenAISettingsField {
|
|
344
|
+
/** A boolean, string, string enum, number or integer schema, without a default. */
|
|
345
|
+
schema: z.ZodType<boolean | string | number>;
|
|
346
|
+
title: string;
|
|
347
|
+
description?: string;
|
|
348
|
+
}
|
|
349
|
+
/** Values of every setting, keyed by field name. */
|
|
350
|
+
export type OpenAISettingsValues<TFields extends Record<string, OpenAISettingsField>> = {
|
|
351
|
+
[K in keyof TFields]-?: Exclude<z.output<TFields[K]["schema"]>, undefined>;
|
|
352
|
+
};
|
|
353
|
+
/** App settings in ChatGPT, registered with `server.registerSettings`. */
|
|
354
|
+
export interface OpenAISettingsConfig<TFields extends Record<string, OpenAISettingsField>, TAuthExtra extends ExtraClaims = ExtraClaims> {
|
|
355
|
+
fields: TFields;
|
|
356
|
+
/** Sections of the settings page. Fields left out appear under "Other settings". */
|
|
357
|
+
layout?: {
|
|
358
|
+
kind: "group";
|
|
359
|
+
title: string;
|
|
360
|
+
items: ({
|
|
361
|
+
kind: "property";
|
|
362
|
+
property: Extract<keyof TFields, string>;
|
|
363
|
+
} | {
|
|
364
|
+
kind: "tool";
|
|
365
|
+
tool: string;
|
|
366
|
+
title: string;
|
|
367
|
+
description?: string;
|
|
368
|
+
})[];
|
|
369
|
+
}[];
|
|
370
|
+
/** Returns the current value of every field. */
|
|
371
|
+
read: (extra: ToolHandlerExtra<TAuthExtra>) => OpenAISettingsValues<TFields> | Promise<OpenAISettingsValues<TFields>>;
|
|
372
|
+
/** Saves the changed fields and returns the value of every field. */
|
|
373
|
+
update: (set: Partial<OpenAISettingsValues<TFields>>, extra: ToolHandlerExtra<TAuthExtra>) => OpenAISettingsValues<TFields> | Promise<OpenAISettingsValues<TFields>>;
|
|
374
|
+
/** Name of the read tool. Defaults to `settings.read`. */
|
|
375
|
+
readTool?: string;
|
|
376
|
+
/** Name of the update tool. Defaults to `settings.update`. */
|
|
377
|
+
updateTool?: string;
|
|
378
|
+
}
|
|
310
379
|
type ToolHandler<TInput extends Record<string, StandardSchemaWithJSON>, TReturn extends {
|
|
311
380
|
content?: HandlerContent;
|
|
312
381
|
} = {
|
|
313
382
|
content?: HandlerContent;
|
|
314
|
-
}, TAuthExtra extends ExtraClaims = ExtraClaims> = (args: ShapeOutput<TInput>, extra: ToolHandlerExtra<TAuthExtra>) => TReturn | Promise<TReturn>;
|
|
383
|
+
}, TAuthExtra extends ExtraClaims = ExtraClaims> = (args: ShapeOutput<TInput>, extra: ToolHandlerExtra<TAuthExtra>) => TReturn | InputRequiredResult | Promise<TReturn | InputRequiredResult>;
|
|
315
384
|
/**
|
|
316
385
|
* Coerce a tool handler's return value into an MCP `content` array. Strings
|
|
317
386
|
* become a single `TextContent`; a single block is wrapped in an array;
|
|
@@ -379,6 +448,7 @@ export declare class McpServer<TTools extends Record<string, ToolDef> = Record<n
|
|
|
379
448
|
private resolveResourceMetadataUrl?;
|
|
380
449
|
private readonly toolSecuritySchemes;
|
|
381
450
|
private readonly userMiddlewareEntries;
|
|
451
|
+
private eventRegistry?;
|
|
382
452
|
constructor(serverInfo: Implementation, options?: ServerOptions, skybridgeOptions?: SkybridgeServerOptions);
|
|
383
453
|
/**
|
|
384
454
|
* The per-tool security schemes collected during registration, keyed by tool
|
|
@@ -444,6 +514,7 @@ export declare class McpServer<TTools extends Record<string, ToolDef> = Record<n
|
|
|
444
514
|
private decorateToolHandler;
|
|
445
515
|
private computeViewVersionParam;
|
|
446
516
|
private lookupViewFile;
|
|
517
|
+
private lookupViewPreloadFiles;
|
|
447
518
|
private lookupDistFile;
|
|
448
519
|
/**
|
|
449
520
|
* Inject the Vite manifest as a value rather than letting `readManifest()`
|
|
@@ -455,6 +526,104 @@ export declare class McpServer<TTools extends Record<string, ToolDef> = Record<n
|
|
|
455
526
|
file: string;
|
|
456
527
|
}>): this;
|
|
457
528
|
private readManifest;
|
|
529
|
+
/**
|
|
530
|
+
* @experimental Register an MCP Events type that hosts can subscribe to, per
|
|
531
|
+
* the Triggers & Events working group draft. Skybridge serves `events/list`,
|
|
532
|
+
* `events/subscribe` and `events/unsubscribe`, checks auth and arguments,
|
|
533
|
+
* verifies the callback URL, then hands each subscription to `onSubscribe`.
|
|
534
|
+
* Delivering the events is up to you, for example with {@link deliverEvent}.
|
|
535
|
+
* API may change.
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```ts
|
|
539
|
+
* server.registerEvent(
|
|
540
|
+
* {
|
|
541
|
+
* name: "comment.created",
|
|
542
|
+
* description: "Fires when someone comments on a document",
|
|
543
|
+
* inputSchema: { documentId: z.string() },
|
|
544
|
+
* payloadSchema: { documentId: z.string(), excerpt: z.string() },
|
|
545
|
+
* },
|
|
546
|
+
* {
|
|
547
|
+
* onSubscribe: ({ documentId }, { subscription }) =>
|
|
548
|
+
* webhooks.upsert({ ...subscription, filter: { documentId } }),
|
|
549
|
+
* onUnsubscribe: (_args, { subscription }) =>
|
|
550
|
+
* webhooks.remove(subscription.id),
|
|
551
|
+
* },
|
|
552
|
+
* );
|
|
553
|
+
* ```
|
|
554
|
+
*
|
|
555
|
+
* @see https://docs.skybridge.tech/api-reference/register-event
|
|
556
|
+
*/
|
|
557
|
+
registerEvent<TInput extends Record<string, StandardSchemaWithJSON> | StandardSchemaWithJSON = Record<never, StandardSchemaWithJSON>>(config: EventConfig<TInput>, hooks: EventHooks<InferEventSchema<TInput>, McpExtra<TAuthExtra>>): this;
|
|
558
|
+
/**
|
|
559
|
+
* Register a ChatGPT file viewer, from the OpenAI MCP extensions: a tool
|
|
560
|
+
* with a file entrypoint for `extensions` and a view. ChatGPT desktop calls
|
|
561
|
+
* it with the file the user opened, as `{ file: { name, resourceUri } }`.
|
|
562
|
+
* Read and save the file from the view with `useFileResource`.
|
|
563
|
+
*
|
|
564
|
+
* @example
|
|
565
|
+
* ```ts
|
|
566
|
+
* server.registerFileViewer(
|
|
567
|
+
* {
|
|
568
|
+
* name: "part-viewer",
|
|
569
|
+
* title: "Part Viewer",
|
|
570
|
+
* extensions: [".stl", ".step"],
|
|
571
|
+
* view: { component: "part-viewer" },
|
|
572
|
+
* },
|
|
573
|
+
* async ({ file }) => ({ structuredContent: { name: file.name } }),
|
|
574
|
+
* );
|
|
575
|
+
* ```
|
|
576
|
+
*
|
|
577
|
+
* @see https://docs.skybridge.tech/api-reference/register-file-viewer
|
|
578
|
+
*/
|
|
579
|
+
registerFileViewer<TName extends string, TReturn extends {
|
|
580
|
+
content?: HandlerContent;
|
|
581
|
+
}>(config: OpenAIFileViewerConfig<TName>, cb: ToolHandler<FileEntrypointInput, TReturn, TAuthExtra>): AddTool<TTools, TName, FileEntrypointInput, ExtractStructuredContent<TReturn>, ExtractMeta<TReturn>, TAuthExtra>;
|
|
582
|
+
/**
|
|
583
|
+
* Register the composer at-mention search for ChatGPT, from the OpenAI MCP
|
|
584
|
+
* extensions. When the user types `@` and your app name, ChatGPT calls
|
|
585
|
+
* `handler` with the typed text and lists the returned resource links.
|
|
586
|
+
* Skybridge registers it as a tool hidden from the model.
|
|
587
|
+
*
|
|
588
|
+
* @example
|
|
589
|
+
* ```ts
|
|
590
|
+
* server.registerMentions({
|
|
591
|
+
* name: "search_parts",
|
|
592
|
+
* handler: async ({ query }) => ({
|
|
593
|
+
* items: findParts(query).map((part) => ({
|
|
594
|
+
* type: "resource_link",
|
|
595
|
+
* uri: `parts://${part.id}`,
|
|
596
|
+
* name: part.name,
|
|
597
|
+
* })),
|
|
598
|
+
* }),
|
|
599
|
+
* });
|
|
600
|
+
* ```
|
|
601
|
+
*
|
|
602
|
+
* @see https://docs.skybridge.tech/api-reference/register-mentions
|
|
603
|
+
*/
|
|
604
|
+
registerMentions(config: OpenAIMentionsConfig<TAuthExtra>): this;
|
|
605
|
+
/**
|
|
606
|
+
* Register app settings for ChatGPT, from the OpenAI MCP extensions.
|
|
607
|
+
* Skybridge registers a read tool and an update tool from `fields`, and
|
|
608
|
+
* advertises them in the `openai/settings` server capability. ChatGPT shows
|
|
609
|
+
* the settings page and calls `update` with the changed fields only. Store
|
|
610
|
+
* the values yourself, for example per user.
|
|
611
|
+
*
|
|
612
|
+
* @example
|
|
613
|
+
* ```ts
|
|
614
|
+
* server.registerSettings({
|
|
615
|
+
* fields: {
|
|
616
|
+
* units: { title: "Units", schema: z.enum(["mm", "in"]) },
|
|
617
|
+
* showGrid: { title: "Show grid", schema: z.boolean() },
|
|
618
|
+
* },
|
|
619
|
+
* read: (extra) => loadSettings(extra),
|
|
620
|
+
* update: (set, extra) => saveSettings(set, extra),
|
|
621
|
+
* });
|
|
622
|
+
* ```
|
|
623
|
+
*
|
|
624
|
+
* @see https://docs.skybridge.tech/api-reference/register-settings
|
|
625
|
+
*/
|
|
626
|
+
registerSettings<TFields extends Record<string, OpenAISettingsField>>(config: OpenAISettingsConfig<TFields, TAuthExtra>): this;
|
|
458
627
|
/**
|
|
459
628
|
* Register a tool. Pass a `config` describing the tool (name, schemas,
|
|
460
629
|
* optional {@link ViewConfig}, optional {@link ToolMeta}) and a handler that
|