@mcp-b/webmcp-ts-sdk 4.0.0 → 5.0.0
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 +57 -210
- package/dist/index.d.ts +57 -205
- package/dist/index.js +392 -609
- package/dist/index.js.map +1 -1
- package/package.json +14 -25
- package/dist/index.d.ts.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["BaseMcpServer","CfWorkerJsonSchemaValidator","mergeCapabilities","ListToolsRequestSchema","CallToolRequestSchema","ListPromptsRequestSchema","GetPromptRequestSchema"],"sources":["../src/browser-server.ts","../src/no-op-validator.ts"],"sourcesContent":["import type {\n InputSchema,\n JsonSchemaForInference,\n ModelContextClient,\n ModelContextCore,\n ModelContextExtensions,\n ModelContextRegisterToolOptions,\n ModelContextTestingExecuteToolOptions,\n ModelContextToolInfo,\n ModelContextToolReference,\n ResourceContents,\n ToolDescriptor,\n ToolListItem,\n ToolResponse,\n} from '@mcp-b/webmcp-types';\nimport { toJsonValue } from '@mcp-b/webmcp-polyfill/schema';\nimport type { ServerOptions } from '@modelcontextprotocol/sdk/server/index.js';\nimport { McpServer as BaseMcpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n getParseErrorMessage,\n normalizeObjectSchema,\n safeParseAsync,\n} from '@modelcontextprotocol/sdk/server/zod-compat.js';\nimport { toJsonSchemaCompat } from '@modelcontextprotocol/sdk/server/zod-json-schema-compat.js';\nimport type { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport { mergeCapabilities } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport { validateAndWarnToolName } from '@modelcontextprotocol/sdk/shared/toolNameValidation.js';\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport type { jsonSchemaValidator } from '@modelcontextprotocol/sdk/validation';\nimport { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/sdk/validation/cfworker';\nimport type {\n CallToolResult as McpCallToolResult,\n CreateMessageRequest,\n CreateMessageResult,\n ElicitRequest,\n ElicitResult,\n Implementation,\n PromptMessage,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n CallToolRequestSchema,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nconst DEFAULT_INPUT_SCHEMA: InputSchema = { type: 'object', properties: {} };\nconst DEFAULT_CLIENT_REQUEST_TIMEOUT = 10_000;\n\nexport const SERVER_MARKER_PROPERTY = '__isBrowserMcpServer' as const;\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isCallToolResult(value: unknown): value is ToolResponse {\n return isPlainObject(value) && Array.isArray(value.content);\n}\n\nfunction isPermissionsPolicySecurityError(error: unknown): boolean {\n if (!error || typeof error !== 'object') {\n return false;\n }\n\n const { name, message } = error as { name?: unknown; message?: unknown };\n\n return (\n name === 'SecurityError' &&\n typeof message === 'string' &&\n /permissions policy|feature \"tools\" is disallowed/i.test(message)\n );\n}\n\nfunction isAbortError(error: unknown): boolean {\n return (\n Boolean(error) &&\n typeof error === 'object' &&\n (error as { name?: unknown }).name === 'AbortError'\n );\n}\n\nfunction createAbortError(): Error {\n if (typeof DOMException === 'function') {\n return new DOMException('signal is aborted without reason', 'AbortError');\n }\n\n const error = new Error('signal is aborted without reason');\n error.name = 'AbortError';\n return error;\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n Boolean(value) &&\n (typeof value === 'object' || typeof value === 'function') &&\n typeof (value as { then?: unknown }).then === 'function'\n );\n}\n\nfunction serializeTextContent(value: unknown): string {\n if (typeof value === 'string') {\n return value;\n }\n\n try {\n const candidate = JSON.stringify(value);\n return candidate ?? String(value);\n } catch {\n return String(value);\n }\n}\n\nfunction normalizeToolResponse(value: unknown): ToolResponse {\n if (isCallToolResult(value)) {\n return value;\n }\n\n const structuredContent = toJsonValue(value);\n\n return {\n content: [{ type: 'text', text: serializeTextContent(value) }],\n ...(structuredContent !== undefined ? { structuredContent } : {}),\n isError: false,\n };\n}\n\nfunction parseNativeToolInputSchema(inputSchema: string | undefined): InputSchema {\n if (!inputSchema) {\n return DEFAULT_INPUT_SCHEMA;\n }\n\n try {\n const parsed = JSON.parse(inputSchema) as unknown;\n if (isPlainObject(parsed)) {\n return parsed as InputSchema;\n }\n } catch {\n // Fall through to the default schema. Native previews have returned invalid\n // schema strings during development; a bad imported tool schema should not\n // prevent the wrapper from initializing.\n }\n\n return DEFAULT_INPUT_SCHEMA;\n}\n\nfunction toToolListItemFromNativeToolInfo(tool: ModelContextToolInfo): ToolListItem {\n return {\n name: tool.name,\n description: tool.description ?? '',\n inputSchema: parseNativeToolInputSchema(tool.inputSchema),\n };\n}\n\nfunction parseNativeToolResult(toolName: string, serialized: string | null): ToolResponse {\n if (serialized === null) {\n return {\n content: [{ type: 'text', text: 'Tool execution interrupted by navigation' }],\n isError: true,\n };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(serialized);\n } catch (parseError) {\n throw new Error(\n `Failed to parse serialized tool response for ${toolName}: ${parseError instanceof Error ? parseError.message : String(parseError)}`\n );\n }\n\n return normalizeToolResponse(parsed);\n}\n\nfunction withDefaultTimeout(options?: RequestOptions): RequestOptions {\n if (options?.signal) return options;\n return { ...options, signal: AbortSignal.timeout(DEFAULT_CLIENT_REQUEST_TIMEOUT) };\n}\n\ninterface RegisteredWebMcpTool {\n title?: string;\n description?: string;\n inputSchema: InputSchema;\n outputSchema?: JsonSchemaForInference;\n annotations?: ToolListItem['annotations'];\n handler: (args: Record<string, unknown>) => Promise<ToolResponse>;\n}\n\ninterface ParentRegisteredResource {\n name: string;\n metadata?: { description?: string; mimeType?: string; title?: string };\n readCallback: (uri: URL, extra: unknown) => Promise<{ contents: ResourceContents[] }>;\n enabled: boolean;\n remove: () => void;\n}\n\ninterface ParentRegisteredPrompt {\n title?: string;\n description?: string;\n argsSchema?: unknown;\n callback: (\n args: Record<string, unknown>,\n extra: unknown\n ) => Promise<{ messages: PromptMessage[] }>;\n enabled: boolean;\n remove: () => void;\n}\n\nexport interface BrowserMcpServerOptions extends ServerOptions {\n native?: ModelContextCore;\n}\n\ntype ParentRegisterResourceFn = (\n name: string,\n uri: string,\n config: Record<string, unknown>,\n cb: (uri: URL, extra: unknown) => Promise<{ contents: ResourceContents[] }>\n) => { remove: () => void };\n\ntype ParentRegisterPromptFn = (\n name: string,\n config: Record<string, unknown>,\n cb: (args: Record<string, unknown>, extra: unknown) => Promise<{ messages: PromptMessage[] }>\n) => { remove: () => void };\n\ntype NativeLegacyToolsApi = ModelContextCore &\n Pick<ModelContextExtensions, 'listTools' | 'callTool'>;\ntype NativeStandardToolsApi = Pick<ModelContextCore, 'getTools' | 'executeTool'>;\ntype MaybePromise<T> = T | PromiseLike<T>;\ntype NativeRegisterToolFn = (\n tool: ToolDescriptor,\n options?: ModelContextRegisterToolOptions\n) => MaybePromise<void>;\ntype NativeUnregisterToolFn = (nameOrTool: string | ModelContextToolReference) => void;\ninterface NativeToolCleanup {\n abort: () => void;\n nativeSignalAccepted: boolean;\n}\n\n/**\n * Browser-optimized MCP Server that speaks WebMCP natively.\n *\n * Implements `registerTool(tool, options?)` while retaining MCP capabilities\n * (resources, prompts, elicitation, sampling) via BaseMcpServer.\n *\n * Deprecated compatibility (kept for Chrome Beta 147 and existing wrappers,\n * removed in the next major): `unregisterTool(name)`.\n *\n * When `native` is provided, tool operations are mirrored so that\n * navigator.modelContextTesting stays in sync.\n */\nexport class BrowserMcpServer extends BaseMcpServer {\n readonly [SERVER_MARKER_PROPERTY] = true as const;\n\n private native: ModelContextCore | undefined;\n private _promptSchemas = new Map<string, InputSchema>();\n private _jsonValidator: jsonSchemaValidator;\n private _publicMethodsBound = false;\n private _unregisterToolDeprecationWarned = false;\n private _nativeToolCleanups = new Map<string, NativeToolCleanup>();\n private _tools = new Map<string, RegisteredWebMcpTool>();\n private _producerEventTarget = new EventTarget();\n private _ontoolchange: ((this: ModelContextCore, ev: Event) => unknown) | null = null;\n private _producerToolsChangedQueued = false;\n\n constructor(serverInfo: Implementation, options?: BrowserMcpServerOptions) {\n const validator = options?.jsonSchemaValidator ?? new CfWorkerJsonSchemaValidator();\n const enhancedOptions: ServerOptions = {\n capabilities: mergeCapabilities(options?.capabilities || {}, {\n tools: { listChanged: true },\n resources: { listChanged: true },\n prompts: { listChanged: true },\n }),\n jsonSchemaValidator: validator,\n };\n\n super(serverInfo, enhancedOptions);\n this._jsonValidator = validator;\n this.native = options?.native;\n this.bindPublicApiMethods();\n this.installToolRequestHandlers();\n }\n\n /**\n * navigator.modelContext consumers may destructure methods (e.g. const { registerTool } = ...).\n * Bind methods once so they remain callable outside instance-method invocation syntax.\n */\n private bindPublicApiMethods(): void {\n if (this._publicMethodsBound) {\n return;\n }\n\n this.registerTool = this.registerTool.bind(this);\n this.unregisterTool = this.unregisterTool.bind(this);\n this.listTools = this.listTools.bind(this);\n this.getTools = this.getTools.bind(this);\n this.callTool = this.callTool.bind(this);\n this.executeTool = this.executeTool.bind(this);\n this.addEventListener = this.addEventListener.bind(this);\n this.removeEventListener = this.removeEventListener.bind(this);\n this.dispatchEvent = this.dispatchEvent.bind(this);\n\n this.registerResource = this.registerResource.bind(this);\n this.listResources = this.listResources.bind(this);\n this.readResource = this.readResource.bind(this);\n\n this.registerPrompt = this.registerPrompt.bind(this);\n this.listPrompts = this.listPrompts.bind(this);\n this.getPrompt = this.getPrompt.bind(this);\n\n this.createMessage = this.createMessage.bind(this);\n this.elicitInput = this.elicitInput.bind(this);\n\n this._publicMethodsBound = true;\n }\n\n private get _parentResources(): Record<string, ParentRegisteredResource> {\n return (this as unknown as { _registeredResources: Record<string, ParentRegisteredResource> })\n ._registeredResources;\n }\n\n private get _parentPrompts(): Record<string, ParentRegisteredPrompt> {\n return (this as unknown as { _registeredPrompts: Record<string, ParentRegisteredPrompt> })\n ._registeredPrompts;\n }\n\n private toJsonSchema(schema: unknown, pipeStrategy: 'input' | 'output'): Record<string, unknown> {\n if (!schema || typeof schema !== 'object') {\n return {};\n }\n\n const normalized = normalizeObjectSchema(schema as Parameters<typeof normalizeObjectSchema>[0]);\n return normalized\n ? (toJsonSchemaCompat(normalized, {\n strictUnions: true,\n pipeStrategy,\n }) as unknown as Record<string, unknown>)\n : (schema as Record<string, unknown>);\n }\n\n private toInputTransportSchema(schema: unknown): InputSchema {\n const jsonSchema = this.toJsonSchema(schema, 'input');\n\n if (Object.keys(jsonSchema).length === 0) {\n return DEFAULT_INPUT_SCHEMA;\n }\n\n if (jsonSchema.type === undefined) {\n return { type: 'object', ...jsonSchema } as InputSchema;\n }\n\n return jsonSchema as InputSchema;\n }\n\n private toOutputTransportSchema(schema: unknown): JsonSchemaForInference {\n return this.toJsonSchema(schema, 'output') as unknown as JsonSchemaForInference;\n }\n\n private isZodSchema(schema: unknown): boolean {\n if (!schema || typeof schema !== 'object') return false;\n const s = schema as Record<string, unknown>;\n return '_zod' in s || '_def' in s;\n }\n\n private getNativeLegacyToolsApi(): NativeLegacyToolsApi | undefined {\n if (!this.native) {\n return undefined;\n }\n\n const candidate = this.native as ModelContextCore &\n Partial<Pick<ModelContextExtensions, 'listTools' | 'callTool'>>;\n if (typeof candidate.listTools !== 'function' || typeof candidate.callTool !== 'function') {\n return undefined;\n }\n\n return candidate as NativeLegacyToolsApi;\n }\n\n private getNativeStandardToolsApi(): NativeStandardToolsApi | undefined {\n if (!this.native) {\n return undefined;\n }\n\n const candidate = this.native as Partial<NativeStandardToolsApi>;\n if (typeof candidate.getTools !== 'function' || typeof candidate.executeTool !== 'function') {\n return undefined;\n }\n\n return candidate as NativeStandardToolsApi;\n }\n\n private getNativeUnregisterTool(): NativeUnregisterToolFn | undefined {\n if (!this.native) {\n return undefined;\n }\n\n const unregisterTool = (this.native as { unregisterTool?: unknown }).unregisterTool;\n if (typeof unregisterTool !== 'function') {\n return undefined;\n }\n\n return (nameOrTool: string | ModelContextToolReference) =>\n unregisterTool.call(this.native, nameOrTool);\n }\n\n private createNativeToolCleanup(signal?: AbortSignal): {\n options: ModelContextRegisterToolOptions;\n abort: () => void;\n } {\n const controller = new AbortController();\n let removeSignalListener: (() => void) | undefined;\n\n if (signal) {\n const abortNativeSignal = () => {\n controller.abort();\n };\n\n if (signal.aborted) {\n abortNativeSignal();\n } else {\n signal.addEventListener('abort', abortNativeSignal, { once: true });\n removeSignalListener = () => signal.removeEventListener('abort', abortNativeSignal);\n }\n }\n\n return {\n options: { signal: controller.signal },\n abort: () => {\n removeSignalListener?.();\n if (!controller.signal.aborted) {\n controller.abort();\n }\n },\n };\n }\n\n private registerNativeToolMirror(\n tool: ToolDescriptor,\n signal?: AbortSignal\n ): NativeToolCleanup | undefined {\n if (!this.native) {\n return undefined;\n }\n\n const nativeRegister = this.native.registerTool as NativeRegisterToolFn;\n const nativeUnregisterTool = this.getNativeUnregisterTool();\n const shouldPassSignal = Boolean(signal) || !nativeUnregisterTool;\n const cleanup = shouldPassSignal ? this.createNativeToolCleanup(signal) : undefined;\n let nativeRegisterResult: MaybePromise<void>;\n\n try {\n if (cleanup) {\n nativeRegisterResult = nativeRegister.call(this.native, tool, cleanup.options);\n } else {\n nativeRegisterResult = nativeRegister.call(this.native, tool);\n }\n } catch (error) {\n cleanup?.abort();\n if (isPermissionsPolicySecurityError(error)) {\n console.warn(\n '[BrowserMcpServer] Native WebMCP tool mirror is blocked by permissions policy; continuing with WebMCP transport registration only.'\n );\n return undefined;\n }\n throw error;\n }\n\n if (!cleanup) {\n return undefined;\n }\n\n const nativeToolCleanup = {\n abort: cleanup.abort,\n // Web IDL optional arguments may not increase function.length. When\n // unregisterTool is absent, the signal is the only native cleanup path.\n nativeSignalAccepted: nativeRegister.length >= 2 || !nativeUnregisterTool,\n };\n this._nativeToolCleanups.set(tool.name, nativeToolCleanup);\n\n if (isPromiseLike(nativeRegisterResult)) {\n nativeRegisterResult.then(undefined, (error: unknown) => {\n cleanup.abort();\n if (this._nativeToolCleanups.get(tool.name) === nativeToolCleanup) {\n this._nativeToolCleanups.delete(tool.name);\n }\n\n if (isPermissionsPolicySecurityError(error)) {\n console.warn(\n '[BrowserMcpServer] Native WebMCP tool mirror is blocked by permissions policy; continuing with WebMCP transport registration only.'\n );\n return;\n }\n\n if (isAbortError(error)) {\n return;\n }\n\n console.warn(\n '[BrowserMcpServer] Native WebMCP tool mirror registration rejected; continuing with WebMCP transport registration only.',\n error\n );\n });\n }\n\n return nativeToolCleanup;\n }\n\n private unregisterNativeToolMirror(\n name: string,\n options?: { preferAbortSignal?: boolean }\n ): void {\n const cleanup = this._nativeToolCleanups.get(name);\n this._nativeToolCleanups.delete(name);\n\n const nativeUnregisterTool = this.getNativeUnregisterTool();\n const shouldUseAbortOnly = options?.preferAbortSignal && cleanup?.nativeSignalAccepted === true;\n\n if (shouldUseAbortOnly || !nativeUnregisterTool) {\n cleanup?.abort();\n return;\n }\n\n try {\n nativeUnregisterTool(name);\n } finally {\n cleanup?.abort();\n }\n }\n\n private installToolRequestHandlers(): void {\n this.server.setRequestHandler(ListToolsRequestSchema, () => ({\n tools: this.listToolsForMcpTransport(),\n }));\n\n this.server.setRequestHandler(CallToolRequestSchema, async (request) => {\n try {\n const params =\n request.params.arguments === undefined\n ? { name: request.params.name }\n : {\n name: request.params.name,\n arguments: request.params.arguments,\n };\n const result = await this.callTool(params);\n return this.toMcpCallToolResult(result);\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: error instanceof Error ? error.message : String(error),\n },\n ],\n isError: true,\n } satisfies McpCallToolResult;\n }\n });\n }\n\n private registerToolInServer(tool: ToolDescriptor): void {\n validateAndWarnToolName(tool.name);\n\n const inputSchema = this.toInputTransportSchema(tool.inputSchema);\n const outputSchema = tool.outputSchema\n ? this.toOutputTransportSchema(tool.outputSchema)\n : undefined;\n\n if (this._tools.has(tool.name)) {\n throw new Error(`Tool ${tool.name} is already registered`);\n }\n\n const registeredTool: RegisteredWebMcpTool = {\n ...(tool.title ? { title: tool.title } : {}),\n description: tool.description,\n inputSchema,\n ...(outputSchema ? { outputSchema } : {}),\n ...(tool.annotations ? { annotations: tool.annotations } : {}),\n handler: async (args: Record<string, unknown>) => {\n const client: ModelContextClient = {\n requestUserInteraction: async (cb: () => Promise<unknown>) => cb(),\n };\n return normalizeToolResponse(await tool.execute(args, client));\n },\n };\n\n this._tools.set(tool.name, registeredTool);\n this.sendToolListChanged();\n this.notifyProducerToolsChanged();\n }\n\n get ontoolchange(): ((this: ModelContextCore, ev: Event) => unknown) | null {\n return this._ontoolchange;\n }\n\n set ontoolchange(handler: ((this: ModelContextCore, ev: Event) => unknown) | null) {\n this._ontoolchange = handler;\n }\n\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | AddEventListenerOptions\n ): void {\n this._producerEventTarget.addEventListener(type, listener, options);\n }\n\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | EventListenerOptions\n ): void {\n this._producerEventTarget.removeEventListener(type, listener, options);\n }\n\n dispatchEvent(event: Event): boolean {\n return this._producerEventTarget.dispatchEvent(event);\n }\n\n private notifyProducerToolsChanged(): void {\n if (this._producerToolsChangedQueued) {\n return;\n }\n this._producerToolsChangedQueued = true;\n\n queueMicrotask(() => {\n this._producerToolsChangedQueued = false;\n const event = new Event('toolchange');\n try {\n this._ontoolchange?.call(this as unknown as ModelContextCore, event);\n } catch (error) {\n console.warn(\n '[BrowserMcpServer] navigator.modelContext.ontoolchange handler threw:',\n error\n );\n }\n this.dispatchEvent(event);\n });\n }\n\n backfillTools(\n tools: readonly ToolListItem[],\n execute: (name: string, args: Record<string, unknown>) => Promise<ToolResponse>\n ): number {\n let synced = 0;\n\n for (const sourceTool of tools) {\n if (!sourceTool?.name || this._tools.has(sourceTool.name)) {\n continue;\n }\n\n const toolDescriptor: ToolDescriptor = {\n name: sourceTool.name,\n description: sourceTool.description ?? '',\n inputSchema: sourceTool.inputSchema ?? DEFAULT_INPUT_SCHEMA,\n execute: async (args: Record<string, unknown>) => execute(sourceTool.name, args),\n };\n\n if (sourceTool.outputSchema) {\n toolDescriptor.outputSchema = sourceTool.outputSchema;\n }\n if (sourceTool.annotations) {\n toolDescriptor.annotations = sourceTool.annotations;\n }\n\n this.registerToolInServer(toolDescriptor);\n synced++;\n }\n\n return synced;\n }\n\n // --- WebMCP standard API (primary surface) ---\n\n // @ts-expect-error -- WebMCP API: (ToolDescriptor, options?) vs MCP SDK: (name, config, cb)\n override registerTool(\n tool: ToolDescriptor,\n options?: ModelContextRegisterToolOptions\n ): Promise<void> {\n const signal = options?.signal;\n\n if (signal?.aborted) {\n return Promise.reject(createAbortError());\n }\n\n this.registerNativeToolMirror(tool, signal);\n\n try {\n this.registerToolInServer(tool);\n } catch (error) {\n if (this.native) {\n try {\n this.unregisterNativeToolMirror(tool.name);\n } catch (rollbackError) {\n console.error(\n '[BrowserMcpServer] Rollback of native tool registration failed:',\n rollbackError\n );\n }\n }\n throw error;\n }\n\n if (signal) {\n signal.addEventListener(\n 'abort',\n () => {\n const removed = this._tools.delete(tool.name);\n if (removed) {\n this.sendToolListChanged();\n }\n try {\n this.unregisterNativeToolMirror(tool.name, { preferAbortSignal: true });\n } catch (error) {\n console.warn('[BrowserMcpServer] Native unregister via abort fallback failed:', error);\n }\n if (removed) {\n this.notifyProducerToolsChanged();\n }\n },\n { once: true }\n );\n }\n\n return Promise.resolve();\n }\n\n /**\n * Backfill tools that were already registered on the native/polyfill context\n * before this BrowserMcpServer wrapper was installed.\n */\n syncNativeTools(): number {\n let synced = 0;\n const nativeLegacyToolsApi = this.getNativeLegacyToolsApi();\n if (nativeLegacyToolsApi) {\n const nativeCallTool = nativeLegacyToolsApi.callTool.bind(nativeLegacyToolsApi);\n synced += this.backfillTools(\n nativeLegacyToolsApi.listTools(),\n async (name: string, args: Record<string, unknown>) =>\n nativeCallTool({\n name,\n arguments: args,\n })\n );\n }\n\n const nativeStandardToolsApi = this.getNativeStandardToolsApi();\n if (nativeStandardToolsApi) {\n void this.backfillNativeStandardTools(nativeStandardToolsApi).catch((error: unknown) => {\n console.warn('[BrowserMcpServer] Native WebMCP tool backfill failed:', error);\n });\n }\n\n return synced;\n }\n\n private async backfillNativeStandardTools(\n nativeToolsApi: NativeStandardToolsApi\n ): Promise<number> {\n const nativeTools = await nativeToolsApi.getTools.call(this.native);\n return this.backfillTools(\n nativeTools.map(toToolListItemFromNativeToolInfo),\n async (name: string, args: Record<string, unknown>) => {\n const nativeTool = nativeTools.find((tool) => tool.name === name);\n if (!nativeTool) {\n throw new Error(`Native tool not found: ${name}`);\n }\n\n const serialized = await nativeToolsApi.executeTool.call(\n this.native,\n nativeTool,\n JSON.stringify(args ?? {})\n );\n return parseNativeToolResult(name, serialized);\n }\n );\n }\n\n unregisterTool(nameOrTool: string | ModelContextToolReference): void {\n this.warnUnregisterToolDeprecationOnce();\n const name = this.resolveToolNameForUnregister(nameOrTool);\n const removed = this._tools.delete(name);\n if (removed) {\n this.sendToolListChanged();\n }\n\n if (this.native) {\n this.unregisterNativeToolMirror(name);\n }\n if (removed) {\n this.notifyProducerToolsChanged();\n }\n }\n\n // @ts-expect-error -- WebMCP API: (descriptor) vs MCP SDK: (name, uri, config, readCallback)\n override registerResource(descriptor: {\n uri: string;\n name: string;\n description?: string;\n mimeType?: string;\n read: (uri: URL, params?: Record<string, string>) => Promise<{ contents: ResourceContents[] }>;\n }): { unregister: () => void } {\n const registered = (super.registerResource as unknown as ParentRegisterResourceFn)(\n descriptor.name,\n descriptor.uri,\n {\n ...(descriptor.description !== undefined && { description: descriptor.description }),\n ...(descriptor.mimeType !== undefined && { mimeType: descriptor.mimeType }),\n },\n async (uri: URL) => ({\n contents: (await descriptor.read(uri)).contents,\n })\n );\n\n return {\n unregister: () => registered.remove(),\n };\n }\n\n // @ts-expect-error -- WebMCP API: (descriptor) vs MCP SDK: (name, config, cb)\n override registerPrompt(descriptor: {\n name: string;\n description?: string;\n argsSchema?: InputSchema;\n get: (args: Record<string, unknown>) => Promise<{ messages: PromptMessage[] }>;\n }): { unregister: () => void } {\n // Store argsSchema locally — the parent SDK's _createRegisteredPrompt corrupts\n // plain JSON Schema objects via objectFromShape() which expects Zod schemas.\n if (descriptor.argsSchema) {\n this._promptSchemas.set(descriptor.name, descriptor.argsSchema);\n }\n\n const registered = (super.registerPrompt as unknown as ParentRegisterPromptFn)(\n descriptor.name,\n {\n ...(descriptor.description !== undefined && { description: descriptor.description }),\n // Do NOT pass argsSchema to parent — it gets corrupted by Zod's objectFromShape\n },\n async (args: Record<string, unknown>) => ({\n messages: (await descriptor.get(args)).messages,\n })\n );\n\n return {\n unregister: () => {\n this._promptSchemas.delete(descriptor.name);\n registered.remove();\n },\n };\n }\n\n private resolveToolNameForUnregister(nameOrTool: string | ModelContextToolReference): string {\n if (typeof nameOrTool === 'string') {\n return nameOrTool;\n }\n\n if (isPlainObject(nameOrTool) && typeof nameOrTool.name === 'string') {\n return nameOrTool.name;\n }\n\n throw new TypeError(\n \"Failed to execute 'unregisterTool' on 'ModelContext': parameter 1 must be a string or an object with a string name.\"\n );\n }\n\n private warnUnregisterToolDeprecationOnce(): void {\n if (this._unregisterToolDeprecationWarned) {\n return;\n }\n\n this._unregisterToolDeprecationWarned = true;\n console.warn(\n '[BrowserMcpServer] navigator.modelContext.unregisterTool() is deprecated. The April 23, 2026 WebMCP draft removed it in favor of registerTool(tool, { signal }) — pass an AbortSignal and abort it to unregister.'\n );\n }\n\n // --- Extension methods ---\n\n listResources(): Array<{\n uri: string;\n name: string;\n description?: string;\n mimeType?: string;\n }> {\n return Object.entries(this._parentResources)\n .filter(([, resource]) => resource.enabled)\n .map(([uri, resource]) => ({\n uri,\n name: resource.name,\n ...resource.metadata,\n }));\n }\n\n async readResource(uri: string): Promise<{ contents: ResourceContents[] }> {\n const resource = this._parentResources[uri];\n if (!resource) {\n throw new Error(`Resource not found: ${uri}`);\n }\n\n return resource.readCallback(new URL(uri), {});\n }\n\n listPrompts(): Array<{\n name: string;\n description?: string;\n arguments?: Array<{ name: string; description?: string; required?: boolean }>;\n }> {\n return Object.entries(this._parentPrompts)\n .filter(([, prompt]) => prompt.enabled)\n .map(([name, prompt]) => {\n const schema = this._promptSchemas.get(name);\n return {\n name,\n ...(prompt.description !== undefined && { description: prompt.description }),\n ...(schema?.properties\n ? {\n arguments: Object.entries(schema.properties).map(([argName, prop]) => ({\n name: argName,\n ...(typeof prop === 'object' && prop !== null && 'description' in prop\n ? { description: (prop as { description: string }).description }\n : {}),\n ...(schema.required?.includes(argName) ? { required: true } : {}),\n })),\n }\n : {}),\n };\n });\n }\n\n async getPrompt(\n name: string,\n args: Record<string, unknown> = {}\n ): Promise<{ messages: PromptMessage[] }> {\n const prompt = this._parentPrompts[name];\n if (!prompt) {\n throw new Error(`Prompt not found: ${name}`);\n }\n\n const schema = this._promptSchemas.get(name);\n if (schema) {\n const validator = this._jsonValidator.getValidator(schema);\n const result = validator(args);\n if (!result.valid) {\n throw new Error(`Invalid arguments for prompt ${name}: ${result.errorMessage}`);\n }\n }\n\n return prompt.callback(args, {});\n }\n\n listTools(): ToolListItem[] {\n return [...this._tools.entries()].map(([name, tool]) => {\n const item: ToolListItem = {\n name,\n description: tool.description ?? '',\n inputSchema: tool.inputSchema,\n };\n if (tool.outputSchema) item.outputSchema = tool.outputSchema;\n if (tool.annotations) item.annotations = tool.annotations;\n return item;\n });\n }\n\n private listToolsForMcpTransport(): ToolListItem[] {\n return this.listTools().map((tool) => {\n if (!tool.outputSchema || tool.outputSchema.type === 'object') {\n return tool;\n }\n\n if (tool.outputSchema.type === undefined) {\n return {\n ...tool,\n outputSchema: {\n ...(tool.outputSchema as Record<string, unknown>),\n type: 'object',\n } as JsonSchemaForInference,\n };\n }\n\n const { outputSchema: _outputSchema, ...mcpTool } = tool;\n return mcpTool;\n });\n }\n\n private toMcpCallToolResult(result: ToolResponse): McpCallToolResult {\n return {\n content: result.content as McpCallToolResult['content'],\n ...(isPlainObject(result.structuredContent)\n ? {\n structuredContent: result.structuredContent as McpCallToolResult['structuredContent'],\n }\n : {}),\n ...(result.isError !== undefined ? { isError: result.isError } : {}),\n };\n }\n\n async getTools(): Promise<ModelContextToolInfo[]> {\n const origin =\n typeof globalThis.location === 'object' && typeof globalThis.location?.origin === 'string'\n ? globalThis.location.origin\n : '';\n const currentWindow =\n typeof globalThis.window === 'object' ? globalThis.window : (undefined as unknown as Window);\n\n return this.listTools().map((tool) => {\n let inputSchema: string;\n try {\n inputSchema = JSON.stringify(tool.inputSchema ?? DEFAULT_INPUT_SCHEMA);\n } catch {\n inputSchema = JSON.stringify(DEFAULT_INPUT_SCHEMA);\n }\n\n return {\n name: tool.name,\n title: this._tools.get(tool.name)?.title ?? tool.description ?? '',\n description: tool.description ?? '',\n inputSchema,\n origin,\n window: currentWindow,\n };\n });\n }\n\n /**\n * Override SDK's validateToolInput to handle both Zod schemas and plain JSON Schema.\n * Zod schemas use the SDK's safeParseAsync; plain JSON Schema uses the configured SDK validator.\n */\n override async validateToolInput(\n tool: { inputSchema?: unknown },\n args: Record<string, unknown> | undefined,\n toolName: string\n ): Promise<Record<string, unknown> | undefined> {\n if (!tool.inputSchema) return undefined;\n\n // Zod schemas → use SDK's safeParseAsync\n if (this.isZodSchema(tool.inputSchema)) {\n const result = await safeParseAsync(\n tool.inputSchema as Parameters<typeof safeParseAsync>[0],\n args ?? {}\n );\n if (!result.success) {\n throw new Error(\n `Invalid arguments for tool ${toolName}: ${getParseErrorMessage(result.error)}`\n );\n }\n return result.data as Record<string, unknown>;\n }\n\n // Plain JSON Schema → use the configured SDK validator\n const validator = this._jsonValidator.getValidator(tool.inputSchema);\n const result = validator(args ?? {});\n if (!result.valid) {\n throw new Error(`Invalid arguments for tool ${toolName}: ${result.errorMessage}`);\n }\n return result.data as Record<string, unknown>;\n }\n\n /**\n * Override SDK's validateToolOutput to handle both Zod schemas and plain JSON Schema.\n */\n override async validateToolOutput(\n tool: { outputSchema?: unknown },\n result: unknown,\n toolName: string\n ): Promise<void> {\n if (!tool.outputSchema) return;\n\n const r = result as { content?: unknown; isError?: unknown; structuredContent?: unknown };\n if (!('content' in r) || r.isError) return;\n if (r.structuredContent === undefined) {\n throw new Error(\n `Output validation error: Tool ${toolName} has an output schema but no structured content was provided`\n );\n }\n\n // Zod schemas → use SDK's safeParseAsync\n if (this.isZodSchema(tool.outputSchema)) {\n const parseResult = await safeParseAsync(\n tool.outputSchema as Parameters<typeof safeParseAsync>[0],\n r.structuredContent\n );\n if (!parseResult.success) {\n throw new Error(\n `Output validation error: Invalid structured content for tool ${toolName}: ${getParseErrorMessage(parseResult.error)}`\n );\n }\n return;\n }\n\n // Plain JSON Schema → use the configured SDK validator\n const validator = this._jsonValidator.getValidator(tool.outputSchema);\n const validationResult = validator(r.structuredContent);\n if (!validationResult.valid) {\n throw new Error(\n `Output validation error: Invalid structured content for tool ${toolName}: ${validationResult.errorMessage}`\n );\n }\n }\n\n /**\n * Executes a registered tool by name.\n *\n * @deprecated Prefer the WebMCP standard producer path: get a descriptor from\n * `getTools()` and pass it to `executeTool(tool, inputArgsJson)`. This method\n * remains as an MCP-B compatibility convenience and MCP transport bridge.\n */\n async callTool(params: {\n name: string;\n arguments?: Record<string, unknown>;\n }): Promise<ToolResponse> {\n const tool = this._tools.get(params.name);\n if (!tool) {\n throw new Error(`Tool not found: ${params.name}`);\n }\n\n const args = await this.validateToolInput(tool, params.arguments, params.name);\n const result = await tool.handler(args ?? {});\n await this.validateToolOutput(tool, result, params.name);\n return result;\n }\n\n /**\n * Executes a tool descriptor returned from getTools().\n */\n executeTool(\n tool: ModelContextToolInfo,\n inputArgsJson: string,\n options?: ModelContextTestingExecuteToolOptions\n ): Promise<string | null>;\n /**\n * Executes a registered tool by name.\n *\n * @deprecated Prefer the WebMCP standard producer path: get a descriptor from\n * `getTools()` and pass it to `executeTool(tool, inputArgsJson)`.\n */\n executeTool(name: string, args?: Record<string, unknown>): Promise<ToolResponse>;\n async executeTool(\n toolOrName: ModelContextToolInfo | string,\n inputArgsJsonOrArgs: string | Record<string, unknown> = {}\n ): Promise<string | null | ToolResponse> {\n if (typeof toolOrName === 'string') {\n return this.callTool({\n name: toolOrName,\n arguments:\n typeof inputArgsJsonOrArgs === 'string'\n ? JSON.parse(inputArgsJsonOrArgs)\n : inputArgsJsonOrArgs,\n });\n }\n\n const result = await this.callTool({\n name: toolOrName.name,\n arguments:\n typeof inputArgsJsonOrArgs === 'string'\n ? (JSON.parse(inputArgsJsonOrArgs) as Record<string, unknown>)\n : inputArgsJsonOrArgs,\n });\n const serialized = JSON.stringify(result);\n return serialized === undefined ? null : serialized;\n }\n\n /**\n * Override connect to initialize request handlers BEFORE the transport connection.\n * This prevents \"Cannot register capabilities after connecting to transport\" errors\n * when tools are registered dynamically after connection.\n *\n * Tool handlers are installed with the public low-level Server API in the constructor.\n * Prompt/resource handlers still come from the parent, then prompt handlers are replaced\n * where the parent expects Zod shapes instead of plain JSON Schema.\n */\n override async connect(transport: Transport): Promise<void> {\n (this as unknown as { setResourceRequestHandlers: () => void }).setResourceRequestHandlers();\n (this as unknown as { setPromptRequestHandlers: () => void }).setPromptRequestHandlers();\n\n // Replace ListPrompts handler — parent calls promptArgumentsFromSchema which expects\n // Zod shapes. We use _promptSchemas which has the real JSON Schema.\n this.server.setRequestHandler(ListPromptsRequestSchema, () => ({\n prompts: this.listPrompts(),\n }));\n\n // Replace GetPrompt handler — parent calls safeParseAsync on argsSchema.\n // We validate with the configured SDK validator instead.\n this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {\n const prompt = this._parentPrompts[request.params.name];\n if (!prompt) {\n throw new Error(`Prompt ${request.params.name} not found`);\n }\n if (!prompt.enabled) {\n throw new Error(`Prompt ${request.params.name} disabled`);\n }\n\n const schema = this._promptSchemas.get(request.params.name);\n if (schema) {\n const validator = this._jsonValidator.getValidator(schema);\n const result = validator(request.params.arguments ?? {});\n if (!result.valid) {\n throw new Error(\n `Invalid arguments for prompt ${request.params.name}: ${result.errorMessage}`\n );\n }\n return prompt.callback(request.params.arguments as Record<string, unknown>, {});\n }\n\n return prompt.callback({}, {});\n });\n\n return super.connect(transport);\n }\n\n // --- Sampling & Elicitation (delegated to Server) ---\n\n async createMessage(\n params: CreateMessageRequest['params'],\n options?: RequestOptions\n ): Promise<CreateMessageResult> {\n return this.server.createMessage(params, withDefaultTimeout(options));\n }\n\n async elicitInput(\n params: ElicitRequest['params'],\n options?: RequestOptions\n ): Promise<ElicitResult> {\n return this.server.elicitInput(params, withDefaultTimeout(options));\n }\n}\n\n// --- Exported descriptor types for consumers ---\n\nexport interface ResourceDescriptor {\n uri: string;\n name: string;\n description?: string;\n mimeType?: string;\n read: (uri: URL, params?: Record<string, string>) => Promise<{ contents: ResourceContents[] }>;\n}\n\nexport interface PromptDescriptor {\n name: string;\n description?: string;\n argsSchema?: InputSchema;\n get: (args: Record<string, unknown>) => Promise<{ messages: PromptMessage[] }>;\n}\n","import type {\n JsonSchemaValidatorResult,\n jsonSchemaValidator,\n} from '@modelcontextprotocol/sdk/validation';\n\n/**\n * No-op JSON Schema validator for browser environments.\n *\n * This validator bypasses the MCP SDK's internal ajv-based validation which causes\n * \"Error compiling schema\" errors in browser extensions due to ajv's use of\n * eval/Function constructor.\n *\n * Validation is handled externally by Zod in @mcp-b/global, making the SDK's\n * internal validation redundant. This no-op validator allows the SDK to function\n * without the ajv dependency issues.\n */\n\n/**\n * A no-op JSON Schema validator that always returns valid.\n *\n * Use this in browser environments where:\n * - ajv causes \"Error compiling schema\" errors\n * - Validation is already handled elsewhere (e.g., by Zod)\n * - You need to avoid eval/Function constructor restrictions\n *\n * @example\n * ```typescript\n * import { BrowserMcpServer } from '@mcp-b/webmcp-ts-sdk';\n * import { NoOpJsonSchemaValidator } from '@mcp-b/webmcp-ts-sdk/no-op-validator';\n *\n * const server = new BrowserMcpServer(\n * { name: 'my-server', version: '1.0.0' },\n * { jsonSchemaValidator: new NoOpJsonSchemaValidator() }\n * );\n * ```\n */\nexport class NoOpJsonSchemaValidator implements jsonSchemaValidator {\n /**\n * Returns a validator function that always passes.\n * The input data is passed through unchanged.\n *\n * @param _schema - The JSON Schema (ignored)\n * @returns A validator function that always returns valid\n */\n getValidator<T>(_schema: unknown): (input: unknown) => JsonSchemaValidatorResult<T> {\n return (input: unknown): JsonSchemaValidatorResult<T> => ({\n valid: true,\n data: input as T,\n errorMessage: undefined,\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/browser-server.ts"],"sourcesContent":["import {\n coerceWebMcpToolDescriptor,\n createInvalidStateError,\n createToolInvocationFailedError,\n createUnknownError,\n isPlainObject,\n normalizeToolResponse,\n normalizeInputSchema,\n parseChromeToolInput,\n serializeChromeToolResult,\n toWebMcpAnnotations,\n validateExecutableOrigin,\n validatePotentiallyTrustworthyOrigins,\n validateWebMcpAccess,\n validateWebMcpToolDescriptor,\n withAbortSignal,\n} from '@mcp-b/webmcp-polyfill/schema';\nimport type { NormalizedInputSchema } from '@mcp-b/webmcp-polyfill/schema';\nimport type {\n ChromeModelContextExecuteToolOptions,\n ChromeModelContextExtensions,\n InputSchema,\n ModelContext,\n ModelContextGetToolOptions,\n ModelContextRegisterToolOptions,\n ModelContextTool,\n ModelContextWithExtensions,\n RegistrationHandle,\n RegisteredTool,\n ToolAnnotations,\n ToolDescriptor,\n ToolListItem,\n WebMcpToolInput,\n} from '@mcp-b/webmcp-types';\nimport {\n fromJsonSchema,\n isInputRequiredResult,\n McpServer,\n mergeCapabilities,\n ResourceTemplate,\n type GetPromptResult,\n type Implementation,\n type ReadResourceResult,\n type RegisteredPrompt as McpRegisteredPrompt,\n type RegisteredResource as McpRegisteredResource,\n type RegisteredResourceTemplate as McpRegisteredResourceTemplate,\n type RegisteredTool as McpRegisteredTool,\n type ServerOptions,\n type StandardSchemaWithJSON,\n type ToolAnnotations as McpToolAnnotations,\n type Transport,\n type Variables,\n} from '@modelcontextprotocol/server';\n\nconst DEFAULT_INPUT_SCHEMA = normalizeInputSchema(undefined).inputSchema;\nconst SERVER_MARKER_PROPERTY = '__isBrowserMcpServer' as const;\n\nexport function isBrowserMcpServer(context: unknown): context is BrowserMcpServer {\n return (\n typeof context === 'object' &&\n context !== null &&\n SERVER_MARKER_PROPERTY in context &&\n context[SERVER_MARKER_PROPERTY] === true\n );\n}\n\ninterface RegisteredWebMcpTool {\n item: ToolListItem;\n registeredInputSchema?: string;\n execute: (args: WebMcpToolInput, signal?: AbortSignal) => Promise<unknown>;\n mcpHandle: McpRegisteredTool | undefined;\n exposedTo?: readonly string[];\n abortSignal?: AbortSignal;\n abortListener?: () => void;\n}\n\ntype McpRegistration = McpRegisteredPrompt | McpRegisteredResource | McpRegisteredResourceTemplate;\n\nexport interface BrowserMcpServerOptions extends ServerOptions {\n native?: ModelContext;\n}\n\ntype NativeStandardToolsApi = ModelContext & {\n executeTool: NonNullable<ChromeModelContextExtensions['executeTool']>;\n};\ntype NativeRegisterToolFn = (\n tool: ModelContextTool<WebMcpToolInput>,\n options?: ModelContextRegisterToolOptions\n) => Promise<void>;\n\ninterface NativeBackfilledTool {\n source: RegisteredTool;\n item: ToolListItem;\n fingerprint: string;\n}\n\nfunction parseNativeToolResult(serialized: string | null): unknown {\n if (serialized === null) {\n return {\n content: [{ type: 'text', text: 'Tool execution interrupted by navigation' }],\n isError: true,\n };\n }\n\n let result: unknown;\n try {\n result = JSON.parse(serialized);\n } catch {\n return normalizeToolResponse(serialized);\n }\n return isInputRequiredResult(result) ? result : normalizeToolResponse(result);\n}\n\nfunction toMcpInputSchema(\n normalized: NormalizedInputSchema\n): StandardSchemaWithJSON<Record<string, unknown>> {\n // normalizeInputSchema() attaches a non-enumerable `~standard` when the caller supplied a\n // Standard Schema validator, so reuse it instead of recompiling the JSON Schema projection.\n const standardSchema = Object.getOwnPropertyDescriptor(normalized.inputSchema, '~standard');\n return standardSchema && !standardSchema.enumerable\n ? (normalized.inputSchema as unknown as StandardSchemaWithJSON<Record<string, unknown>>)\n : fromJsonSchema<Record<string, unknown>>(\n normalized.inputSchema as Parameters<typeof fromJsonSchema>[0]\n );\n}\n\nfunction toMcpAnnotations(\n annotations: ToolAnnotations | undefined\n): McpToolAnnotations | undefined {\n if (!annotations) return undefined;\n const { untrustedContentHint: _untrustedContentHint, ...mcpAnnotations } = annotations;\n return mcpAnnotations;\n}\n\nfunction toNativeTool(\n tool: ToolDescriptor<WebMcpToolInput>,\n inputSchema: InputSchema | undefined,\n execute: ModelContextTool<WebMcpToolInput>['execute']\n): ModelContextTool<WebMcpToolInput> {\n const annotations = tool.annotations ? toWebMcpAnnotations(tool.annotations) : undefined;\n return {\n name: tool.name,\n ...(tool.title !== undefined ? { title: tool.title } : {}),\n description: tool.description,\n ...(inputSchema !== undefined ? { inputSchema } : {}),\n ...(annotations ? { annotations } : {}),\n execute,\n };\n}\n\n/**\n * Thin WebMCP-to-MCP v2 adapter.\n *\n * The official v2 `McpServer` owns MCP registration, validation, and transport\n * behavior. This class only adds the document-facing WebMCP contract and native\n * Chrome mirroring.\n */\nexport class BrowserMcpServer extends EventTarget implements ModelContextWithExtensions {\n readonly [SERVER_MARKER_PROPERTY] = true as const;\n readonly mcpServer: McpServer;\n\n private readonly native: ModelContext | undefined;\n private readonly ownerDocument: Document | null;\n private readonly tools = new Map<string, RegisteredWebMcpTool>();\n private peerOrigin: string | undefined;\n private readonly registrations = new Set<McpRegistration>();\n private readonly nativeToolAbortControllers = new Map<string, AbortController>();\n private readonly nativeBackfilledTools = new Map<string, NativeBackfilledTool>();\n private readonly pendingTools = new Map<string, AbortController>();\n private readonly removingNativeTools = new Set<string>();\n private nativeSyncQueue: Promise<void> = Promise.resolve();\n private nativeToolChangeQueue: Promise<void> = Promise.resolve();\n private nativeToolChangeListener: EventListener | undefined;\n private closed = false;\n private closePromise: Promise<void> | undefined;\n private ontoolchangeHandler: ((this: ModelContext, event: Event) => unknown) | null = null;\n private readonly ontoolchangeListener: EventListener = (event) => {\n this.ontoolchangeHandler?.call(this, event);\n };\n\n constructor(serverInfo: Implementation, options: BrowserMcpServerOptions = {}) {\n super();\n const { native, ...serverOptions } = options;\n this.mcpServer = new McpServer(serverInfo, {\n ...serverOptions,\n capabilities: mergeCapabilities(serverOptions.capabilities ?? {}, {\n tools: { listChanged: true },\n resources: { listChanged: true },\n prompts: { listChanged: true },\n }),\n });\n this.native = native;\n this.ownerDocument = globalThis.document ?? null;\n if (native) {\n this.nativeToolChangeListener = () => {\n if (this.closed) return;\n this.nativeToolChangeQueue = this.nativeToolChangeQueue.then(async () => {\n try {\n await this.syncNativeTools();\n } catch (error) {\n console.warn('[BrowserMcpServer] Native WebMCP tool reconciliation failed:', error);\n }\n await this.notifyProducerToolsChanged();\n });\n };\n native.addEventListener('toolchange', this.nativeToolChangeListener);\n }\n }\n\n get ontoolchange(): ((this: ModelContext, event: Event) => unknown) | null {\n return this.ontoolchangeHandler;\n }\n\n set ontoolchange(handler: ((this: ModelContext, event: Event) => unknown) | null) {\n const listener = typeof handler === 'function' ? handler : null;\n if (listener === null) {\n this.ontoolchangeHandler = null;\n super.removeEventListener('toolchange', this.ontoolchangeListener);\n return;\n }\n\n if (this.ontoolchangeHandler === null) {\n super.addEventListener('toolchange', this.ontoolchangeListener);\n }\n this.ontoolchangeHandler = listener;\n }\n\n private async notifyProducerToolsChanged(): Promise<void> {\n if (this.closed) return;\n // Preserve task ordering because WebMCP does not expose its platform task source.\n await new Promise((resolve) => setTimeout(resolve, 0));\n if (!this.closed) this.dispatchEvent(new Event('toolchange'));\n }\n\n private getNativeStandardToolsApi(): NativeStandardToolsApi | undefined {\n const candidate: (ModelContext & Partial<ChromeModelContextExtensions>) | undefined =\n this.native;\n return candidate && typeof candidate.executeTool === 'function'\n ? (candidate as NativeStandardToolsApi)\n : undefined;\n }\n\n private async registerNativeToolMirror(\n tool: ToolDescriptor<WebMcpToolInput>,\n normalized: NormalizedInputSchema,\n options: ModelContextRegisterToolOptions,\n execute: RegisteredWebMcpTool['execute'],\n controller: AbortController\n ): Promise<void> {\n if (!this.native) return;\n\n // The overload set keys on a statically known inputSchema; mirrored tools carry a dynamic one.\n const nativeRegister = this.native.registerTool as unknown as NativeRegisterToolFn;\n const signal = options.signal\n ? AbortSignal.any([options.signal, controller.signal])\n : controller.signal;\n\n const nativeInputSchema =\n normalized.registeredInputSchema === undefined\n ? undefined\n : (JSON.parse(normalized.registeredInputSchema) as InputSchema);\n this.nativeToolAbortControllers.set(tool.name, controller);\n try {\n await nativeRegister.call(\n this.native,\n toNativeTool(tool, nativeInputSchema, (input) => execute(input)),\n { ...options, signal }\n );\n } catch (error) {\n controller.abort();\n if (this.nativeToolAbortControllers.get(tool.name) === controller) {\n this.nativeToolAbortControllers.delete(tool.name);\n }\n throw error;\n }\n if (this.nativeToolAbortControllers.get(tool.name) === controller) {\n this.removingNativeTools.delete(tool.name);\n }\n }\n\n private abortNativeToolMirror(\n name: string,\n controller = this.nativeToolAbortControllers.get(name)\n ): void {\n if (!controller || this.nativeToolAbortControllers.get(name) !== controller) return;\n this.removingNativeTools.add(name);\n controller.abort();\n this.nativeToolAbortControllers.delete(name);\n }\n\n private validateToolDescriptor(tool: ToolDescriptor<WebMcpToolInput>): NormalizedInputSchema {\n validateWebMcpToolDescriptor(tool);\n if (this.tools.has(tool.name) || this.pendingTools.has(tool.name)) {\n throw createInvalidStateError(`Tool already registered: ${tool.name}`);\n }\n return normalizeInputSchema(tool.inputSchema);\n }\n\n private registerToolInMcp(\n tool: ToolDescriptor<WebMcpToolInput>,\n normalized: NormalizedInputSchema,\n executeTool: RegisteredWebMcpTool['execute'],\n exposedTo: readonly string[] | undefined\n ): RegisteredWebMcpTool {\n const outputSchema =\n tool.outputSchema === undefined ? undefined : structuredClone(tool.outputSchema);\n const mcpOutputSchema =\n outputSchema === undefined\n ? undefined\n : fromJsonSchema(outputSchema as Parameters<typeof fromJsonSchema>[0]);\n const mcpAnnotations = toMcpAnnotations(tool.annotations);\n const mcpCompatibleInput =\n normalized.inputSchema.type === undefined || normalized.inputSchema.type === 'object';\n const mcpHandle = mcpCompatibleInput\n ? this.mcpServer.registerTool(\n tool.name,\n {\n ...(tool.title !== undefined ? { title: tool.title } : {}),\n description: tool.description,\n inputSchema: toMcpInputSchema(normalized),\n ...(mcpOutputSchema ? { outputSchema: mcpOutputSchema } : {}),\n ...(mcpAnnotations ? { annotations: mcpAnnotations } : {}),\n },\n async (args, context) => {\n const result = await executeTool(args, context.mcpReq.signal);\n if (isInputRequiredResult(result)) {\n throw new Error(\n `WebMCP tool \"${tool.name}\" returned input_required. Multi-round tool flows require BrowserMcpServer.mcpServer.registerTool().`\n );\n }\n return normalizeToolResponse(result);\n }\n )\n : undefined;\n // A restricted tool is never observable on the wire before its audience is\n // checked: the handle is disabled here, in the same synchronous step that created\n // it, and only applyToolExposure re-enables it.\n if (exposedTo?.length) mcpHandle?.disable();\n\n if (!mcpCompatibleInput) {\n console.warn(\n `[BrowserMcpServer] Tool \"${tool.name}\" remains available through WebMCP but cannot be exposed over MCP because MCP input schemas require an object root.`\n );\n }\n\n const item: ToolListItem = {\n name: tool.name,\n ...(tool.title !== undefined ? { title: tool.title } : {}),\n description: tool.description,\n inputSchema: normalized.inputSchema,\n ...(outputSchema === undefined ? {} : { outputSchema }),\n ...(tool.annotations ? { annotations: tool.annotations } : {}),\n };\n return {\n item,\n ...(normalized.registeredInputSchema !== undefined\n ? { registeredInputSchema: normalized.registeredInputSchema }\n : {}),\n execute: executeTool,\n mcpHandle,\n ...(exposedTo?.length ? { exposedTo } : {}),\n };\n }\n\n readonly registerTool: ModelContextWithExtensions['registerTool'] = async (\n toolValue: unknown,\n optionsValue: ModelContextRegisterToolOptions | null = {}\n ): Promise<void> => {\n const options = optionsValue ?? {};\n validateWebMcpAccess(this.ownerDocument);\n if (this.closed) throw createInvalidStateError('BrowserMcpServer is closed');\n if (!isPlainObject(toolValue)) {\n throw new TypeError('registerTool(tool) requires a tool object');\n }\n const tool = coerceWebMcpToolDescriptor(toolValue);\n const normalized = this.validateToolDescriptor(tool);\n options.signal?.throwIfAborted();\n validatePotentiallyTrustworthyOrigins(options.exposedTo);\n options.signal?.throwIfAborted();\n const execute: RegisteredWebMcpTool['execute'] = async (args, signal) => {\n signal?.throwIfAborted();\n return withAbortSignal(\n Promise.resolve().then(() => Reflect.apply(tool.execute, undefined, [args])),\n signal\n );\n };\n const controller = new AbortController();\n let registered: RegisteredWebMcpTool | undefined;\n const abort = () => {\n if (this.pendingTools.get(tool.name) === controller) {\n this.pendingTools.delete(tool.name);\n }\n if (registered && this.tools.get(tool.name) === registered) {\n this.removeTool(tool.name);\n } else {\n this.abortNativeToolMirror(tool.name, controller);\n }\n };\n options.signal?.addEventListener('abort', abort, { once: true });\n this.pendingTools.set(tool.name, controller);\n try {\n await this.registerNativeToolMirror(tool, normalized, options, execute, controller);\n if (this.closed) throw createInvalidStateError('BrowserMcpServer is closed');\n options.signal?.throwIfAborted();\n registered = this.registerToolInMcp(tool, normalized, execute, options.exposedTo);\n this.tools.set(tool.name, registered);\n this.applyToolExposure();\n if (options.signal?.aborted) {\n abort();\n options.signal.throwIfAborted();\n }\n } catch (error) {\n this.abortNativeToolMirror(tool.name, controller);\n options.signal?.removeEventListener('abort', abort);\n options.signal?.throwIfAborted();\n throw error;\n } finally {\n if (this.pendingTools.get(tool.name) === controller) {\n this.pendingTools.delete(tool.name);\n }\n }\n if (options.signal) {\n registered.abortSignal = options.signal;\n registered.abortListener = abort;\n }\n if (this.tools.get(tool.name) === registered) {\n if (this.native) await this.nativeToolChangeQueue;\n else await this.notifyProducerToolsChanged();\n }\n if (this.closed) throw createInvalidStateError('BrowserMcpServer is closed');\n options.signal?.throwIfAborted();\n };\n\n private removeTool(name: string, options?: { skipNative?: boolean; notify?: boolean }): void {\n const registered = this.tools.get(name);\n if (registered) {\n if (registered.abortSignal && registered.abortListener) {\n registered.abortSignal.removeEventListener('abort', registered.abortListener);\n }\n this.tools.delete(name);\n this.nativeBackfilledTools.delete(name);\n registered.mcpHandle?.remove();\n if ((options?.notify ?? true) && !this.native) {\n void this.notifyProducerToolsChanged();\n }\n }\n if (!options?.skipNative) this.abortNativeToolMirror(name);\n }\n\n syncNativeTools(): Promise<void> {\n const sync = this.nativeSyncQueue.then(async () => {\n if (this.closed) return;\n const native = this.getNativeStandardToolsApi();\n if (native) await this.backfillNativeStandardTools(native);\n });\n this.nativeSyncQueue = sync.then(\n () => undefined,\n () => undefined\n );\n return sync;\n }\n\n private async backfillNativeStandardTools(native: NativeStandardToolsApi): Promise<void> {\n const tools = await native.getTools();\n if (this.closed) return;\n const nextTools = new Map<string, NativeBackfilledTool>();\n const nativeNames = new Set(tools.map(({ name }) => name));\n for (const name of this.removingNativeTools) {\n if (!nativeNames.has(name)) this.removingNativeTools.delete(name);\n }\n for (const tool of tools) {\n // ponytail: MCP tool names are global, so keep the first valid visible tool.\n // Add origin-qualified aliases if MCP gains scoped tool identity.\n if (\n nextTools.has(tool.name) ||\n this.pendingTools.has(tool.name) ||\n this.removingNativeTools.has(tool.name)\n ) {\n continue;\n }\n let inputSchema: InputSchema | undefined = DEFAULT_INPUT_SCHEMA;\n if (tool.inputSchema !== undefined) {\n try {\n // An object since webmcp#241; a serialized string from older Chrome. The\n // round-trip detaches the object from the page's graph and rejects non-JSON.\n const serialized =\n typeof tool.inputSchema === 'string'\n ? tool.inputSchema\n : JSON.stringify(tool.inputSchema);\n const parsed: unknown = JSON.parse(serialized);\n inputSchema = isPlainObject(parsed) ? (parsed as InputSchema) : undefined;\n } catch {\n inputSchema = undefined;\n }\n }\n if (!inputSchema) {\n console.warn(\n `[BrowserMcpServer] Native tool \"${tool.name}\" was not exposed over MCP because its input schema is malformed.`\n );\n continue;\n }\n const item: ToolListItem = {\n name: tool.name,\n ...(tool.title !== undefined ? { title: tool.title } : {}),\n description: tool.description,\n inputSchema,\n ...(tool.annotations ? { annotations: tool.annotations } : {}),\n };\n nextTools.set(tool.name, {\n source: tool,\n item,\n fingerprint: JSON.stringify(item),\n });\n }\n\n for (const [name, current] of this.nativeBackfilledTools) {\n const next = nextTools.get(name);\n if (!next || next.fingerprint !== current.fingerprint) {\n this.removeTool(name, { skipNative: true, notify: false });\n continue;\n }\n this.nativeBackfilledTools.set(name, next);\n }\n\n for (const [name, next] of nextTools) {\n if (this.tools.has(name)) continue;\n const execute = async (args: WebMcpToolInput, signal?: AbortSignal) => {\n const currentTool = this.nativeBackfilledTools.get(name)?.source;\n if (!currentTool) throw new Error(`Native tool not found: ${name}`);\n const input = JSON.stringify(args);\n return parseNativeToolResult(\n signal\n ? await native.executeTool.call(this.native, currentTool, input, { signal })\n : await native.executeTool.call(this.native, currentTool, input)\n );\n };\n const tool: ToolDescriptor<WebMcpToolInput> = {\n name,\n ...(next.item.title !== undefined ? { title: next.item.title } : {}),\n description: next.item.description,\n inputSchema: next.item.inputSchema,\n ...(next.item.annotations ? { annotations: next.item.annotations } : {}),\n execute: (args) => execute(args),\n };\n try {\n const normalized = this.validateToolDescriptor(tool);\n // Native getTools() does not report the allowlist a tool registered with, so a\n // backfilled mirror carries none and stays as widely exposed as it is today.\n this.tools.set(tool.name, this.registerToolInMcp(tool, normalized, execute, undefined));\n this.nativeBackfilledTools.set(name, next);\n } catch (error) {\n console.warn(\n `[BrowserMcpServer] Native tool \"${name}\" was not exposed over MCP because its schema could not be compiled:`,\n error\n );\n }\n }\n }\n\n registerResource(descriptor: ResourceDescriptor): RegistrationHandle {\n if (this.closed) throw createInvalidStateError('BrowserMcpServer is closed');\n const registeredDescriptor = { ...descriptor };\n const config = {\n ...(registeredDescriptor.description !== undefined\n ? { description: registeredDescriptor.description }\n : {}),\n ...(registeredDescriptor.mimeType !== undefined\n ? { mimeType: registeredDescriptor.mimeType }\n : {}),\n };\n const template = registeredDescriptor.uri.includes('{')\n ? new ResourceTemplate(registeredDescriptor.uri, { list: undefined })\n : undefined;\n const mcpHandle = template\n ? this.mcpServer.registerResource(\n registeredDescriptor.name,\n template,\n config,\n async (uri, variables) => registeredDescriptor.read(uri, variables)\n )\n : this.mcpServer.registerResource(\n registeredDescriptor.name,\n registeredDescriptor.uri,\n config,\n async (uri) => registeredDescriptor.read(uri)\n );\n this.registrations.add(mcpHandle);\n return {\n unregister: () => {\n if (this.registrations.delete(mcpHandle)) mcpHandle.remove();\n },\n };\n }\n\n registerPrompt(descriptor: PromptDescriptor): RegistrationHandle {\n if (this.closed) throw createInvalidStateError('BrowserMcpServer is closed');\n const registeredDescriptor = {\n ...descriptor,\n ...(descriptor.argsSchema === undefined\n ? {}\n : { argsSchema: structuredClone(descriptor.argsSchema) }),\n };\n const argsSchema =\n registeredDescriptor.argsSchema === undefined\n ? undefined\n : fromJsonSchema<Record<string, string>>(\n registeredDescriptor.argsSchema as Parameters<typeof fromJsonSchema>[0]\n );\n const mcpHandle = this.mcpServer.registerPrompt(\n registeredDescriptor.name,\n {\n ...(registeredDescriptor.description !== undefined\n ? { description: registeredDescriptor.description }\n : {}),\n ...(argsSchema ? { argsSchema } : {}),\n },\n async (args) => registeredDescriptor.get(args ?? {})\n );\n this.registrations.add(mcpHandle);\n return {\n unregister: () => {\n if (this.registrations.delete(mcpHandle)) mcpHandle.remove();\n },\n };\n }\n\n listTools(): ToolListItem[] {\n return structuredClone([...this.tools.values()].map(({ item }) => item));\n }\n\n async getTools(options?: ModelContextGetToolOptions): Promise<RegisteredTool[]> {\n validateWebMcpAccess(this.ownerDocument);\n if (this.closed) throw createInvalidStateError('BrowserMcpServer is closed');\n if (this.native) {\n return this.native.getTools(options);\n }\n validatePotentiallyTrustworthyOrigins(options?.fromOrigins);\n if (options?.fromOrigins?.length) {\n throw new DOMException(\n 'Cross-document tool discovery requires native WebMCP',\n 'NotSupportedError'\n );\n }\n\n const origin = globalThis.location?.origin ?? '';\n const currentWindow = globalThis.window;\n\n const tools = [...this.tools.values()]\n .map(({ item, registeredInputSchema }) => {\n // A fresh object per call, aligned with the polyfill's post-webmcp#241\n // shape. A custom toJSON can serialize to non-object JSON; omit those\n // rather than emit a value consumers would mistake for a pre-154\n // serialized string.\n const parsed: unknown =\n registeredInputSchema === undefined ? undefined : JSON.parse(registeredInputSchema);\n return {\n name: item.name,\n title: item.title ?? '',\n description: item.description,\n ...(isPlainObject(parsed) ? { inputSchema: parsed } : {}),\n origin,\n window: currentWindow,\n ...(item.annotations ? { annotations: toWebMcpAnnotations(item.annotations) } : {}),\n };\n })\n .sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n await new Promise((resolve) => setTimeout(resolve, 0));\n return tools;\n }\n\n async executeTool(\n tool: RegisteredTool,\n inputArgsJson: string,\n options?: ChromeModelContextExecuteToolOptions\n ): Promise<string | null> {\n validateWebMcpAccess(this.ownerDocument);\n if (this.closed) throw createInvalidStateError('BrowserMcpServer is closed');\n const native = this.getNativeStandardToolsApi();\n if (native) {\n return native.executeTool.call(this.native, tool, inputArgsJson, options);\n }\n\n if (tool === null || typeof tool !== 'object') {\n throw new TypeError('RegisteredTool must be an object');\n }\n for (const required of ['name', 'description', 'window', 'origin'] as const) {\n if (!(required in tool)) {\n throw new TypeError(`RegisteredTool.${required} is required`);\n }\n }\n validateExecutableOrigin(tool.origin);\n const origin = globalThis.location?.origin ?? '';\n const currentWindow = globalThis.window;\n if (tool.origin !== origin || tool.window !== currentWindow) {\n throw createUnknownError(`Native tool not found: ${tool.name}`);\n }\n options?.signal?.throwIfAborted();\n const registered = this.tools.get(tool.name);\n if (!registered) throw createUnknownError(`Tool not found: ${tool.name}`);\n const args = parseChromeToolInput(inputArgsJson);\n try {\n const result = await withAbortSignal(\n registered.execute(args, options?.signal),\n registered.abortSignal,\n () => createUnknownError('Tool unregistered')\n );\n return serializeChromeToolResult(result);\n } catch (error) {\n if (options?.signal?.aborted && error === options.signal.reason) throw error;\n if (registered.abortSignal?.aborted) throw error;\n throw createToolInvocationFailedError(error);\n }\n }\n\n /**\n * Re-evaluate which registered tools may appear on the wire.\n *\n * `exposedTo` narrows a tool to named embedder origins. The peer origin is only known\n * once a transport that reports one has heard from its peer, so a restricted tool stays\n * disabled until then — and stays disabled forever on transports that cannot name a peer\n * at all. Failing closed keeps a tool that asked for a narrow audience from reaching a\n * wider one; unrestricted tools are untouched and behave exactly as before.\n */\n private applyToolExposure(): void {\n for (const { exposedTo, mcpHandle } of this.tools.values()) {\n if (!exposedTo?.length || !mcpHandle) continue;\n const visible = this.peerOrigin !== undefined && exposedTo.includes(this.peerOrigin);\n if (visible === mcpHandle.enabled) continue;\n if (visible) mcpHandle.enable();\n else mcpHandle.disable();\n }\n }\n\n /**\n * Follow the peer origin of transports that report one, so `exposedTo` can be scoped to\n * the embedder actually connected. Duck-typed rather than imported: the SDK must not take\n * a build dependency on `@mcp-b/transports`, and transports that never name a peer simply\n * leave every restricted tool disabled.\n */\n private observePeerOrigin(transport: Transport): void {\n if (!('clientOrigin' in transport)) return;\n const peered = transport as Transport & {\n clientOrigin?: string;\n onclientorigin?: (origin: string) => void;\n };\n this.peerOrigin = peered.clientOrigin;\n this.applyToolExposure();\n const previous = peered.onclientorigin;\n peered.onclientorigin = (origin) => {\n previous?.(origin);\n this.peerOrigin = origin;\n this.applyToolExposure();\n };\n }\n\n connect(transport: Transport): Promise<void> {\n if (this.closed) return Promise.reject(createInvalidStateError('BrowserMcpServer is closed'));\n this.observePeerOrigin(transport);\n return this.mcpServer.connect(transport);\n }\n\n close(): Promise<void> {\n if (this.closePromise) return this.closePromise;\n this.closed = true;\n this.closePromise = (async () => {\n if (this.native && this.nativeToolChangeListener) {\n this.native.removeEventListener('toolchange', this.nativeToolChangeListener);\n this.nativeToolChangeListener = undefined;\n }\n for (const name of this.nativeToolAbortControllers.keys()) {\n this.abortNativeToolMirror(name);\n }\n for (const name of this.tools.keys()) {\n this.removeTool(name, { notify: false });\n }\n for (const handle of this.registrations) handle.remove();\n this.registrations.clear();\n this.nativeBackfilledTools.clear();\n this.removingNativeTools.clear();\n await this.mcpServer.close();\n })();\n return this.closePromise;\n }\n}\n\nexport interface ResourceDescriptor {\n uri: string;\n name: string;\n description?: string;\n mimeType?: string;\n read: (uri: URL, params?: Variables) => Promise<ReadResourceResult>;\n}\n\nexport interface PromptDescriptor {\n name: string;\n description?: string;\n argsSchema?: InputSchema;\n get: (args: Record<string, string>) => Promise<GetPromptResult>;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-b/webmcp-ts-sdk",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "Thin WebMCP-to-MCP v2 browser adapter with native Chrome tool mirroring",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adapter",
|
|
7
7
|
"ai-agents",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"claude",
|
|
13
13
|
"copilot",
|
|
14
14
|
"cursor",
|
|
15
|
+
"document-modelcontext",
|
|
15
16
|
"dynamic-tools",
|
|
16
17
|
"gemini",
|
|
17
18
|
"llm",
|
|
@@ -19,7 +20,6 @@
|
|
|
19
20
|
"mcp-client",
|
|
20
21
|
"mcp-server",
|
|
21
22
|
"model-context-protocol",
|
|
22
|
-
"navigator-modelcontext",
|
|
23
23
|
"openai",
|
|
24
24
|
"sdk",
|
|
25
25
|
"tool-registration",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"dist"
|
|
44
44
|
],
|
|
45
45
|
"type": "module",
|
|
46
|
+
"sideEffects": false,
|
|
46
47
|
"main": "./dist/index.js",
|
|
47
48
|
"module": "./dist/index.js",
|
|
48
49
|
"types": "./dist/index.d.ts",
|
|
@@ -57,29 +58,19 @@
|
|
|
57
58
|
"registry": "https://registry.npmjs.org/"
|
|
58
59
|
},
|
|
59
60
|
"dependencies": {
|
|
60
|
-
"@modelcontextprotocol/
|
|
61
|
-
"@mcp-b/webmcp-polyfill": "
|
|
62
|
-
"@mcp-b/webmcp-types": "
|
|
61
|
+
"@modelcontextprotocol/server": "2.0.0",
|
|
62
|
+
"@mcp-b/webmcp-polyfill": "5.0.0",
|
|
63
|
+
"@mcp-b/webmcp-types": "5.0.0"
|
|
63
64
|
},
|
|
64
65
|
"devDependencies": {
|
|
65
|
-
"@
|
|
66
|
+
"@modelcontextprotocol/client": "2.0.0",
|
|
67
|
+
"playwright": "^1.60.0",
|
|
66
68
|
"typescript": "^5.8.3",
|
|
67
|
-
"vite-plus": "^0.1.22"
|
|
68
|
-
|
|
69
|
-
"peerDependencies": {
|
|
70
|
-
"zod": "^3.25 || ^4.0",
|
|
71
|
-
"zod-to-json-schema": "^3.25.0"
|
|
72
|
-
},
|
|
73
|
-
"peerDependenciesMeta": {
|
|
74
|
-
"zod": {
|
|
75
|
-
"optional": true
|
|
76
|
-
},
|
|
77
|
-
"zod-to-json-schema": {
|
|
78
|
-
"optional": true
|
|
79
|
-
}
|
|
69
|
+
"vite-plus": "^0.1.22",
|
|
70
|
+
"vitest": "npm:@voidzero-dev/vite-plus-test@latest"
|
|
80
71
|
},
|
|
81
72
|
"engines": {
|
|
82
|
-
"node": ">=
|
|
73
|
+
"node": ">=20"
|
|
83
74
|
},
|
|
84
75
|
"scripts": {
|
|
85
76
|
"build": "vp pack",
|
|
@@ -89,9 +80,7 @@
|
|
|
89
80
|
"lint": "vp lint --fix",
|
|
90
81
|
"publish:dry": "pnpm publish --access public --dry-run",
|
|
91
82
|
"publish:npm": "pnpm publish --access public",
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"version:minor": "pnpm version minor --no-git-tag-version",
|
|
95
|
-
"version:patch": "pnpm version patch --no-git-tag-version"
|
|
83
|
+
"test": "vp test run",
|
|
84
|
+
"typecheck": "tsc --noEmit"
|
|
96
85
|
}
|
|
97
86
|
}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/browser-server.ts","../src/no-op-validator.ts","../src/index.ts"],"mappings":";;;;;;;;;;;;cAiDa,sBAAA;AAAA,UA8JI,uBAAA,SAAgC,aAAA;EAC/C,MAAA,GAAS,gBAAA;AAAA;;;AA/JX;;;;;AA8JA;;;;;cA2Ca,gBAAA,SAAyB,SAAA;EAAA,UAC1B,sBAAA;EAAA,QAEF,MAAA;EAAA,QACA,cAAA;EAAA,QACA,cAAA;EAAA,QACA,mBAAA;EAAA,QACA,gCAAA;EAAA,QACA,mBAAA;EAAA,QACA,MAAA;EAAA,QACA,oBAAA;EAAA,QACA,aAAA;EAAA,QACA,2BAAA;cAEI,UAAA,EAAY,gBAAA,EAAgB,OAAA,GAAU,uBAAA;EAyUM;;;;EAAA,QAnThD,oBAAA;EAAA,YA6BI,gBAAA,CAAA;EAAA,YAKA,cAAA,CAAA;EAAA,QAKJ,YAAA;EAAA,QAcA,sBAAA;EAAA,QAcA,uBAAA;EAAA,QAIA,WAAA;EAAA,QAMA,uBAAA;EAAA,QAcA,yBAAA;EAAA,QAaA,uBAAA;EAAA,QAcA,uBAAA;EAAA,QA+BA,wBAAA;EAAA,QAuEA,0BAAA;EAAA,QAsBA,0BAAA;EAAA,QA8BA,oBAAA;EAAA,IA+BJ,YAAA,CAAA,KAAkB,IAAA,EAAM,gBAAA,EAAkB,EAAA,EAAI,KAAA;EAAA,IAI9C,YAAA,CAAa,OAAA,IAAW,IAAA,EAAM,gBAAA,EAAkB,EAAA,EAAI,KAAA;EAIxD,gBAAA,CACE,IAAA,UACA,QAAA,EAAU,kCAAA,SACV,OAAA,aAAoB,uBAAA;EAKtB,mBAAA,CACE,IAAA,UACA,QAAA,EAAU,kCAAA,SACV,OAAA,aAAoB,oBAAA;EAKtB,aAAA,CAAc,KAAA,EAAO,KAAA;EAAA,QAIb,0BAAA;EAqBR,aAAA,CACE,KAAA,WAAgB,YAAA,IAChB,OAAA,GAAU,IAAA,UAAc,IAAA,EAAM,MAAA,sBAA4B,OAAA,CAAQ,YAAA;EAiC3D,YAAA,CACP,IAAA,EAAM,cAAA,EACN,OAAA,GAAU,+BAAA,GACT,OAAA;EA6PK;;;;EAxMR,eAAA,CAAA;EAAA,QAyBc,2BAAA;EAsBd,cAAA,CAAe,UAAA,WAAqB,yBAAA;EAiB3B,gBAAA,CAAiB,UAAA;IACxB,GAAA;IACA,IAAA;IACA,WAAA;IACA,QAAA;IACA,IAAA,GAAO,GAAA,EAAK,GAAA,EAAK,MAAA,GAAS,MAAA,qBAA2B,OAAA;MAAU,QAAA,EAAU,kBAAA;IAAA;EAAA;IACrE,UAAA;EAAA;EAmBG,cAAA,CAAe,UAAA;IACtB,IAAA;IACA,WAAA;IACA,UAAA,GAAa,WAAA;IACb,GAAA,GAAM,IAAA,EAAM,MAAA,sBAA4B,OAAA;MAAU,QAAA,EAAU,eAAA;IAAA;EAAA;IACxD,UAAA;EAAA;EAAA,QA0BE,4BAAA;EAAA,QAcA,iCAAA;EAaR,aAAA,CAAA,GAAiB,KAAA;IACf,GAAA;IACA,IAAA;IACA,WAAA;IACA,QAAA;EAAA;EAWI,YAAA,CAAa,GAAA,WAAc,OAAA;IAAU,QAAA,EAAU,kBAAA;EAAA;EASrD,WAAA,CAAA,GAAe,KAAA;IACb,IAAA;IACA,WAAA;IACA,SAAA,GAAY,KAAA;MAAQ,IAAA;MAAc,WAAA;MAAsB,QAAA;IAAA;EAAA;EAwBpD,SAAA,CACJ,IAAA,UACA,IAAA,GAAM,MAAA,oBACL,OAAA;IAAU,QAAA,EAAU,eAAA;EAAA;EAkBvB,SAAA,CAAA,GAAa,YAAA;EAAA,QAaL,wBAAA;EAAA,QAqBA,mBAAA;EAYF,QAAA,CAAA,GAAY,OAAA,CAAQ,oBAAA;EA7nBlB;;;;EA4pBO,iBAAA,CACb,IAAA;IAAQ,WAAA;EAAA,GACR,IAAA,EAAM,MAAA,+BACN,QAAA,WACC,OAAA,CAAQ,MAAA;EArfH;;;EAkhBO,kBAAA,CACb,IAAA;IAAQ,YAAA;EAAA,GACR,MAAA,WACA,QAAA,WACC,OAAA;EAzd2C;;;;;;;EAmgBxC,QAAA,CAAS,MAAA;IACb,IAAA;IACA,SAAA,GAAY,MAAA;EAAA,IACV,OAAA,CAAQ,YAAA;EA3fU;;;EA0gBtB,WAAA,CACE,IAAA,EAAM,oBAAA,EACN,aAAA,UACA,OAAA,GAAU,qCAAA,GACT,OAAA;EAvgBS;;;;;;EA8gBZ,WAAA,CAAY,IAAA,UAAc,IAAA,GAAO,MAAA,oBAA0B,OAAA,CAAQ,YAAA;EApgB3D;;;;;;;;;EAuiBO,OAAA,CAAQ,SAAA,EAAW,WAAA,GAAY,OAAA;EAyCxC,aAAA,CACJ,MAAA,EAAQ,sBAAA,YACR,OAAA,GAAU,gBAAA,GACT,OAAA,CAAQ,qBAAA;EAIL,WAAA,CACJ,MAAA,EAAQ,eAAA,YACR,OAAA,GAAU,gBAAA,GACT,OAAA,CAAQ,cAAA;AAAA;AAAA,UAOI,kBAAA;EACf,GAAA;EACA,IAAA;EACA,WAAA;EACA,QAAA;EACA,IAAA,GAAO,GAAA,EAAK,GAAA,EAAK,MAAA,GAAS,MAAA,qBAA2B,OAAA;IAAU,QAAA,EAAU,kBAAA;EAAA;AAAA;AAAA,UAG1D,gBAAA;EACf,IAAA;EACA,WAAA;EACA,UAAA,GAAa,WAAA;EACb,GAAA,GAAM,IAAA,EAAM,MAAA,sBAA4B,OAAA;IAAU,QAAA,EAAU,eAAA;EAAA;AAAA;;;;;;;;;;;;;;AArqC9D;;;;;AA8JA;;;;;;;;;AA2CA;;;;;AAzMA,cCba,uBAAA,YAAmC,mBAAA;EDyiBlB;;;;;;;ECjiB5B,YAAA,GAAA,CAAgB,OAAA,aAAoB,KAAA,cAAmB,yBAAA,CAA0B,CAAA;AAAA;;;KC2DvE,qBAAA,GAAwB,sBAAA;AAAA,KACxB,cAAA,GAAiB,qBAAA"}
|