simple-webmcp 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/internal/utils.ts","../src/internal/inferRuntime.ts","../src/internal/schema.ts","../src/internal/registry.ts","../src/internal/normalize.ts","../src/webmcp.ts","../src/constants.ts"],"names":["controller","entry"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Base error for simple-webmcp\n */\nexport class SimpleWebMCPError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = this.constructor.name;\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n cause: this.cause,\n };\n }\n}\n\nexport class NotSupportedError extends SimpleWebMCPError {\n constructor(message = 'WebMCP is not supported in this environment', opts?: { cause?: unknown }) {\n super(message, 'NOT_SUPPORTED', opts?.cause);\n }\n}\n\nexport class NotAllowedError extends SimpleWebMCPError {\n constructor(message = 'WebMCP tools are blocked by Permissions Policy', opts?: { cause?: unknown }) {\n super(message, 'NOT_ALLOWED', opts?.cause);\n }\n}\n\nexport class RegistrationError extends SimpleWebMCPError {\n constructor(message: string, opts?: { cause?: unknown }) {\n super(message, 'REGISTRATION_ERROR', opts?.cause);\n }\n}\n\nexport class ValidationError extends SimpleWebMCPError {\n constructor(message: string, opts?: { cause?: unknown }) {\n super(message, 'VALIDATION_ERROR', opts?.cause);\n }\n}\n\nexport class ConfigurationError extends SimpleWebMCPError {\n constructor(message: string, opts?: { cause?: unknown }) {\n super(message, 'CONFIGURATION_ERROR', opts?.cause);\n }\n}\n","import type { JsonSchema, ModelContextLike } from '../types.js';\n\n/**\n * Convert camelCase / PascalCase to snake_case for tool naming.\n * searchCustomers → search_customers\n * SearchCustomers → search_customers\n */\nexport function toSnakeCase(name: string): string {\n if (!name) return 'anonymous_tool';\n return name\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')\n .toLowerCase()\n .replace(/[^a-z0-9_]+/g, '_')\n .replace(/^_+|_+$/g, '') || 'anonymous_tool';\n}\n\n/**\n * Totally minimal doc extraction — best effort.\n * Full JSDoc inference is build-time. Runtime we just note presence.\n */\nexport function getFunctionName(fn: Function): string {\n return (fn as any).displayName || fn.name || '';\n}\n\n/**\n * Check if WebMCP is supported (native or polyfilled)\n */\nexport function isWebMCPSupported(): boolean {\n if (typeof document === 'undefined') return false;\n const docAny = document as any;\n return !!docAny.modelContext && typeof docAny.modelContext.registerTool === 'function';\n}\n\nexport function getModelContext(): ModelContextLike | null {\n if (typeof document === 'undefined') return null;\n const docAny = document as any;\n if (docAny.modelContext && typeof docAny.modelContext.registerTool === 'function') {\n return docAny.modelContext as ModelContextLike;\n }\n return null;\n}\n\n/**\n * Heuristic check if value looks like JSON Schema (vs StandardSchema)\n */\nexport function looksLikeJsonSchema(value: unknown): value is JsonSchema {\n if (!value || typeof value !== 'object') return false;\n const obj = value as Record<string, unknown>;\n // JSON Schema typically has `type` at top, no `~standard`\n if ('~standard' in obj) return false;\n // Has type or properties or $ref etc\n return (\n 'type' in obj ||\n 'properties' in obj ||\n '$ref' in obj ||\n 'anyOf' in obj ||\n 'oneOf' in obj ||\n 'allOf' in obj ||\n 'enum' in obj\n );\n}\n\n/**\n * Check if value is StandardSchema\n */\nexport function isStandardSchema(value: unknown): boolean {\n return (\n !!value &&\n typeof value === 'object' &&\n '~standard' in (value as any) &&\n (value as any)['~standard']?.validate != null &&\n typeof (value as any)['~standard'].validate === 'function'\n );\n}\n\n/**\n * Cheap JSDoc/description fallback — runtime can't parse JSDoc,\n * but we check if fn has __webmcpDescription attached by build plugin or manual.\n */\nexport function getDescription(fn: Function, override?: string): string {\n if (override != null) return override;\n const anyFn = fn as any;\n if (typeof anyFn.__webmcpDescription === 'string') return anyFn.__webmcpDescription;\n // No JSDoc at runtime — return empty and warn elsewhere\n return '';\n}\n\nlet warnedNoDesc = false;\nexport function warnNoDescription(fn: Function) {\n if (warnedNoDesc) return;\n // Only warn once per page load\n warnedNoDesc = true;\n if (typeof console !== 'undefined' && typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.warn(\n `[simple-webmcp] tool \"${getFunctionName(fn) || 'anonymous'}\" has no description. Add \\`description:\"...\"\\` or JSDoc. See https://github.com/emingure/simple-webmcp`,\n );\n } else if (typeof console !== 'undefined') {\n // In browser dev, also warn once\n // eslint-disable-next-line no-console\n console.warn(`[simple-webmcp] tool \"${getFunctionName(fn) || 'anonymous'}\" has no description.`);\n }\n}\n","import type { JsonSchema } from '../types.js';\n\n/**\n * Runtime inference — best-effort, confidence: low (§11).\n * We cannot know types from JS alone. We return placeholders and defaults detection.\n * Build-time TS/JSDoc inference (unplugin) will overwrite this in prod if enabled.\n */\n\nexport type InferredParam = {\n name: string;\n hasDefault: boolean;\n defaultValue?: unknown;\n // we don't know type; assume string-ish placeholder unless default hints\n};\n\nexport type RuntimeInference = {\n params: InferredParam[];\n isAsync: boolean;\n isObjectParam: boolean;\n objectKeys: string[]; // if first param is destructured object\n confidence: 'low';\n};\n\nfunction parseFunctionSource(fn: Function): string {\n try {\n return Function.prototype.toString.call(fn);\n } catch {\n return '';\n }\n}\n\n/**\n * Extract param list from fn.toString()\n * Handles:\n * - function foo(a,b=1, {x,y}= {}) {}\n * - (a,b) => {}\n * - async ({query, limit=20}) => {}\n * - class { method(a) {} }\n */\nexport function parseParamNames(fn: Function): InferredParam[] {\n const src = parseFunctionSource(fn);\n // Remove comments and newlines for easier parsing\n const clean = src.replace(/\\/\\*[\\s\\S]*?\\*\\/|\\/\\/.*/g, '').replace(/\\n/g, ' ');\n // Find first parentheses or destructured object\n // Match: function name?( ... ) or (...) => or async (... ) => etc.\n // We look for outermost `(` ... `)` before `=>` or `{`\n let paramBlock = '';\n const arrowIdx = clean.indexOf('=>');\n const firstParen = clean.indexOf('(');\n const firstBrace = clean.indexOf('{');\n\n // Prefer '(' block if exists before body\n if (firstParen !== -1) {\n // Find matching closing paren\n let depth = 0;\n let start = firstParen;\n let end = -1;\n for (let i = start; i < clean.length; i++) {\n const ch = clean[i];\n if (ch === '(') depth++;\n else if (ch === ')') {\n depth--;\n if (depth === 0) {\n end = i;\n break;\n }\n }\n }\n if (end !== -1) {\n paramBlock = clean.slice(start + 1, end);\n }\n } else if (arrowIdx !== -1) {\n // Single param arrow: x => {}\n const beforeArrow = clean.slice(0, arrowIdx).trim();\n // Could be `x` without parens\n const single = beforeArrow.split(/\\s+/).pop() || '';\n if (single && !single.includes(' ')) {\n paramBlock = single.replace(/^async\\s+/, '');\n }\n }\n\n if (!paramBlock.trim()) return [];\n\n // Split by comma not inside braces/brackets/parens\n const params: InferredParam[] = [];\n let current = '';\n let depthCurly = 0;\n let depthBracket = 0;\n let depthParen = 0;\n for (let i = 0; i < paramBlock.length; i++) {\n const ch = paramBlock[i];\n if (ch === '{') depthCurly++;\n else if (ch === '}') depthCurly--;\n else if (ch === '[') depthBracket++;\n else if (ch === ']') depthBracket--;\n else if (ch === '(') depthParen++;\n else if (ch === ')') depthParen--;\n if (ch === ',' && depthCurly === 0 && depthBracket === 0 && depthParen === 0) {\n const p = current.trim();\n if (p) params.push(parseSingleParam(p));\n current = '';\n } else {\n current += ch;\n }\n }\n const last = current.trim();\n if (last) params.push(parseSingleParam(last));\n return params;\n}\n\nfunction parseSingleParam(raw: string): InferredParam {\n // raw could be: \"a\", \"b=20\", \"{x, y}\", \"{query, limit=20}\", \"...rest\", \"a /* comment */ = 5\"\n let s = raw.trim();\n // Remove rest spread prefix\n if (s.startsWith('...')) s = s.slice(3).trim();\n // Check for default value `=`\n let hasDefault = false;\n let defaultValue: unknown = undefined;\n let eqIdx = -1;\n // Need to find `=` not inside braces\n let depth = 0;\n for (let i = 0; i < s.length; i++) {\n const ch = s[i];\n if (ch === '{' || ch === '(' || ch === '[') depth++;\n else if (ch === '}' || ch === ')' || ch === ']') depth--;\n else if (ch === '=' && depth === 0) {\n eqIdx = i;\n break;\n }\n }\n let namePart = s;\n if (eqIdx !== -1) {\n hasDefault = true;\n namePart = s.slice(0, eqIdx).trim();\n const defStr = s.slice(eqIdx + 1).trim();\n defaultValue = parseDefaultLiteral(defStr);\n }\n\n // If destructured object: {a, b=c, x: alias} etc.\n let name = namePart;\n // For destructuring, keep the raw interior for objectKeys extraction\n // But the param name for tool args is the object itself — we'll expand later\n // For now, return the raw destructure as name and let caller handle\n if (name.startsWith('{') && name.endsWith('}')) {\n // Keep as is — will be expanded\n name = name;\n } else if (name.startsWith('[')) {\n // array destructure — rare\n name = name;\n }\n return { name, hasDefault, defaultValue };\n}\n\nfunction parseDefaultLiteral(str: string): unknown {\n const t = str.trim().replace(/,$/, '');\n if (t === 'true') return true;\n if (t === 'false') return false;\n if (t === 'null') return null;\n if (t === 'undefined') return undefined;\n if (/^-?\\d+(\\.\\d+)?$/.test(t)) return Number(t);\n if ((t.startsWith('\"') && t.endsWith('\"')) || (t.startsWith(\"'\") && t.endsWith(\"'\")) || (t.startsWith('`') && t.endsWith('`'))) {\n return t.slice(1, -1);\n }\n if (t.startsWith('{') || t.startsWith('[')) return undefined; // complex literal — don't eval\n return undefined;\n}\n\n/**\n * Main runtime inference entry — returns low-confidence schema placeholder.\n */\nexport function inferRuntime(fn: Function): { inference: RuntimeInference; schema: JsonSchema } {\n const params = parseParamNames(fn);\n const src = parseFunctionSource(fn);\n const isAsync = /^\\s*async\\b/.test(src);\n\n // Determine if single param is destructured object → treat as object tool input\n let isObjectParam = false;\n let objectKeys: string[] = [];\n if (params.length === 1 && params[0].name.startsWith('{')) {\n isObjectParam = true;\n const inner = params[0].name.slice(1, -1); // strip { }\n // Split inner similarly to extract keys\n // e.g. \"query, limit=20, status\" → [\"query\",\"limit\",\"status\"]\n const keys: string[] = [];\n let cur = '';\n let d = 0;\n for (let i = 0; i < inner.length; i++) {\n const ch = inner[i];\n if (ch === '{' || ch === '[' || ch === '(') d++;\n else if (ch === '}' || ch === ']' || ch === ')') d--;\n if (ch === ',' && d === 0) {\n const k = cur.trim(); if (k) keys.push(extractKey(k)); cur = '';\n } else cur += ch;\n }\n const last = cur.trim(); if (last) keys.push(extractKey(last));\n objectKeys = keys.filter(Boolean);\n }\n\n const inference: RuntimeInference = {\n params,\n isAsync,\n isObjectParam,\n objectKeys,\n confidence: 'low',\n };\n\n // Build low-confidence schema: object with placeholder properties\n const schema: JsonSchema = {\n type: 'object',\n properties: {},\n required: [],\n additionalProperties: false,\n };\n\n if (isObjectParam && objectKeys.length > 0) {\n const props: Record<string, JsonSchema> = {};\n const required: string[] = [];\n // Try to know defaults per key\n // Re-parse inner with defaults mapping\n const innerRaw = params[0].name.slice(1, -1);\n const entries = splitObjectEntries(innerRaw);\n for (const entry of entries) {\n const { key, hasDefault, defaultValue } = entry;\n const prop: JsonSchema = {};\n // Best guess type from default value\n if (typeof defaultValue === 'number') prop.type = 'number';\n else if (typeof defaultValue === 'boolean') prop.type = 'boolean';\n // else leave type undefined (any) — valid placeholder but warn\n if (hasDefault && defaultValue !== undefined) prop.default = defaultValue;\n props[key] = prop;\n if (!hasDefault) required.push(key);\n }\n schema.properties = props;\n schema.required = required;\n } else if (params.length > 0) {\n // For multi-arg or single non-object param, create properties per param name\n // But if param was destructured without isObject detection fallback, still treat similarly\n const props: Record<string, JsonSchema> = {};\n const required: string[] = [];\n for (const p of params) {\n // For object-like still expand? we already handled single object case.\n // Now single 'query' etc.\n let key = p.name;\n // Strip alias `x: y` or `query: string` leftovers already removed; keep before colon/equals\n if (key.includes(':')) key = key.split(':')[0].trim();\n if (key.includes('=')) key = key.split('=')[0].trim();\n // Remove braces/brackets artifacts\n if (key.startsWith('{') || key.startsWith('[')) continue;\n if (!key) continue;\n const prop: JsonSchema = {};\n if (typeof p.defaultValue === 'number') prop.type = 'number';\n else if (typeof p.defaultValue === 'boolean') prop.type = 'boolean';\n if (p.hasDefault && p.defaultValue !== undefined) prop.default = p.defaultValue;\n props[key] = prop;\n if (!p.hasDefault) required.push(key);\n }\n schema.properties = props;\n schema.required = required;\n }\n\n return { inference, schema };\n}\n\nfunction extractKey(raw: string): string {\n let s = raw.trim();\n // Remove default `=`\n const eq = s.indexOf('=');\n if (eq !== -1) s = s.slice(0, eq).trim();\n // Remove alias `x: y` — keep x\n const colon = s.indexOf(':');\n if (colon !== -1) s = s.slice(0, colon).trim();\n // Remove spread\n if (s.startsWith('...')) s = s.slice(3).trim();\n // Remove braces\n s = s.replace(/^{|}$/g, '').trim();\n return s.split(/\\s+/)[0] || '';\n}\n\nfunction splitObjectEntries(inner: string): Array<{ key: string; hasDefault: boolean; defaultValue?: unknown }> {\n const res: Array<{ key: string; hasDefault: boolean; defaultValue?: unknown }> = [];\n let cur = '';\n let d = 0;\n for (let i = 0; i < inner.length; i++) {\n const ch = inner[i];\n if (ch === '{' || ch === '[' || ch === '(') d++;\n else if (ch === '}' || ch === ']' || ch === ')') d--;\n if (ch === ',' && d === 0) {\n if (cur.trim()) res.push(parseObjectEntry(cur.trim()));\n cur = '';\n } else cur += ch;\n }\n if (cur.trim()) res.push(parseObjectEntry(cur.trim()));\n return res;\n}\n\nfunction parseObjectEntry(raw: string): { key: string; hasDefault: boolean; defaultValue?: unknown } {\n let s = raw.trim();\n let hasDefault = false;\n let defaultValue: unknown;\n let eqIdx = s.indexOf('=');\n if (eqIdx !== -1) {\n hasDefault = true;\n const def = s.slice(eqIdx + 1).trim();\n defaultValue = parseDefaultLiteral(def);\n s = s.slice(0, eqIdx).trim();\n }\n // alias `prop: alias` → keep prop\n const colon = s.indexOf(':');\n if (colon !== -1) s = s.slice(0, colon).trim();\n const key = extractKey(s);\n return { key, hasDefault, defaultValue };\n}\n","import type { JsonSchema, StandardSchemaV1, FieldDefOrSchema } from '../types.js';\nimport { isStandardSchema, looksLikeJsonSchema } from './utils.js';\n\n// Global registry key for optional Zod converter (split to keep core lean, no hard dep)\nconst ZOD_CONVERTER_KEY = '__simpleWebmcp_zodConverter';\n\ntype ZodConverter = (schema: unknown) => JsonSchema | null;\n\nexport function registerZodConverter(fn: ZodConverter): void {\n (globalThis as any)[ZOD_CONVERTER_KEY] = fn;\n}\n\nfunction getZodConverter(): ZodConverter | null {\n return (globalThis as any)[ZOD_CONVERTER_KEY] ?? null;\n}\n\nfunction zodLikeToJsonSchema(schema: unknown): JsonSchema | null {\n const conv = getZodConverter();\n if (conv) {\n try {\n return conv(schema);\n } catch {\n return null;\n }\n }\n return null;\n}\n\n/**\n * Convert a StandardSchema (maybe Zod) to JSON Schema for WebMCP registration.\n * If conversion fails, returns null → caller uses fallback.\n * Core knows only JSON; Zod support is provided via `import 'simple-webmcp/zod'` which registers converter.\n */\nexport function standardSchemaToJsonSchema(schema: StandardSchemaV1): JsonSchema | null {\n const zodJson = zodLikeToJsonSchema(schema as unknown);\n if (zodJson) return zodJson;\n return null;\n}\n\n/**\n * Convert any `schema` option (JSON Schema or StandardSchema) to JSON Schema.\n * Returns { json, standard } where standard is kept for runtime validation if needed.\n */\nexport function normalizeSchemaInput(\n schema: JsonSchema | StandardSchemaV1 | undefined | null,\n): { json: JsonSchema | null; standard: StandardSchemaV1 | null } {\n if (!schema) return { json: null, standard: null };\n if (looksLikeJsonSchema(schema)) {\n return { json: schema as JsonSchema, standard: null };\n }\n if (isStandardSchema(schema)) {\n const std = schema as StandardSchemaV1;\n const json = standardSchemaToJsonSchema(std);\n return { json, standard: std };\n }\n // If it's a plain object that looks like Zod but without ~standard (older Zod), try convert via registered converter\n const maybeZodJson = zodLikeToJsonSchema(schema as unknown);\n if (maybeZodJson) return { json: maybeZodJson, standard: isStandardSchema(schema) ? (schema as StandardSchemaV1) : null };\n // Unknown — treat as JSON if it has properties, else null\n if (typeof schema === 'object' && schema !== null) {\n // Could be JSON schema without explicit type — treat as json\n return { json: schema as unknown as JsonSchema, standard: null };\n }\n return { json: null, standard: null };\n}\n\n/**\n * Convert a field definition (Partial<JsonSchema> | StandardSchema) to JsonSchema fragment.\n */\nexport function fieldDefToJsonSchema(field: FieldDefOrSchema): JsonSchema {\n if (!field) return {};\n if (isStandardSchema(field)) {\n const json = standardSchemaToJsonSchema(field as StandardSchemaV1);\n if (json) return json;\n // Fallback: unknown standard field → placeholder object\n return { type: 'string' };\n }\n // It's a FieldDef (Partial<JsonSchema>)\n return field as JsonSchema;\n}\n\n/**\n * Merge `fields` patch onto base schema per corrected hierarchy:\n * base = schema (whole) or inferred; fields decorates it.\n */\nexport function applyFieldsPatch(base: JsonSchema, fields?: Record<string, FieldDefOrSchema>): JsonSchema {\n if (!fields || Object.keys(fields).length === 0) return base;\n const result: JsonSchema = {\n ...base,\n properties: { ...(base.properties || {}) },\n required: [...(base.required || [])],\n };\n if (!result.properties) result.properties = {};\n if (!result.required) result.required = [];\n\n for (const [key, field] of Object.entries(fields)) {\n const isStd = isStandardSchema(field);\n if (isStd) {\n const json = standardSchemaToJsonSchema(field as StandardSchemaV1);\n const fragment = json ?? { type: 'string' };\n result.properties[key] = fragment;\n const anyField = field as any;\n const isOpt = anyField?._def?.typeName === 'ZodOptional' || anyField?.isOptional?.() === true;\n if (!isOpt) {\n if (!result.required.includes(key)) result.required.push(key);\n } else {\n result.required = result.required.filter((k) => k !== key);\n }\n const desc = anyField?.description ?? anyField?._def?.description;\n if (desc && !(result.properties[key] as any).description) (result.properties[key] as any).description = desc;\n } else {\n const patch = field as JsonSchema;\n const existing = (result.properties[key] as JsonSchema) || {};\n const merged: JsonSchema = { ...existing, ...patch };\n result.properties[key] = merged;\n if ('required' in patch) {\n const req = (patch as any).required;\n if (req === false) {\n result.required = result.required.filter((k) => k !== key);\n delete (merged as any).required;\n } else if (req === true) {\n if (!result.required.includes(key)) result.required.push(key);\n delete (merged as any).required;\n }\n } else {\n if (!(key in (base.properties || {})) && !(patch as any).required) {\n const hasDefault = 'default' in patch;\n if (!hasDefault && !result.required.includes(key)) result.required.push(key);\n }\n }\n }\n }\n\n if (result.required && result.required.length === 0) delete (result as any).required;\n return result;\n}\n\n/**\n * Build final inputSchema per hierarchy:\n * 1. whole schema (schema) if json available → base\n * 2. else inferred schema\n * 3. then fields patch\n */\nexport function buildFinalInputSchema(opts: {\n wholeSchema?: JsonSchema | StandardSchemaV1;\n inferred: JsonSchema;\n fields?: Record<string, FieldDefOrSchema>;\n}): { json: JsonSchema; standard: StandardSchemaV1 | null } {\n const wholeNorm = normalizeSchemaInput(opts.wholeSchema);\n let baseJson: JsonSchema;\n let standard: StandardSchemaV1 | null = wholeNorm.standard;\n\n if (wholeNorm.json) {\n baseJson = wholeNorm.json;\n } else if (wholeNorm.standard && !wholeNorm.json) {\n baseJson = opts.inferred;\n } else {\n baseJson = opts.inferred;\n }\n\n if (!baseJson.type) baseJson.type = 'object';\n if (!baseJson.properties) baseJson.properties = {};\n if (baseJson.additionalProperties == null) baseJson.additionalProperties = false;\n\n const patched = applyFieldsPatch(baseJson, opts.fields);\n\n return { json: patched, standard };\n}\n\n/**\n * Normalize outputSchema similarly but without fields\n */\nexport function normalizeOutputSchema(schema?: JsonSchema | StandardSchemaV1): { json?: JsonSchema; standard?: StandardSchemaV1 } {\n if (!schema) return {};\n const norm = normalizeSchemaInput(schema);\n if (norm.json) return { json: norm.json, standard: norm.standard ?? undefined };\n if (norm.standard) return { standard: norm.standard };\n return {};\n}\n","import type { ToolContract, RegistrationStatus, ModelContextLike } from '../types.js';\nimport { getModelContext, isWebMCPSupported } from './utils.js';\nimport { RegistrationError, NotSupportedError, NotAllowedError } from '../errors.js';\nimport { wrapExecute } from './normalize.js';\n\n/**\n * Global tool registry — tracks registration state per tool name.\n * Handles async registerTool (Promise<void>) + AbortSignal lifecycle per WebMCP spec (current types).\n * Deduplicates StrictMode double-mount.\n */\n\ntype Entry = {\n name: string;\n controller: AbortController;\n status: RegistrationStatus;\n promise: Promise<void> | null;\n unregister: () => void;\n};\n\nclass Registry {\n private entries = new Map<string, Entry>();\n // expose for devtools/tests\n list(): Array<{ name: string; status: RegistrationStatus }> {\n return Array.from(this.entries.values()).map((e) => ({ name: e.name, status: e.status }));\n }\n\n clear() {\n for (const e of this.entries.values()) {\n try { e.controller.abort(); } catch {}\n }\n this.entries.clear();\n }\n\n isRegistered(name: string): boolean {\n return this.entries.get(name)?.status === 'registered';\n }\n\n getStatus(name: string): RegistrationStatus {\n return this.entries.get(name)?.status ?? 'unregistered';\n }\n\n async register(\n contract: ToolContract,\n opts?: { signal?: AbortSignal; execute?: (args: unknown, ctx?: unknown) => Promise<any> },\n ): Promise<() => void> {\n const name = contract.name;\n const existing = this.entries.get(name);\n if (existing && (existing.status === 'registered' || existing.status === 'registering')) {\n // Dedup — return existing unregister\n return existing.unregister;\n }\n\n if (!isWebMCPSupported()) {\n // Graceful no-op — still track as registered for polyfilled later? but error for now\n // For tests, mock document.modelContext; if missing, do no-op but resolve.\n // We don't throw NotSupportedError unless strict? For 0.1, just no-op and return no-op unregister.\n // Caller can check isWebMCPSupported separately.\n const controller = new AbortController();\n const entry: Entry = {\n name,\n controller,\n status: 'registered',\n promise: Promise.resolve(),\n unregister: () => {\n try { controller.abort(); } catch {}\n this.entries.delete(name);\n },\n };\n // Wire external abort\n if (opts?.signal) {\n if (opts.signal.aborted) {\n controller.abort();\n this.entries.delete(name);\n return () => {};\n }\n opts.signal.addEventListener('abort', () => {\n try { controller.abort(); } catch {}\n this.entries.delete(name);\n }, { once: true });\n }\n this.entries.set(name, entry);\n return entry.unregister;\n }\n\n const modelContext = getModelContext();\n if (!modelContext) throw new NotSupportedError();\n\n const controller = new AbortController();\n // Wire external signal to internal\n if (opts?.signal) {\n if (opts.signal.aborted) {\n controller.abort();\n } else {\n opts.signal.addEventListener(\n 'abort',\n () => {\n try {\n controller.abort();\n } catch {}\n },\n { once: true },\n );\n }\n }\n\n const entry: Entry = {\n name,\n controller,\n status: 'registering',\n promise: null,\n unregister: () => {\n if (entry.status === 'registered' || entry.status === 'registering') {\n entry.status = 'unregistering';\n try {\n controller.abort();\n } catch {}\n // Small delay to allow spec to unregister\n entry.status = 'unregistered';\n this.entries.delete(name);\n }\n },\n };\n this.entries.set(name, entry);\n\n const wrappedExecute = opts?.execute ?? (async (args: unknown) => ({ content: [{ type: 'text', text: `no execute for ${name}` }] }));\n\n try {\n const regPromise = (modelContext as ModelContextLike).registerTool(\n {\n name: contract.name,\n description: contract.description,\n inputSchema: contract.inputSchema,\n outputSchema: contract.outputSchema,\n annotations: contract.annotations,\n execute: wrappedExecute,\n },\n { signal: controller.signal },\n );\n entry.promise = regPromise;\n await regPromise;\n // If not aborted in-flight\n if (controller.signal.aborted) {\n entry.status = 'unregistered';\n this.entries.delete(name);\n } else {\n entry.status = 'registered';\n }\n // Cleanup on abort signal\n controller.signal.addEventListener('abort', () => {\n entry.status = 'unregistered';\n this.entries.delete(name);\n }, { once: true });\n\n return entry.unregister;\n } catch (err: any) {\n entry.status = 'error';\n this.entries.delete(name);\n const msg = err?.message || String(err);\n // Detect Permissions Policy NotAllowedError per spec\n if (err?.name === 'NotAllowedError' || /NotAllowedError|Permissions Policy|blocked/i.test(msg)) {\n throw new NotAllowedError(msg, { cause: err });\n }\n throw new RegistrationError(`Failed to register tool \"${name}\": ${msg}`, { cause: err });\n }\n }\n\n unregister(name: string) {\n const entry = this.entries.get(name);\n if (!entry) return;\n try {\n entry.controller.abort();\n } catch {}\n this.entries.delete(name);\n }\n}\n\nexport const registry = new Registry();\n\n// Export wrap helper for external tests\nexport function getRegistry() {\n return registry;\n}\n","/**\n * Normalize execute return values per WebMCP spec.\n * WebMCP expects { content: [{type:'text', text: ...}], isError? }\n * We allow fn to return string, object, or already-normalized shape.\n */\n\nexport type NormalizedResult = {\n content: Array<{ type: 'text'; text: string } | { type: string; [k: string]: unknown }>;\n isError?: boolean;\n // allow raw passthrough for custom\n [k: string]: unknown;\n};\n\nexport function normalizeResult(value: unknown): NormalizedResult {\n if (value == null) {\n return { content: [{ type: 'text', text: '' }] };\n }\n if (typeof value === 'string') {\n return { content: [{ type: 'text', text: value }] };\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return { content: [{ type: 'text', text: String(value) }] };\n }\n // Already normalized?\n if (typeof value === 'object' && value !== null && 'content' in (value as any) && Array.isArray((value as any).content)) {\n return value as NormalizedResult;\n }\n // If Error-like object with isError?\n if (typeof value === 'object' && value !== null && 'isError' in (value as any)) {\n // Could be { isError:true, content:[...] } already — covered above\n // Otherwise wrap\n if ('content' in (value as any)) return value as NormalizedResult;\n }\n // Fallback: JSON stringify\n try {\n const text = JSON.stringify(value, null, 2);\n return { content: [{ type: 'text', text }] };\n } catch {\n return { content: [{ type: 'text', text: String(value) }] };\n }\n}\n\nexport function normalizeError(err: unknown): NormalizedResult {\n const message = err instanceof Error ? err.message : typeof err === 'string' ? err : (() => {\n try { return JSON.stringify(err); } catch { return String(err); }\n })();\n return {\n content: [{ type: 'text', text: `Error: ${message}` }],\n isError: true,\n };\n}\n\n/**\n * Wrap an execute fn to handle:\n * - args: object (WebMCP passes single object) vs spread\n * - async errors\n * - result normalization\n * For 0.1 we assume fn expects single object param (preferred).\n * For multi-arg legacy, user should use webmcp.bind (deferred) — here we provide auto-spread fallback heuristic.\n */\nexport function wrapExecute<F extends (...args: any) => any>(\n fn: F,\n opts?: { argMode?: 'object' | 'spread' },\n): (args: unknown, ctx?: unknown) => Promise<NormalizedResult> {\n return async (args: unknown, _ctx?: unknown) => {\n try {\n let result: unknown;\n // If args is an object and fn.length === 1 or opts explicit object, call fn(args)\n // If fn.length > 1 and args is object, we try to spread values in param order? For 0.1 we call with object.\n // We detect fn expecting spread by `fn.length > 1` and object keys match param names heuristic? Keep simple: always object.\n // The only spread case is for bind() which we defer, so keep object.\n const mode = opts?.argMode ?? 'object';\n if (mode === 'spread' && args && typeof args === 'object' && !Array.isArray(args)) {\n const values = Object.values(args as Record<string, unknown>);\n result = await (fn as any)(...values);\n } else {\n // object\n // If fn expects 0 args and args is empty object, still pass nothing? But passing {} is ok.\n // If fn signature is positional, passing object may be wrong; but we mandate object for 0.1. Document accordingly.\n result = await (fn as any)(args);\n }\n // If result is promise-like already awaited, normalize\n return normalizeResult(result);\n } catch (err) {\n return normalizeError(err);\n }\n };\n}\n","import type { WebMCPOptions, WebMCPTool, ToolContract, RegistrationStatus } from './types.js';\nimport type { JsonSchema } from './types.js';\nimport { SimpleWebMCPError, ConfigurationError } from './errors.js';\nimport { toSnakeCase, getFunctionName, warnNoDescription, isWebMCPSupported } from './internal/utils.js';\nimport { inferRuntime } from './internal/inferRuntime.js';\nimport { buildFinalInputSchema, normalizeOutputSchema } from './internal/schema.js';\nimport { registry } from './internal/registry.js';\nimport { wrapExecute } from './internal/normalize.js';\n\n/**\n * Callable wrapper factory — core of simple-webmcp.\n * Hierarchy: schema (whole) > inferred > fields patch > metadata\n */\n\nfunction resolveScope(opts?: WebMCPOptions<any>): 'global' | 'scoped' | 'manual' {\n if (opts?.scope) return opts.scope;\n if (opts?.global) return 'global';\n // Default per plan: scoped — requires useWebMCP; manual if enabled false?\n return 'scoped';\n}\n\nfunction warnIfNoScopeInServerContext() {\n // no-op\n}\n\nexport function webmcp<F extends (...args: any) => any>(fn: F, options?: WebMCPOptions<F>): WebMCPTool<F> {\n if (typeof fn !== 'function') {\n throw new ConfigurationError('webmcp(fn, opts) — first argument must be a function');\n }\n\n // Prevent double wrap\n const anyFn = fn as any;\n if (anyFn.__webmcpBrand === true && anyFn.definition) {\n // Already a tool — apply new options as patch? For 0.1, return as is if no opts, else merge\n if (!options || Object.keys(options).length === 0) return anyFn as WebMCPTool<F>;\n // Merge patch onto existing tool's schema\n // For simplicity, re-wrap original __fn\n const original = (anyFn.__fn ?? fn) as F;\n return webmcp(original, { ...(anyFn.__webmcpOptions || {}), ...options } as WebMCPOptions<F>);\n }\n\n const name = options?.name ?? toSnakeCase(getFunctionName(fn));\n if (!name) throw new ConfigurationError('Tool name could not be inferred — pass {name:\"my_tool\"}');\n let description = options?.description ?? (anyFn.__webmcpDescription as string | undefined) ?? '';\n if (!description) {\n warnNoDescription(fn);\n description = '';\n }\n\n // Strict check — if strict and fn has no types/fields/schema, throw\n const hasSchema = !!options?.schema;\n const hasFields = !!options?.fields && Object.keys(options.fields).length > 0;\n if (options?.strict && !hasSchema && !hasFields) {\n // Try infer; strict requires at least one typed property (type present) — runtime `{}` is low confidence\n const { schema: inferred } = inferRuntime(fn);\n const props = (inferred.properties || {}) as Record<string, any>;\n const propKeys = Object.keys(props);\n const hasTypedProps = propKeys.length > 0 && propKeys.some((k) => !!props[k]?.type);\n if (!hasTypedProps) {\n throw new ConfigurationError(\n `webmcp strict: could not infer schema for \"${name}\" — add TypeScript types, JSDoc, {schema} or {fields}`,\n );\n }\n }\n\n // Build schemas\n const { schema: inferredSchema } = inferRuntime(fn);\n const { json: finalInput, standard } = buildFinalInputSchema({\n wholeSchema: options?.schema,\n inferred: inferredSchema,\n fields: options?.fields,\n });\n\n const outNorm = normalizeOutputSchema(options?.outputSchema);\n const annotations = options?.annotations;\n\n const contract: ToolContract = {\n name,\n description,\n inputSchema: finalInput,\n outputSchema: outNorm.json,\n annotations,\n };\n\n // Detect WebMCP availability at create time for enabled default?\n const enabled = options?.enabled ?? true;\n\n // Create callable wrapper\n // We use a function that forwards to original fn, preserving this, length, name where possible\n const wrapper = function (this: unknown, ...args: any[]) {\n return (fn as any).apply(this, args);\n } as unknown as WebMCPTool<F>;\n\n // Copy over properties from original for debuggability? Not enumerable\n try {\n Object.defineProperty(wrapper, 'name', { value: fn.name || name, configurable: true });\n } catch {}\n try {\n Object.defineProperty(wrapper, 'length', { value: fn.length, configurable: true });\n } catch {}\n\n // Internal slots\n let status: RegistrationStatus = 'unregistered';\n let registrationPromise: Promise<void> | null = null;\n let unregisterFn: (() => void) | null = null;\n let activeController: AbortController | null = null;\n\n const wrappedExec = wrapExecute(fn as any);\n\n const toolWrapper = wrapper as WebMCPTool<F>;\n // Brand\n (toolWrapper as any).__webmcpBrand = true;\n (toolWrapper as any).__fn = fn;\n (toolWrapper as any).__webmcpOptions = options;\n if (standard) (toolWrapper as any).__standardSchema = standard;\n if (outNorm.standard) (toolWrapper as any).__outputStandardSchema = outNorm.standard;\n (toolWrapper as any).tool = contract;\n (toolWrapper as any).definition = contract;\n\n Object.defineProperty(toolWrapper, 'status', {\n get() { return status; },\n enumerable: true,\n });\n Object.defineProperty(toolWrapper, 'registration', {\n get() { return registrationPromise; },\n enumerable: true,\n });\n\n toolWrapper.isRegistered = () => status === 'registered';\n\n toolWrapper.register = async (opts?: { signal?: AbortSignal }) => {\n if (status === 'registered' || status === 'registering') {\n // already registered — return existing unregister\n return unregisterFn ?? (() => toolWrapper.unregister());\n }\n if (enabled === false) {\n // inert\n return () => {};\n }\n status = 'registering';\n const controller = new AbortController();\n activeController = controller;\n\n // Wire external signal\n if (opts?.signal) {\n if (opts.signal.aborted) {\n controller.abort();\n status = 'unregistered';\n activeController = null;\n return () => {};\n }\n opts.signal.addEventListener('abort', () => {\n try { controller.abort(); } catch {}\n toolWrapper.unregister();\n }, { once: true });\n }\n\n controller.signal.addEventListener('abort', () => {\n if (status !== 'unregistered') status = 'unregistered';\n activeController = null;\n }, { once: true });\n\n try {\n const unregister = await registry.register(contract, {\n signal: controller.signal,\n execute: wrappedExec as any,\n });\n // registry handles dupe and polyfill\n unregisterFn = unregister;\n registrationPromise = Promise.resolve();\n if (controller.signal.aborted) {\n status = 'unregistered';\n } else {\n status = 'registered';\n }\n return () => {\n try { unregister(); } catch {}\n status = 'unregistered';\n activeController = null;\n unregisterFn = null;\n };\n } catch (err) {\n status = 'error';\n registrationPromise = Promise.reject(err);\n // Re-throw as typed\n if (err instanceof SimpleWebMCPError) throw err;\n throw err;\n }\n };\n\n toolWrapper.unregister = () => {\n if (status === 'unregistered') return;\n status = 'unregistering';\n try {\n registry.unregister(contract.name);\n } catch {}\n try {\n activeController?.abort();\n } catch {}\n status = 'unregistered';\n activeController = null;\n unregisterFn = null;\n registrationPromise = null;\n };\n\n // Auto global if scope global and enabled\n const scope = resolveScope(options);\n if (scope === 'global' && enabled !== false) {\n // Defer to next tick to allow import order; but also handle document not yet ready\n // Only register if in browser (document exists). If not, warn and keep status unregistered until manual.\n if (typeof document !== 'undefined') {\n // Use microtask\n queueMicrotask(() => {\n // Don't await — fire and forget, but catch\n toolWrapper.register().catch(() => {});\n });\n } else {\n // SSR — no-op until client hydrates; user should use useWebMCP or call register on client\n // Keep as is\n }\n }\n\n // Preserve original toString etc for inference?\n (toolWrapper as any).toString = fn.toString.bind(fn);\n\n return toolWrapper;\n}\n\n// Namespace helpers — webmcp.global\n(webmcp as any).global = function global<F extends (...args: any) => any>(fn: F, opts?: Omit<WebMCPOptions<F>, 'global' | 'scope'>): WebMCPTool<F> {\n return webmcp(fn, { ...(opts as any), global: true } as WebMCPOptions<F>);\n};\n\n// Optional internal check\n(webmcp as any).isWebMCPTool = function isWebMCPTool(v: unknown): boolean {\n return !!(v as any)?.__webmcpBrand;\n};\n\nexport default webmcp;\n","export const SDK_VERSION = '0.1.0';\nexport const DEFAULT_TOOL_ANNOTATIONS = {} as const;\n"]}
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ // src/polyfill.ts
6
+ var installed = false;
7
+ function installPolyfill(opts) {
8
+ if (installed && !opts?.force) return true;
9
+ if (typeof document === "undefined") return false;
10
+ const docAny = document;
11
+ if (docAny.modelContext && !opts?.force) {
12
+ installed = true;
13
+ return true;
14
+ }
15
+ const tools = /* @__PURE__ */ new Map();
16
+ const polyfill = {
17
+ _isPolyfill: true,
18
+ _tools: tools,
19
+ async registerTool(def, opts2) {
20
+ const name = def?.name;
21
+ if (!name) throw new Error("registerTool: name required");
22
+ if (tools.has(name)) {
23
+ return;
24
+ }
25
+ tools.set(name, { def, signal: opts2?.signal });
26
+ if (opts2?.signal) {
27
+ const onAbort = () => {
28
+ if (tools.get(name)?.signal === opts2.signal) tools.delete(name);
29
+ };
30
+ if (opts2.signal.aborted) {
31
+ tools.delete(name);
32
+ } else {
33
+ opts2.signal.addEventListener("abort", onAbort, { once: true });
34
+ }
35
+ }
36
+ },
37
+ listTools() {
38
+ return Array.from(tools.values()).map((v) => v.def);
39
+ },
40
+ async invokeTool(name, args) {
41
+ const entry = tools.get(name);
42
+ if (!entry) throw new Error(`Tool ${name} not found`);
43
+ return entry.def.execute(args);
44
+ }
45
+ };
46
+ docAny.modelContext = polyfill;
47
+ installed = true;
48
+ return true;
49
+ }
50
+ function isPolyfilled() {
51
+ if (typeof document === "undefined") return false;
52
+ return !!document.modelContext?._isPolyfill;
53
+ }
54
+ if (typeof document !== "undefined") {
55
+ queueMicrotask(() => {
56
+ const docAny = document;
57
+ if (!docAny.modelContext) {
58
+ installPolyfill();
59
+ }
60
+ });
61
+ }
62
+ var polyfill_default = installPolyfill;
63
+
64
+ exports.default = polyfill_default;
65
+ exports.installPolyfill = installPolyfill;
66
+ exports.isPolyfilled = isPolyfilled;
67
+ //# sourceMappingURL=polyfill.cjs.map
68
+ //# sourceMappingURL=polyfill.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/polyfill.ts"],"names":["opts"],"mappings":";;;;;AAgBA,IAAI,SAAA,GAAY,KAAA;AAET,SAAS,gBAAgB,IAAA,EAAiC;AAC/D,EAAA,IAAI,SAAA,IAAa,CAAC,IAAA,EAAM,KAAA,EAAO,OAAO,IAAA;AACtC,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,KAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,QAAA;AACf,EAAA,IAAI,MAAA,CAAO,YAAA,IAAgB,CAAC,IAAA,EAAM,KAAA,EAAO;AACvC,IAAA,SAAA,GAAY,IAAA;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAIA,EAAA,MAAM,KAAA,uBAAY,GAAA,EAMhB;AAEF,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,WAAA,EAAa,IAAA;AAAA,IACb,MAAA,EAAQ,KAAA;AAAA,IACR,MAAM,YAAA,CAAa,GAAA,EAAUA,KAAAA,EAAiC;AAC5D,MAAA,MAAM,OAAO,GAAA,EAAK,IAAA;AAClB,MAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,MAAM,6BAA6B,CAAA;AACxD,MAAA,IAAI,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,EAAG;AAEnB,QAAA;AAAA,MACF;AACA,MAAA,KAAA,CAAM,IAAI,IAAA,EAAM,EAAE,KAAK,MAAA,EAAQA,KAAAA,EAAM,QAAQ,CAAA;AAC7C,MAAA,IAAIA,OAAM,MAAA,EAAQ;AAChB,QAAA,MAAM,UAAU,MAAM;AACpB,UAAA,IAAI,KAAA,CAAM,IAAI,IAAI,CAAA,EAAG,WAAWA,KAAAA,CAAK,MAAA,EAAQ,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA;AAAA,QAChE,CAAA;AACA,QAAA,IAAIA,KAAAA,CAAK,OAAO,OAAA,EAAS;AACvB,UAAA,KAAA,CAAM,OAAO,IAAI,CAAA;AAAA,QACnB,CAAA,MAAO;AACL,UAAAA,KAAAA,CAAK,OAAO,gBAAA,CAAiB,OAAA,EAAS,SAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,QAC/D;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,SAAA,GAAY;AACV,MAAA,OAAO,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,MAAA,EAAQ,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAG,CAAA;AAAA,IACpD,CAAA;AAAA,IACA,MAAM,UAAA,CAAW,IAAA,EAAc,IAAA,EAAe;AAC5C,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA;AAC5B,MAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,KAAA,CAAM,CAAA,KAAA,EAAQ,IAAI,CAAA,UAAA,CAAY,CAAA;AACpD,MAAA,OAAO,KAAA,CAAM,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA;AAAA,IAC/B;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,YAAA,GAAe,QAAA;AACtB,EAAA,SAAA,GAAY,IAAA;AACZ,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,YAAA,GAAwB;AACtC,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,KAAA;AAC5C,EAAA,OAAO,CAAC,CAAE,QAAA,CAAiB,YAAA,EAAc,WAAA;AAC3C;AAGA,IAAI,OAAO,aAAa,WAAA,EAAa;AAEnC,EAAA,cAAA,CAAe,MAAM;AACnB,IAAA,MAAM,MAAA,GAAS,QAAA;AACf,IAAA,IAAI,CAAC,OAAO,YAAA,EAAc;AACxB,MAAA,eAAA,EAAgB;AAAA,IAClB;AAAA,EACF,CAAC,CAAA;AACH;AAEA,IAAO,gBAAA,GAAQ","file":"polyfill.cjs","sourcesContent":["/**\n * simple-webmcp/polyfill — adapter entry.\n * We do not hard-depend on a specific shim; we attach a minimal no-op polyfill that\n * allows `registry.register` to succeed in non-Chrome environments for dev/testing.\n * In production Chrome with native WebMCP, this is a no-op (detected via native presence).\n *\n * For full polyfill fidelity, user can `npm i @mcp-b/global` and `import '@mcp-b/global/polyfill'`\n * before importing simple-webmcp; our adapter detects `document.modelContext` already present and skips.\n *\n * This thin adapter exists to shield users from spec churn (per review §17).\n */\n\nexport type PolyfillOptions = {\n force?: boolean;\n};\n\nlet installed = false;\n\nexport function installPolyfill(opts?: PolyfillOptions): boolean {\n if (installed && !opts?.force) return true;\n if (typeof document === 'undefined') return false;\n const docAny = document as any;\n if (docAny.modelContext && !opts?.force) {\n installed = true;\n return true;\n }\n\n // Minimal polyfill — tracks tools in memory, invokes via same ABI.\n // Not a full MCP transport; sufficient for registry + tests + devtools.\n const tools = new Map<\n string,\n {\n def: any;\n signal?: AbortSignal;\n }\n >();\n\n const polyfill = {\n _isPolyfill: true,\n _tools: tools,\n async registerTool(def: any, opts?: { signal?: AbortSignal }) {\n const name = def?.name;\n if (!name) throw new Error('registerTool: name required');\n if (tools.has(name)) {\n // Dedup like native — ignore second registration\n return;\n }\n tools.set(name, { def, signal: opts?.signal });\n if (opts?.signal) {\n const onAbort = () => {\n if (tools.get(name)?.signal === opts.signal) tools.delete(name);\n };\n if (opts.signal.aborted) {\n tools.delete(name);\n } else {\n opts.signal.addEventListener('abort', onAbort, { once: true });\n }\n }\n },\n listTools() {\n return Array.from(tools.values()).map((v) => v.def);\n },\n async invokeTool(name: string, args: unknown) {\n const entry = tools.get(name);\n if (!entry) throw new Error(`Tool ${name} not found`);\n return entry.def.execute(args);\n },\n };\n\n docAny.modelContext = polyfill;\n installed = true;\n return true;\n}\n\nexport function isPolyfilled(): boolean {\n if (typeof document === 'undefined') return false;\n return !!(document as any).modelContext?._isPolyfill;\n}\n\n// Auto-install side-effect import: `import 'simple-webmcp/polyfill'`\nif (typeof document !== 'undefined') {\n // Defer to next tick to allow native detection first\n queueMicrotask(() => {\n const docAny = document as any;\n if (!docAny.modelContext) {\n installPolyfill();\n }\n });\n}\n\nexport default installPolyfill;\n"]}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * simple-webmcp/polyfill — adapter entry.
3
+ * We do not hard-depend on a specific shim; we attach a minimal no-op polyfill that
4
+ * allows `registry.register` to succeed in non-Chrome environments for dev/testing.
5
+ * In production Chrome with native WebMCP, this is a no-op (detected via native presence).
6
+ *
7
+ * For full polyfill fidelity, user can `npm i @mcp-b/global` and `import '@mcp-b/global/polyfill'`
8
+ * before importing simple-webmcp; our adapter detects `document.modelContext` already present and skips.
9
+ *
10
+ * This thin adapter exists to shield users from spec churn (per review §17).
11
+ */
12
+ type PolyfillOptions = {
13
+ force?: boolean;
14
+ };
15
+ declare function installPolyfill(opts?: PolyfillOptions): boolean;
16
+ declare function isPolyfilled(): boolean;
17
+
18
+ export { type PolyfillOptions, installPolyfill as default, installPolyfill, isPolyfilled };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * simple-webmcp/polyfill — adapter entry.
3
+ * We do not hard-depend on a specific shim; we attach a minimal no-op polyfill that
4
+ * allows `registry.register` to succeed in non-Chrome environments for dev/testing.
5
+ * In production Chrome with native WebMCP, this is a no-op (detected via native presence).
6
+ *
7
+ * For full polyfill fidelity, user can `npm i @mcp-b/global` and `import '@mcp-b/global/polyfill'`
8
+ * before importing simple-webmcp; our adapter detects `document.modelContext` already present and skips.
9
+ *
10
+ * This thin adapter exists to shield users from spec churn (per review §17).
11
+ */
12
+ type PolyfillOptions = {
13
+ force?: boolean;
14
+ };
15
+ declare function installPolyfill(opts?: PolyfillOptions): boolean;
16
+ declare function isPolyfilled(): boolean;
17
+
18
+ export { type PolyfillOptions, installPolyfill as default, installPolyfill, isPolyfilled };
@@ -0,0 +1,62 @@
1
+ // src/polyfill.ts
2
+ var installed = false;
3
+ function installPolyfill(opts) {
4
+ if (installed && !opts?.force) return true;
5
+ if (typeof document === "undefined") return false;
6
+ const docAny = document;
7
+ if (docAny.modelContext && !opts?.force) {
8
+ installed = true;
9
+ return true;
10
+ }
11
+ const tools = /* @__PURE__ */ new Map();
12
+ const polyfill = {
13
+ _isPolyfill: true,
14
+ _tools: tools,
15
+ async registerTool(def, opts2) {
16
+ const name = def?.name;
17
+ if (!name) throw new Error("registerTool: name required");
18
+ if (tools.has(name)) {
19
+ return;
20
+ }
21
+ tools.set(name, { def, signal: opts2?.signal });
22
+ if (opts2?.signal) {
23
+ const onAbort = () => {
24
+ if (tools.get(name)?.signal === opts2.signal) tools.delete(name);
25
+ };
26
+ if (opts2.signal.aborted) {
27
+ tools.delete(name);
28
+ } else {
29
+ opts2.signal.addEventListener("abort", onAbort, { once: true });
30
+ }
31
+ }
32
+ },
33
+ listTools() {
34
+ return Array.from(tools.values()).map((v) => v.def);
35
+ },
36
+ async invokeTool(name, args) {
37
+ const entry = tools.get(name);
38
+ if (!entry) throw new Error(`Tool ${name} not found`);
39
+ return entry.def.execute(args);
40
+ }
41
+ };
42
+ docAny.modelContext = polyfill;
43
+ installed = true;
44
+ return true;
45
+ }
46
+ function isPolyfilled() {
47
+ if (typeof document === "undefined") return false;
48
+ return !!document.modelContext?._isPolyfill;
49
+ }
50
+ if (typeof document !== "undefined") {
51
+ queueMicrotask(() => {
52
+ const docAny = document;
53
+ if (!docAny.modelContext) {
54
+ installPolyfill();
55
+ }
56
+ });
57
+ }
58
+ var polyfill_default = installPolyfill;
59
+
60
+ export { polyfill_default as default, installPolyfill, isPolyfilled };
61
+ //# sourceMappingURL=polyfill.js.map
62
+ //# sourceMappingURL=polyfill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/polyfill.ts"],"names":["opts"],"mappings":";AAgBA,IAAI,SAAA,GAAY,KAAA;AAET,SAAS,gBAAgB,IAAA,EAAiC;AAC/D,EAAA,IAAI,SAAA,IAAa,CAAC,IAAA,EAAM,KAAA,EAAO,OAAO,IAAA;AACtC,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,KAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,QAAA;AACf,EAAA,IAAI,MAAA,CAAO,YAAA,IAAgB,CAAC,IAAA,EAAM,KAAA,EAAO;AACvC,IAAA,SAAA,GAAY,IAAA;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAIA,EAAA,MAAM,KAAA,uBAAY,GAAA,EAMhB;AAEF,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,WAAA,EAAa,IAAA;AAAA,IACb,MAAA,EAAQ,KAAA;AAAA,IACR,MAAM,YAAA,CAAa,GAAA,EAAUA,KAAAA,EAAiC;AAC5D,MAAA,MAAM,OAAO,GAAA,EAAK,IAAA;AAClB,MAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,MAAM,6BAA6B,CAAA;AACxD,MAAA,IAAI,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,EAAG;AAEnB,QAAA;AAAA,MACF;AACA,MAAA,KAAA,CAAM,IAAI,IAAA,EAAM,EAAE,KAAK,MAAA,EAAQA,KAAAA,EAAM,QAAQ,CAAA;AAC7C,MAAA,IAAIA,OAAM,MAAA,EAAQ;AAChB,QAAA,MAAM,UAAU,MAAM;AACpB,UAAA,IAAI,KAAA,CAAM,IAAI,IAAI,CAAA,EAAG,WAAWA,KAAAA,CAAK,MAAA,EAAQ,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA;AAAA,QAChE,CAAA;AACA,QAAA,IAAIA,KAAAA,CAAK,OAAO,OAAA,EAAS;AACvB,UAAA,KAAA,CAAM,OAAO,IAAI,CAAA;AAAA,QACnB,CAAA,MAAO;AACL,UAAAA,KAAAA,CAAK,OAAO,gBAAA,CAAiB,OAAA,EAAS,SAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,QAC/D;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,SAAA,GAAY;AACV,MAAA,OAAO,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,MAAA,EAAQ,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAG,CAAA;AAAA,IACpD,CAAA;AAAA,IACA,MAAM,UAAA,CAAW,IAAA,EAAc,IAAA,EAAe;AAC5C,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA;AAC5B,MAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,KAAA,CAAM,CAAA,KAAA,EAAQ,IAAI,CAAA,UAAA,CAAY,CAAA;AACpD,MAAA,OAAO,KAAA,CAAM,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA;AAAA,IAC/B;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,YAAA,GAAe,QAAA;AACtB,EAAA,SAAA,GAAY,IAAA;AACZ,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,YAAA,GAAwB;AACtC,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,KAAA;AAC5C,EAAA,OAAO,CAAC,CAAE,QAAA,CAAiB,YAAA,EAAc,WAAA;AAC3C;AAGA,IAAI,OAAO,aAAa,WAAA,EAAa;AAEnC,EAAA,cAAA,CAAe,MAAM;AACnB,IAAA,MAAM,MAAA,GAAS,QAAA;AACf,IAAA,IAAI,CAAC,OAAO,YAAA,EAAc;AACxB,MAAA,eAAA,EAAgB;AAAA,IAClB;AAAA,EACF,CAAC,CAAA;AACH;AAEA,IAAO,gBAAA,GAAQ","file":"polyfill.js","sourcesContent":["/**\n * simple-webmcp/polyfill — adapter entry.\n * We do not hard-depend on a specific shim; we attach a minimal no-op polyfill that\n * allows `registry.register` to succeed in non-Chrome environments for dev/testing.\n * In production Chrome with native WebMCP, this is a no-op (detected via native presence).\n *\n * For full polyfill fidelity, user can `npm i @mcp-b/global` and `import '@mcp-b/global/polyfill'`\n * before importing simple-webmcp; our adapter detects `document.modelContext` already present and skips.\n *\n * This thin adapter exists to shield users from spec churn (per review §17).\n */\n\nexport type PolyfillOptions = {\n force?: boolean;\n};\n\nlet installed = false;\n\nexport function installPolyfill(opts?: PolyfillOptions): boolean {\n if (installed && !opts?.force) return true;\n if (typeof document === 'undefined') return false;\n const docAny = document as any;\n if (docAny.modelContext && !opts?.force) {\n installed = true;\n return true;\n }\n\n // Minimal polyfill — tracks tools in memory, invokes via same ABI.\n // Not a full MCP transport; sufficient for registry + tests + devtools.\n const tools = new Map<\n string,\n {\n def: any;\n signal?: AbortSignal;\n }\n >();\n\n const polyfill = {\n _isPolyfill: true,\n _tools: tools,\n async registerTool(def: any, opts?: { signal?: AbortSignal }) {\n const name = def?.name;\n if (!name) throw new Error('registerTool: name required');\n if (tools.has(name)) {\n // Dedup like native — ignore second registration\n return;\n }\n tools.set(name, { def, signal: opts?.signal });\n if (opts?.signal) {\n const onAbort = () => {\n if (tools.get(name)?.signal === opts.signal) tools.delete(name);\n };\n if (opts.signal.aborted) {\n tools.delete(name);\n } else {\n opts.signal.addEventListener('abort', onAbort, { once: true });\n }\n }\n },\n listTools() {\n return Array.from(tools.values()).map((v) => v.def);\n },\n async invokeTool(name: string, args: unknown) {\n const entry = tools.get(name);\n if (!entry) throw new Error(`Tool ${name} not found`);\n return entry.def.execute(args);\n },\n };\n\n docAny.modelContext = polyfill;\n installed = true;\n return true;\n}\n\nexport function isPolyfilled(): boolean {\n if (typeof document === 'undefined') return false;\n return !!(document as any).modelContext?._isPolyfill;\n}\n\n// Auto-install side-effect import: `import 'simple-webmcp/polyfill'`\nif (typeof document !== 'undefined') {\n // Defer to next tick to allow native detection first\n queueMicrotask(() => {\n const docAny = document as any;\n if (!docAny.modelContext) {\n installPolyfill();\n }\n });\n}\n\nexport default installPolyfill;\n"]}
package/dist/react.cjs ADDED
@@ -0,0 +1,110 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ // src/internal/utils.ts
7
+ function isWebMCPSupported() {
8
+ if (typeof document === "undefined") return false;
9
+ const docAny = document;
10
+ return !!docAny.modelContext && typeof docAny.modelContext.registerTool === "function";
11
+ }
12
+
13
+ // src/react/useWebMCP.ts
14
+ function isTool(v) {
15
+ return !!v?.__webmcpBrand;
16
+ }
17
+ function useWebMCP(tool, opts) {
18
+ const enabled = opts?.enabled ?? true;
19
+ const [registered, setRegistered] = react.useState(false);
20
+ const [error, setError] = react.useState(null);
21
+ const supported = react.useMemo(() => isWebMCPSupported(), []);
22
+ const isPolyfilled = react.useMemo(() => {
23
+ if (typeof document === "undefined") return false;
24
+ const docAny = document;
25
+ return !!docAny.modelContext?._isPolyfill;
26
+ }, [supported]);
27
+ const toolRef = react.useRef(tool);
28
+ toolRef.current = tool;
29
+ react.useEffect(() => {
30
+ if (!enabled) {
31
+ setRegistered(false);
32
+ setError(null);
33
+ return;
34
+ }
35
+ const t = toolRef.current;
36
+ if (!isTool(t)) {
37
+ if (typeof console !== "undefined") {
38
+ console.warn("[simple-webmcp] useWebMCP expected webmcp(fn) tool, got plain function. Wrap with webmcp() first.");
39
+ }
40
+ setError(new Error("useWebMCP: wrap fn with webmcp() first"));
41
+ setRegistered(false);
42
+ return;
43
+ }
44
+ const webTool = t;
45
+ if (webTool.status === "registered") {
46
+ setRegistered(true);
47
+ setError(null);
48
+ return;
49
+ }
50
+ let cancelled = false;
51
+ let unregister = null;
52
+ const controller = new AbortController();
53
+ webTool.register({ signal: controller.signal }).then((u) => {
54
+ if (cancelled) {
55
+ try {
56
+ u();
57
+ } catch {
58
+ }
59
+ return;
60
+ }
61
+ unregister = u;
62
+ setRegistered(true);
63
+ setError(null);
64
+ }).catch((e) => {
65
+ if (cancelled) return;
66
+ setRegistered(false);
67
+ const err = e instanceof Error ? e : new Error(String(e));
68
+ setError(err);
69
+ });
70
+ return () => {
71
+ cancelled = true;
72
+ try {
73
+ controller.abort();
74
+ } catch {
75
+ }
76
+ if (unregister) {
77
+ try {
78
+ unregister();
79
+ } catch {
80
+ }
81
+ } else {
82
+ try {
83
+ webTool.unregister?.();
84
+ } catch {
85
+ }
86
+ }
87
+ setRegistered(false);
88
+ };
89
+ }, [enabled, supported, tool]);
90
+ const status = !supported ? "unsupported" : error ? "error" : registered ? "registered" : enabled ? "registering" : "unregistered";
91
+ return { supported: !!supported, registered, error, isPolyfilled, status };
92
+ }
93
+ function ToolRegistrar({ tool, enabled }) {
94
+ useWebMCP(tool, { enabled });
95
+ return null;
96
+ }
97
+ function Scope({ tools, enabled = true, children }) {
98
+ const normalized = react.useMemo(() => tools ?? [], [tools]);
99
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
100
+ normalized.map((t, i) => /* @__PURE__ */ jsxRuntime.jsx(ToolRegistrar, { tool: t, enabled }, t?.tool?.name ?? t?.definition?.name ?? `tool-${i}`)),
101
+ children
102
+ ] });
103
+ }
104
+ var WebMCPScope = Scope;
105
+
106
+ exports.Scope = Scope;
107
+ exports.WebMCPScope = WebMCPScope;
108
+ exports.useWebMCP = useWebMCP;
109
+ //# sourceMappingURL=react.cjs.map
110
+ //# sourceMappingURL=react.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/utils.ts","../src/react/useWebMCP.ts","../src/react/Scope.tsx"],"names":["useState","useMemo","useRef","useEffect","jsxs","Fragment","jsx"],"mappings":"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","file":"react.cjs","sourcesContent":["import type { JsonSchema, ModelContextLike } from '../types.js';\n\n/**\n * Convert camelCase / PascalCase to snake_case for tool naming.\n * searchCustomers → search_customers\n * SearchCustomers → search_customers\n */\nexport function toSnakeCase(name: string): string {\n if (!name) return 'anonymous_tool';\n return name\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')\n .toLowerCase()\n .replace(/[^a-z0-9_]+/g, '_')\n .replace(/^_+|_+$/g, '') || 'anonymous_tool';\n}\n\n/**\n * Totally minimal doc extraction — best effort.\n * Full JSDoc inference is build-time. Runtime we just note presence.\n */\nexport function getFunctionName(fn: Function): string {\n return (fn as any).displayName || fn.name || '';\n}\n\n/**\n * Check if WebMCP is supported (native or polyfilled)\n */\nexport function isWebMCPSupported(): boolean {\n if (typeof document === 'undefined') return false;\n const docAny = document as any;\n return !!docAny.modelContext && typeof docAny.modelContext.registerTool === 'function';\n}\n\nexport function getModelContext(): ModelContextLike | null {\n if (typeof document === 'undefined') return null;\n const docAny = document as any;\n if (docAny.modelContext && typeof docAny.modelContext.registerTool === 'function') {\n return docAny.modelContext as ModelContextLike;\n }\n return null;\n}\n\n/**\n * Heuristic check if value looks like JSON Schema (vs StandardSchema)\n */\nexport function looksLikeJsonSchema(value: unknown): value is JsonSchema {\n if (!value || typeof value !== 'object') return false;\n const obj = value as Record<string, unknown>;\n // JSON Schema typically has `type` at top, no `~standard`\n if ('~standard' in obj) return false;\n // Has type or properties or $ref etc\n return (\n 'type' in obj ||\n 'properties' in obj ||\n '$ref' in obj ||\n 'anyOf' in obj ||\n 'oneOf' in obj ||\n 'allOf' in obj ||\n 'enum' in obj\n );\n}\n\n/**\n * Check if value is StandardSchema\n */\nexport function isStandardSchema(value: unknown): boolean {\n return (\n !!value &&\n typeof value === 'object' &&\n '~standard' in (value as any) &&\n (value as any)['~standard']?.validate != null &&\n typeof (value as any)['~standard'].validate === 'function'\n );\n}\n\n/**\n * Cheap JSDoc/description fallback — runtime can't parse JSDoc,\n * but we check if fn has __webmcpDescription attached by build plugin or manual.\n */\nexport function getDescription(fn: Function, override?: string): string {\n if (override != null) return override;\n const anyFn = fn as any;\n if (typeof anyFn.__webmcpDescription === 'string') return anyFn.__webmcpDescription;\n // No JSDoc at runtime — return empty and warn elsewhere\n return '';\n}\n\nlet warnedNoDesc = false;\nexport function warnNoDescription(fn: Function) {\n if (warnedNoDesc) return;\n // Only warn once per page load\n warnedNoDesc = true;\n if (typeof console !== 'undefined' && typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.warn(\n `[simple-webmcp] tool \"${getFunctionName(fn) || 'anonymous'}\" has no description. Add \\`description:\"...\"\\` or JSDoc. See https://github.com/emingure/simple-webmcp`,\n );\n } else if (typeof console !== 'undefined') {\n // In browser dev, also warn once\n // eslint-disable-next-line no-console\n console.warn(`[simple-webmcp] tool \"${getFunctionName(fn) || 'anonymous'}\" has no description.`);\n }\n}\n","'use client';\n\nimport { useEffect, useState, useRef, useMemo } from 'react';\nimport type { WebMCPTool } from '../types.js';\nimport { isWebMCPSupported } from '../internal/utils.js';\nimport { NotSupportedError } from '../errors.js';\n\n// Check helper to see if value is a WebMCPTool\nfunction isTool<F extends (...a: any) => any>(v: WebMCPTool<F> | F): v is WebMCPTool<F> {\n return !!(v as any)?.__webmcpBrand;\n}\n\nexport type UseWebMCPResult = {\n supported: boolean;\n registered: boolean;\n error: Error | null;\n isPolyfilled: boolean;\n status: 'unregistered' | 'registering' | 'registered' | 'error' | 'unsupported';\n};\n\n/**\n * Register a tool for the lifetime of the component.\n * Matches WebMCP spec AbortSignal lifecycle and StrictMode double-mount safety via dedup registry.\n *\n * @param tool - WebMCPTool from webmcp(fn) or raw fn (will warn and no-op)\n * @param opts.enabled - if false, inert\n */\nexport function useWebMCP<F extends (...args: any) => any>(\n tool: WebMCPTool<F> | F,\n opts?: { enabled?: boolean },\n): UseWebMCPResult {\n const enabled = opts?.enabled ?? true;\n const [registered, setRegistered] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const supported = useMemo(() => isWebMCPSupported(), []);\n // polyfill detection — if isWebMCPSupported true and shim marker present\n const isPolyfilled = useMemo(() => {\n if (typeof document === 'undefined') return false;\n const docAny = document as any;\n return !!docAny.modelContext?._isPolyfill;\n }, [supported]);\n\n const toolRef = useRef(tool);\n toolRef.current = tool;\n\n useEffect(() => {\n if (!enabled) {\n setRegistered(false);\n setError(null);\n return;\n }\n\n const t: any = toolRef.current as any;\n\n if (!isTool(t as any)) {\n // Plain fn passed — warn, optionally auto-wrap? For 0.1 we no-op with warning\n if (typeof console !== 'undefined') {\n // eslint-disable-next-line no-console\n console.warn('[simple-webmcp] useWebMCP expected webmcp(fn) tool, got plain function. Wrap with webmcp() first.');\n }\n setError(new Error('useWebMCP: wrap fn with webmcp() first'));\n setRegistered(false);\n return;\n }\n\n const webTool = t as WebMCPTool<F>;\n\n // If tool was created with global:true, it's already global — just track status\n // We still sync registered state\n if ((webTool as any).status === 'registered') {\n setRegistered(true);\n setError(null);\n return;\n }\n\n let cancelled = false;\n let unregister: (() => void) | null = null;\n\n // Async register — hook's job is to handle AbortSignal mapping\n const controller = new AbortController();\n\n webTool\n .register({ signal: controller.signal })\n .then((u) => {\n if (cancelled) {\n try {\n u();\n } catch {}\n return;\n }\n unregister = u;\n setRegistered(true);\n setError(null);\n })\n .catch((e: unknown) => {\n if (cancelled) return;\n setRegistered(false);\n const err = e instanceof Error ? e : new Error(String(e));\n setError(err);\n });\n\n return () => {\n cancelled = true;\n try {\n controller.abort();\n } catch {}\n if (unregister) {\n try {\n unregister();\n } catch {}\n } else {\n // If registration still pending, ensure tool's own unregister clears\n try {\n (webTool as any).unregister?.();\n } catch {}\n }\n setRegistered(false);\n };\n // Re-run if tool identity changes or enabled\n }, [enabled, supported, tool]);\n\n const status = !supported ? 'unsupported' : error ? 'error' : registered ? 'registered' : enabled ? 'registering' : 'unregistered';\n\n return { supported: !!supported, registered, error, isPolyfilled, status: status as any };\n}\n","'use client';\n\nimport React, { useMemo } from 'react';\nimport type { WebMCPTool } from '../types.js';\nimport { useWebMCP } from './useWebMCP.js';\n\nexport type ScopeProps = {\n tools: Array<WebMCPTool<any>>;\n enabled?: boolean;\n children?: React.ReactNode;\n};\n\n/**\n * React subtree scope — exposes tools while this component is mounted.\n * Maps cleanly onto WebMCP AbortSignal lifecycle.\n * Naturally gives route-level scope when placed in Next.js layout.tsx.\n */\nfunction ToolRegistrar({ tool, enabled }: { tool: WebMCPTool<any>; enabled?: boolean }) {\n useWebMCP(tool as any, { enabled });\n return null;\n}\n\nexport function Scope({ tools, enabled = true, children }: ScopeProps) {\n const normalized = useMemo(() => tools ?? [], [tools]);\n return (\n <>\n {normalized.map((t, i) => (\n <ToolRegistrar key={(t as any)?.tool?.name ?? (t as any)?.definition?.name ?? `tool-${i}`} tool={t} enabled={enabled} />\n ))}\n {children}\n </>\n );\n}\n\n// Also export as WebMCP.Scope style\nexport const WebMCPScope = Scope;\n"]}
@@ -0,0 +1,30 @@
1
+ import { a as WebMCPTool } from './types-D-cwSfEU.cjs';
2
+ import React from 'react';
3
+
4
+ type UseWebMCPResult = {
5
+ supported: boolean;
6
+ registered: boolean;
7
+ error: Error | null;
8
+ isPolyfilled: boolean;
9
+ status: 'unregistered' | 'registering' | 'registered' | 'error' | 'unsupported';
10
+ };
11
+ /**
12
+ * Register a tool for the lifetime of the component.
13
+ * Matches WebMCP spec AbortSignal lifecycle and StrictMode double-mount safety via dedup registry.
14
+ *
15
+ * @param tool - WebMCPTool from webmcp(fn) or raw fn (will warn and no-op)
16
+ * @param opts.enabled - if false, inert
17
+ */
18
+ declare function useWebMCP<F extends (...args: any) => any>(tool: WebMCPTool<F> | F, opts?: {
19
+ enabled?: boolean;
20
+ }): UseWebMCPResult;
21
+
22
+ type ScopeProps = {
23
+ tools: Array<WebMCPTool<any>>;
24
+ enabled?: boolean;
25
+ children?: React.ReactNode;
26
+ };
27
+ declare function Scope({ tools, enabled, children }: ScopeProps): React.JSX.Element;
28
+ declare const WebMCPScope: typeof Scope;
29
+
30
+ export { Scope, type UseWebMCPResult, WebMCPScope, useWebMCP };
@@ -0,0 +1,30 @@
1
+ import { a as WebMCPTool } from './types-D-cwSfEU.js';
2
+ import React from 'react';
3
+
4
+ type UseWebMCPResult = {
5
+ supported: boolean;
6
+ registered: boolean;
7
+ error: Error | null;
8
+ isPolyfilled: boolean;
9
+ status: 'unregistered' | 'registering' | 'registered' | 'error' | 'unsupported';
10
+ };
11
+ /**
12
+ * Register a tool for the lifetime of the component.
13
+ * Matches WebMCP spec AbortSignal lifecycle and StrictMode double-mount safety via dedup registry.
14
+ *
15
+ * @param tool - WebMCPTool from webmcp(fn) or raw fn (will warn and no-op)
16
+ * @param opts.enabled - if false, inert
17
+ */
18
+ declare function useWebMCP<F extends (...args: any) => any>(tool: WebMCPTool<F> | F, opts?: {
19
+ enabled?: boolean;
20
+ }): UseWebMCPResult;
21
+
22
+ type ScopeProps = {
23
+ tools: Array<WebMCPTool<any>>;
24
+ enabled?: boolean;
25
+ children?: React.ReactNode;
26
+ };
27
+ declare function Scope({ tools, enabled, children }: ScopeProps): React.JSX.Element;
28
+ declare const WebMCPScope: typeof Scope;
29
+
30
+ export { Scope, type UseWebMCPResult, WebMCPScope, useWebMCP };