@widgentic/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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Diego Hoyos
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # @widgentic/webmcp
2
+
3
+ > **Beta.** The API may change in minor versions before 1.0. Built against the
4
+ > WebMCP specification's `document.modelContext` shape; see "Browsers" below
5
+ > for what has been exercised where.
6
+
7
+ Expose the mounted widgentic designers as [WebMCP](https://github.com/webmachinelearning/webmcp)
8
+ tools, so a browser-side agent — ChatGPT Desktop's browser, Chrome or Edge in
9
+ the WebMCP origin trial — can read and edit the drafts the person is looking
10
+ at. **Agents edit, people save**: no tool here persists anything; the host's
11
+ save controls stay the only write path. Browser-safe, no network I/O, depends
12
+ only on `@widgentic/core` and `@widgentic/designer`.
13
+
14
+ ```sh
15
+ npm install @widgentic/webmcp
16
+ ```
17
+
18
+ One call after mounting. Sources are **getters**, resolved on every tool call,
19
+ because hosts remount designers when the person switches tabs:
20
+
21
+ ```ts
22
+ import { exposeDesigners } from "@widgentic/webmcp";
23
+
24
+ const agentTools = await exposeDesigners({
25
+ widget: () => widgetDesigner, // a DesignerHandle, or undefined while unmounted
26
+ theme: () => { showTab("theme"); return themeDesigner; }, // a getter may mount first
27
+ schema: () => schemaDesigner,
28
+ action: () => actionDesigner
29
+ });
30
+
31
+ status.textContent = agentTools.supported
32
+ ? `agent tools: ${agentTools.registered.length} registered`
33
+ : "no agent-capable browser";
34
+
35
+ // Later, e.g. on sign-out: every tool disappears together.
36
+ agentTools.dispose();
37
+ ```
38
+
39
+ In a browser without a model context the call resolves with
40
+ `supported: false`, registers nothing and throws nothing — the page is
41
+ unchanged.
42
+
43
+ ## The tools
44
+
45
+ Names are `<prefix>_<suffix>`; the prefix defaults to `widgentic` (`{ prefix }`
46
+ in the options). Only designers you supply a source for get tools; the token
47
+ reference is always present.
48
+
49
+ | Tool | Read-only | Does |
50
+ |---|---|---|
51
+ | `widget_draft_get` | yes | The open widget definition in export shape `{ kind, template, descriptor, load? }` plus the designer's diagnostics |
52
+ | `widget_draft_load` | | Replace the draft with a definition, through the designer's validation |
53
+ | `widget_example_data_set` | | Replace `descriptor.dataExample` — what the preview renders; the example-vs-schema verdict comes back in the diagnostics |
54
+ | `widget_theme_set` | | Set the preview theme tokens of the draft |
55
+ | `theme_get` / `theme_load` | get | The theme entry `{ name, label?, description?, tokens }` |
56
+ | `theme_tokens_set` | | Merge tokens into the open entry (`{ tokens, remove? }`), validated as a whole |
57
+ | `schema_get` / `schema_load` | get | The shared data-schema entry `{ name, label?, description?, schema }` |
58
+ | `action_get` / `action_load` | get | The action entry `{ name, label?, description?, definition }` |
59
+ | `theme_token_specs` | yes | Every `--wg-*` token with type, default, purpose and fallback, from the exported specs |
60
+
61
+ Every tool resolves to MCP-shaped text content carrying one JSON document with
62
+ a boolean `ok`:
63
+
64
+ ```json
65
+ { "content": [{ "type": "text", "text": "{\"ok\":false,\"code\":\"REJECTED\",\"errors\":[\"template: … \"]}" }] }
66
+ ```
67
+
68
+ Refusals are results, never rejections: `NOT_MOUNTED` (the source returned
69
+ nothing), `INVALID_INPUT` (with the `argument`), `REJECTED` (with the
70
+ designer's own `errors`). Read tools carry `annotations.readOnlyHint`, so
71
+ agents run them without a confirmation step.
72
+
73
+ Diagnostics come from the designer itself: the package subscribes to each
74
+ handle it sees and returns what the designer computed for the change a tool
75
+ made. Before the first change there is nothing to return, so `widget_draft_get`
76
+ derives them without the host's shared entries and says so with
77
+ `diagnosticsDerived: true`.
78
+
79
+ ## Your own tools
80
+
81
+ `registerTools(tools, { modelContext?, signal? })` registers any descriptors in
82
+ the same shape under one abort signal; `exposeDesigners` accepts extra ones as
83
+ `{ tools }` and reports them in the same result. Build results with
84
+ `okResult()` / `failResult()` so hosts and agents see one vocabulary.
85
+ `designerTools(sources, { prefix })` returns the descriptors without
86
+ registering — inspect them, or hand them to your own registration.
87
+
88
+ ## Browsers
89
+
90
+ - **Native**: the package resolves `document.modelContext` (the specification;
91
+ ChatGPT Desktop's browser) and falls back to `navigator.modelContext` (Chrome
92
+ origin trial). An explicit `{ modelContext }` option wins over both.
93
+ - **Chrome 149+ / Edge 150 without a token**: enable
94
+ `chrome://flags/#enable-webmcp-testing`, or launch with
95
+ `--enable-features=WebMCPTesting,DevToolsWebMCPSupport` and drive the tools
96
+ from `navigator.modelContextTesting.getTools()` / `executeTool()`.
97
+ - **Polyfills**: nothing is bundled — a polyfill supplies the API, not the
98
+ agent, and cannot make Firefox or Safari agent-capable. If you want
99
+ extension-based agents (for example `@mcp-b/webmcp-polyfill`, which installs
100
+ `document.modelContext` and defers to a native one), load it **before** the
101
+ `exposeDesigners` call; the resolver finds whatever the page has.
102
+
103
+ Tools must be registered on the top-level page; browsers do not read tools from
104
+ iframes.
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Theme, schema and action designer tools: each mirrors its handle — read the
3
+ * entry, load an entry through the designer's validation — plus a token merge
4
+ * for the theme designer.
5
+ */
6
+ import type { ActionDesignerHandle, SchemaDesignerHandle, ThemeDesignerHandle } from "@widgentic/designer";
7
+ import type { NameOf } from "./tool.js";
8
+ import type { WebMcpTool } from "./types.js";
9
+ export declare function themeTools(source: () => ThemeDesignerHandle | undefined, name: NameOf): WebMcpTool[];
10
+ export declare function schemaTools(source: () => SchemaDesignerHandle | undefined, name: NameOf): WebMcpTool[];
11
+ export declare function actionTools(source: () => ActionDesignerHandle | undefined, name: NameOf): WebMcpTool[];
12
+ //# sourceMappingURL=entry-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-tools.d.ts","sourceRoot":"","sources":["../src/entry-tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK7C,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,mBAAmB,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CAgEpG;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,oBAAoB,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CAkCtG;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,oBAAoB,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CAkCtG"}
@@ -0,0 +1,149 @@
1
+ import { isPlainObject } from "@widgentic/core";
2
+ import { argumentsOf, invalidArgument, notMounted, okResult, rejected } from "./result.js";
3
+ import { defineTool, objectSchema, PERSON_SAVES } from "./tool.js";
4
+ const ENTRY_SCHEMA = (what) => objectSchema({ entry: { type: "object", description: `The ${what} entry.` } }, ["entry"]);
5
+ export function themeTools(source, name) {
6
+ return [
7
+ defineTool({
8
+ name: name("theme_get"),
9
+ title: "Read the theme entry",
10
+ readOnly: true,
11
+ description: "Read the theme entry open in the theme designer: { entry: { name, label?, description?, extends?, tokens } } — tokens is a map of --wg-* token names (and x-<name> author variables) to CSS values.",
12
+ inputSchema: objectSchema({}),
13
+ execute() {
14
+ const handle = source();
15
+ if (handle === undefined)
16
+ return notMounted("theme");
17
+ return okResult({ entry: handle.getTheme() });
18
+ }
19
+ }),
20
+ defineTool({
21
+ name: name("theme_load"),
22
+ title: "Load a theme entry",
23
+ description: "Replace the entry in the theme designer: { entry: { name, label?, description?, tokens } }. name: lowercase letters, digits, '.', '_' or '-'; light and dark are reserved. " +
24
+ "Validated by the theming rules (list tokens with theme_token_specs); refused → { ok: false, code: 'REJECTED', errors }. " +
25
+ PERSON_SAVES,
26
+ inputSchema: ENTRY_SCHEMA("theme"),
27
+ execute(input) {
28
+ const handle = source();
29
+ if (handle === undefined)
30
+ return notMounted("theme");
31
+ const { entry } = argumentsOf(input);
32
+ if (!isPlainObject(entry))
33
+ return invalidArgument("entry", "object");
34
+ const result = handle.loadTheme(entry);
35
+ if (!result.ok)
36
+ return rejected(result.errors);
37
+ return okResult({ entry: handle.getTheme() });
38
+ }
39
+ }),
40
+ defineTool({
41
+ name: name("theme_tokens_set"),
42
+ title: "Merge theme tokens",
43
+ description: "Change some tokens of the theme entry open in the theme designer without retyping the rest: { tokens: { <token>: <css value> }, remove?: [<token>] }. " +
44
+ "The result is validated as a whole; an invalid value leaves the entry unchanged and returns { ok: false, code: 'REJECTED', errors }. " +
45
+ PERSON_SAVES,
46
+ inputSchema: objectSchema({
47
+ tokens: { type: "object", description: "Token name → CSS value to set.", additionalProperties: { type: "string" } },
48
+ remove: { type: "array", items: { type: "string" }, description: "Token names to drop." }
49
+ }),
50
+ execute(input) {
51
+ const handle = source();
52
+ if (handle === undefined)
53
+ return notMounted("theme");
54
+ const args = argumentsOf(input);
55
+ const tokens = args.tokens === undefined ? {} : args.tokens;
56
+ if (!isPlainObject(tokens))
57
+ return invalidArgument("tokens", "object of token → value");
58
+ const remove = args.remove === undefined ? [] : args.remove;
59
+ if (!Array.isArray(remove) || !remove.every((item) => typeof item === "string")) {
60
+ return invalidArgument("remove", "array of token names");
61
+ }
62
+ const current = handle.getTheme();
63
+ const merged = { ...current.tokens, ...tokens };
64
+ for (const token of remove)
65
+ delete merged[token];
66
+ const next = { ...current, tokens: merged };
67
+ const result = handle.loadTheme(next);
68
+ if (!result.ok)
69
+ return rejected(result.errors);
70
+ return okResult({ entry: handle.getTheme() });
71
+ }
72
+ })
73
+ ];
74
+ }
75
+ export function schemaTools(source, name) {
76
+ return [
77
+ defineTool({
78
+ name: name("schema_get"),
79
+ title: "Read the schema entry",
80
+ readOnly: true,
81
+ description: "Read the shared data-schema entry open in the schema designer: { entry: { name, label?, description?, schema } } — schema is a JSON Schema object widgets reference by name (dataSchemaRef).",
82
+ inputSchema: objectSchema({}),
83
+ execute() {
84
+ const handle = source();
85
+ if (handle === undefined)
86
+ return notMounted("schema");
87
+ return okResult({ entry: handle.getSchema() });
88
+ }
89
+ }),
90
+ defineTool({
91
+ name: name("schema_load"),
92
+ title: "Load a schema entry",
93
+ description: "Replace the entry in the schema designer: { entry: { name, label?, description?, schema } }. name: letters, digits, '.', '_' or '-'; schema: a JSON Schema object. " +
94
+ "Refused → { ok: false, code: 'REJECTED', errors }. " +
95
+ PERSON_SAVES,
96
+ inputSchema: ENTRY_SCHEMA("schema"),
97
+ execute(input) {
98
+ const handle = source();
99
+ if (handle === undefined)
100
+ return notMounted("schema");
101
+ const { entry } = argumentsOf(input);
102
+ if (!isPlainObject(entry))
103
+ return invalidArgument("entry", "object");
104
+ const result = handle.loadSchema(entry);
105
+ if (!result.ok)
106
+ return rejected(result.errors);
107
+ return okResult({ entry: handle.getSchema() });
108
+ }
109
+ })
110
+ ];
111
+ }
112
+ export function actionTools(source, name) {
113
+ return [
114
+ defineTool({
115
+ name: name("action_get"),
116
+ title: "Read the action entry",
117
+ readOnly: true,
118
+ description: "Read the action entry open in the action designer: { entry: { name, label?, description?, definition } } — definition is a prompt action ({ kind: 'prompt', text }) or an http action ({ kind: 'http', … }).",
119
+ inputSchema: objectSchema({}),
120
+ execute() {
121
+ const handle = source();
122
+ if (handle === undefined)
123
+ return notMounted("action");
124
+ return okResult({ entry: handle.getAction() });
125
+ }
126
+ }),
127
+ defineTool({
128
+ name: name("action_load"),
129
+ title: "Load an action entry",
130
+ description: "Replace the entry in the action designer: { entry: { name, label?, description?, definition } }. name: lowercase letters, digits and dashes, starting with a letter. " +
131
+ "Refused → { ok: false, code: 'REJECTED', errors }. Secrets are referenced by name only and never pass through this tool. " +
132
+ PERSON_SAVES,
133
+ inputSchema: ENTRY_SCHEMA("action"),
134
+ execute(input) {
135
+ const handle = source();
136
+ if (handle === undefined)
137
+ return notMounted("action");
138
+ const { entry } = argumentsOf(input);
139
+ if (!isPlainObject(entry))
140
+ return invalidArgument("entry", "object");
141
+ const result = handle.loadAction(entry);
142
+ if (!result.ok)
143
+ return rejected(result.errors);
144
+ return okResult({ entry: handle.getAction() });
145
+ }
146
+ })
147
+ ];
148
+ }
149
+ //# sourceMappingURL=entry-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-tools.js","sourceRoot":"","sources":["../src/entry-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @widgentic/webmcp (beta) — the mounted widgentic designers as WebMCP tools.
3
+ * `exposeDesigners(sources)` builds tool descriptors over the designer
4
+ * handles a host supplies (as getters, resolved per call) and registers them
5
+ * on the page's model context; in a browser without one it is a reported
6
+ * no-op. Agents read and edit the working copies; the person saves — no tool
7
+ * here persists anything. Browser-safe, no network I/O.
8
+ */
9
+ export { designerTools, DEFAULT_PREFIX } from "./tools.js";
10
+ export { exposeDesigners, registerTools, resolveModelContext } from "./register.js";
11
+ export { okResult, failResult } from "./result.js";
12
+ export type { FailureCode } from "./result.js";
13
+ export type { DesignerSources, ExposeOptions, ExposeResult, ModelContextLike, RegisterFailure, RegisterOptions, RegisterResult, ToolsOptions, WebMcpExecuteOptions, WebMcpTextContent, WebMcpTool, WebMcpToolAnnotations, WebMcpToolResult } from "./types.js";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EACV,eAAe,EACf,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,EACV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @widgentic/webmcp (beta) — the mounted widgentic designers as WebMCP tools.
3
+ * `exposeDesigners(sources)` builds tool descriptors over the designer
4
+ * handles a host supplies (as getters, resolved per call) and registers them
5
+ * on the page's model context; in a browser without one it is a reported
6
+ * no-op. Agents read and edit the working copies; the person saves — no tool
7
+ * here persists anything. Browser-safe, no network I/O.
8
+ */
9
+ export { designerTools, DEFAULT_PREFIX } from "./tools.js";
10
+ export { exposeDesigners, registerTools, resolveModelContext } from "./register.js";
11
+ export { okResult, failResult } from "./result.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { NameOf } from "./tool.js";
2
+ import type { WebMcpTool } from "./types.js";
3
+ export declare function themeTokenSpecsTool(name: NameOf): WebMcpTool;
4
+ //# sourceMappingURL=reference-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-tools.d.ts","sourceRoot":"","sources":["../src/reference-tools.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAmB5D"}
@@ -0,0 +1,24 @@
1
+ /** Tools that need no designer: reference data derived from the exported specs at call time. */
2
+ import { TOKEN_SPECS } from "@widgentic/core";
3
+ import { okResult } from "./result.js";
4
+ import { defineTool, objectSchema } from "./tool.js";
5
+ export function themeTokenSpecsTool(name) {
6
+ return defineTool({
7
+ name: name("theme_token_specs"),
8
+ title: "List the theme tokens",
9
+ readOnly: true,
10
+ description: "List every --wg-* theme token with its value type, default, purpose and fallback token — the vocabulary for theme entries and preview themes. Author-defined variables are x-<name>.",
11
+ inputSchema: objectSchema({}),
12
+ execute() {
13
+ const tokens = Object.entries(TOKEN_SPECS).map(([token, spec]) => ({
14
+ name: token,
15
+ type: spec.type,
16
+ default: spec.default,
17
+ use: spec.use,
18
+ ...("fallback" in spec && spec.fallback !== undefined ? { fallback: spec.fallback } : {})
19
+ }));
20
+ return okResult({ tokens });
21
+ }
22
+ });
23
+ }
24
+ //# sourceMappingURL=reference-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-tools.js","sourceRoot":"","sources":["../src/reference-tools.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAIrD,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,UAAU,CAAC;QAChB,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC;QAC/B,KAAK,EAAE,uBAAuB;QAC9B,QAAQ,EAAE,IAAI;QACd,WAAW,EACT,sLAAsL;QACxL,WAAW,EAAE,YAAY,CAAC,EAAE,CAAC;QAC7B,OAAO;YACL,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjE,IAAI,EAAE,KAAK;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,GAAG,CAAC,UAAU,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1F,CAAC,CAAC,CAAC;YACJ,OAAO,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9B,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { DesignerSources, ExposeOptions, ExposeResult, ModelContextLike, RegisterOptions, RegisterResult, WebMcpTool } from "./types.js";
2
+ /** The page's model context: the document's (spec, ChatGPT) before the navigator's (Chrome origin trial). */
3
+ export declare function resolveModelContext(): ModelContextLike | undefined;
4
+ export declare function registerTools(tools: readonly WebMcpTool[], options?: RegisterOptions): Promise<RegisterResult>;
5
+ /** The one call a host makes after mounting: build the designer tools and register them. */
6
+ export declare function exposeDesigners(sources: DesignerSources, options?: ExposeOptions): Promise<ExposeResult>;
7
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,YAAY,EACZ,gBAAgB,EAEhB,eAAe,EACf,cAAc,EACd,UAAU,EACX,MAAM,YAAY,CAAC;AAUpB,6GAA6G;AAC7G,wBAAgB,mBAAmB,IAAI,gBAAgB,GAAG,SAAS,CAUlE;AAQD,wBAAsB,aAAa,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAwCxH;AAED,4FAA4F;AAC5F,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAUlH"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Registration on the page's model context. Feature-detected (the spec's
3
+ * `document.modelContext`, then Chrome's `navigator.modelContext`), reported
4
+ * rather than thrown, disposable as one unit through a single abort signal.
5
+ */
6
+ import { designerTools } from "./tools.js";
7
+ function isModelContext(value) {
8
+ return (typeof value === "object" &&
9
+ value !== null &&
10
+ typeof value.registerTool === "function");
11
+ }
12
+ /** The page's model context: the document's (spec, ChatGPT) before the navigator's (Chrome origin trial). */
13
+ export function resolveModelContext() {
14
+ const scope = globalThis;
15
+ const fromDocument = scope.document?.modelContext;
16
+ if (isModelContext(fromDocument))
17
+ return fromDocument;
18
+ const fromNavigator = scope.navigator?.modelContext;
19
+ if (isModelContext(fromNavigator))
20
+ return fromNavigator;
21
+ return undefined;
22
+ }
23
+ function messageOf(reason) {
24
+ return reason instanceof Error ? reason.message : String(reason);
25
+ }
26
+ const UNSUPPORTED = { supported: false, registered: [], failed: [], dispose() { } };
27
+ export async function registerTools(tools, options = {}) {
28
+ const context = options.modelContext ?? resolveModelContext();
29
+ if (context === undefined)
30
+ return UNSUPPORTED;
31
+ const controller = new AbortController();
32
+ const registered = [];
33
+ const failed = [];
34
+ let disposed = false;
35
+ const dispose = () => {
36
+ if (disposed)
37
+ return;
38
+ disposed = true;
39
+ controller.abort();
40
+ if (typeof context.unregisterTool !== "function")
41
+ return;
42
+ for (const name of registered) {
43
+ try {
44
+ context.unregisterTool(name);
45
+ }
46
+ catch {
47
+ // Already gone (the abort did it) — nothing to report.
48
+ }
49
+ }
50
+ };
51
+ if (options.signal !== undefined) {
52
+ if (options.signal.aborted)
53
+ dispose();
54
+ else
55
+ options.signal.addEventListener("abort", dispose, { once: true });
56
+ }
57
+ // One rejection (a duplicate name, a permissions-policy refusal) must not
58
+ // take the others down: settle them all, report by name.
59
+ const outcomes = await Promise.allSettled(tools.map(async (tool) => {
60
+ await context.registerTool(tool, { signal: controller.signal });
61
+ return tool.name;
62
+ }));
63
+ outcomes.forEach((outcome, index) => {
64
+ const name = tools[index]?.name ?? "";
65
+ if (outcome.status === "fulfilled")
66
+ registered.push(name);
67
+ else
68
+ failed.push({ name, message: messageOf(outcome.reason) });
69
+ });
70
+ return { supported: true, registered, failed, dispose };
71
+ }
72
+ /** The one call a host makes after mounting: build the designer tools and register them. */
73
+ export async function exposeDesigners(sources, options = {}) {
74
+ const tools = [
75
+ ...designerTools(sources, options.prefix === undefined ? {} : { prefix: options.prefix }),
76
+ ...(options.tools ?? [])
77
+ ];
78
+ const result = await registerTools(tools, {
79
+ ...(options.modelContext === undefined ? {} : { modelContext: options.modelContext }),
80
+ ...(options.signal === undefined ? {} : { signal: options.signal })
81
+ });
82
+ return { ...result, tools };
83
+ }
84
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { WebMcpToolResult } from "./types.js";
2
+ export type FailureCode = "NOT_MOUNTED" | "INVALID_INPUT" | "REJECTED";
3
+ export declare function okResult(payload?: Record<string, unknown>): WebMcpToolResult;
4
+ export declare function failResult(code: FailureCode, detail?: Record<string, unknown>): WebMcpToolResult;
5
+ /** The arguments object, or an empty one when the agent sent nothing usable. */
6
+ export declare function argumentsOf(input: unknown): Record<string, unknown>;
7
+ export declare function invalidArgument(argument: string, expected: string): WebMcpToolResult;
8
+ export declare function notMounted(designer: "widget" | "theme" | "schema" | "action"): WebMcpToolResult;
9
+ export declare function rejected(errors: readonly string[]): WebMcpToolResult;
10
+ //# sourceMappingURL=result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,eAAe,GAAG,UAAU,CAAC;AAMvE,wBAAgB,QAAQ,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,gBAAgB,CAEhF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,gBAAgB,CAEpG;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEnE;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAEpF;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,gBAAgB,CAK/F;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAEpE"}
package/dist/result.js ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Tool results: one JSON document inside MCP text content, always with a
3
+ * boolean `ok`. Refusals are results, never rejections — a thrown error reaches
4
+ * the agent as an opaque failure, a result is something it can act on.
5
+ */
6
+ import { isPlainObject } from "@widgentic/core";
7
+ function textResult(payload) {
8
+ return { content: [{ type: "text", text: JSON.stringify(payload) }] };
9
+ }
10
+ export function okResult(payload = {}) {
11
+ return textResult({ ok: true, ...payload });
12
+ }
13
+ export function failResult(code, detail = {}) {
14
+ return textResult({ ok: false, code, ...detail });
15
+ }
16
+ /** The arguments object, or an empty one when the agent sent nothing usable. */
17
+ export function argumentsOf(input) {
18
+ return isPlainObject(input) ? input : {};
19
+ }
20
+ export function invalidArgument(argument, expected) {
21
+ return failResult("INVALID_INPUT", { argument, expected });
22
+ }
23
+ export function notMounted(designer) {
24
+ return failResult("NOT_MOUNTED", {
25
+ designer,
26
+ message: `The ${designer} designer is not mounted on this page right now.`
27
+ });
28
+ }
29
+ export function rejected(errors) {
30
+ return failResult("REJECTED", { errors: [...errors] });
31
+ }
32
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKhD,SAAS,UAAU,CAAC,OAAgC;IAClD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAO,GAA4B,EAAE;IAC5D,OAAO,UAAU,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAiB,EAAE,MAAM,GAA4B,EAAE;IAChF,OAAO,UAAU,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,QAAgB;IAChE,OAAO,UAAU,CAAC,eAAe,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAkD;IAC3E,OAAO,UAAU,CAAC,aAAa,EAAE;QAC/B,QAAQ;QACR,OAAO,EAAE,OAAO,QAAQ,kDAAkD;KAC3E,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAyB;IAChD,OAAO,UAAU,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC"}
package/dist/tool.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ /** Descriptor construction shared by every tool module. */
2
+ import type { WebMcpTool, WebMcpToolResult } from "./types.js";
3
+ export type NameOf = (suffix: string) => string;
4
+ /** A closed object schema: every accepted argument named, nothing else allowed. */
5
+ export declare function objectSchema(properties: Record<string, unknown>, required?: readonly string[]): Record<string, unknown>;
6
+ export interface ToolSpec {
7
+ name: string;
8
+ title: string;
9
+ description: string;
10
+ inputSchema: Record<string, unknown>;
11
+ readOnly?: boolean;
12
+ execute(input: unknown): WebMcpToolResult | Promise<WebMcpToolResult>;
13
+ }
14
+ export declare function defineTool(spec: ToolSpec): WebMcpTool;
15
+ /** The sentence every editing tool ends with — the boundary agents must hear every time. */
16
+ export declare const PERSON_SAVES = "Nothing is saved by this tool: the person reviews the result in the designer and saves.";
17
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE/D,MAAM,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAEhD,mFAAmF;AACnF,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,QAAQ,GAAE,SAAS,MAAM,EAAO,GAC/B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOzB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACvE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CASrD;AAED,4FAA4F;AAC5F,eAAO,MAAM,YAAY,4FAA4F,CAAC"}
package/dist/tool.js ADDED
@@ -0,0 +1,22 @@
1
+ /** A closed object schema: every accepted argument named, nothing else allowed. */
2
+ export function objectSchema(properties, required = []) {
3
+ return {
4
+ type: "object",
5
+ properties,
6
+ ...(required.length > 0 ? { required: [...required] } : {}),
7
+ additionalProperties: false
8
+ };
9
+ }
10
+ export function defineTool(spec) {
11
+ return {
12
+ name: spec.name,
13
+ title: spec.title,
14
+ description: spec.description,
15
+ inputSchema: spec.inputSchema,
16
+ ...(spec.readOnly === true ? { annotations: { readOnlyHint: true } } : {}),
17
+ execute: async (input) => spec.execute(input)
18
+ };
19
+ }
20
+ /** The sentence every editing tool ends with — the boundary agents must hear every time. */
21
+ export const PERSON_SAVES = "Nothing is saved by this tool: the person reviews the result in the designer and saves.";
22
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"AAKA,mFAAmF;AACnF,MAAM,UAAU,YAAY,CAC1B,UAAmC,EACnC,QAAQ,GAAsB,EAAE;IAEhC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,UAAU;QACV,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,oBAAoB,EAAE,KAAK;KAC5B,CAAC;AACJ,CAAC;AAWD,MAAM,UAAU,UAAU,CAAC,IAAc;IACvC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,MAAM,CAAC,MAAM,YAAY,GAAG,yFAAyF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { DesignerSources, ToolsOptions, WebMcpTool } from "./types.js";
2
+ export declare const DEFAULT_PREFIX = "widgentic";
3
+ export declare function designerTools(sources: DesignerSources, options?: ToolsOptions): WebMcpTool[];
4
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG5E,eAAO,MAAM,cAAc,cAAc,CAAC;AAI1C,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,GAAE,YAAiB,GAAG,UAAU,EAAE,CAahG"}
package/dist/tools.js ADDED
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The descriptor factory: pure, no browser API — hosts and tests inspect the
3
+ * tools before anything is registered. Only designers with a source get tools;
4
+ * the token reference tool is always present.
5
+ */
6
+ import { actionTools, schemaTools, themeTools } from "./entry-tools.js";
7
+ import { themeTokenSpecsTool } from "./reference-tools.js";
8
+ import { widgetTools } from "./widget-tools.js";
9
+ export const DEFAULT_PREFIX = "widgentic";
10
+ /** Prefixes are identifiers: a host namespaces its tools, it does not encode data in them. */
11
+ const PREFIX = /^[a-z][a-z0-9_]{0,31}$/;
12
+ export function designerTools(sources, options = {}) {
13
+ const prefix = options.prefix ?? DEFAULT_PREFIX;
14
+ if (!PREFIX.test(prefix)) {
15
+ throw new TypeError(`Tool prefix '${prefix}' must be lowercase letters, digits and underscores, starting with a letter (max 32).`);
16
+ }
17
+ const name = (suffix) => `${prefix}_${suffix}`;
18
+ const tools = [];
19
+ if (sources.widget !== undefined)
20
+ tools.push(...widgetTools(sources.widget, name));
21
+ if (sources.theme !== undefined)
22
+ tools.push(...themeTools(sources.theme, name));
23
+ if (sources.schema !== undefined)
24
+ tools.push(...schemaTools(sources.schema, name));
25
+ if (sources.action !== undefined)
26
+ tools.push(...actionTools(sources.action, name));
27
+ tools.push(themeTokenSpecsTool(name));
28
+ return tools;
29
+ }
30
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC;AAC1C,8FAA8F;AAC9F,MAAM,MAAM,GAAG,wBAAwB,CAAC;AAExC,MAAM,UAAU,aAAa,CAAC,OAAwB,EAAE,OAAO,GAAiB,EAAE;IAChF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,SAAS,CAAC,gBAAgB,MAAM,uFAAuF,CAAC,CAAC;IACrI,CAAC;IACD,MAAM,IAAI,GAAW,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;IACvD,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACnF,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAChF,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACnF,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACnF,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * The shapes this package shares with hosts: the WebMCP tool descriptor (a
3
+ * duck-typed subset of the spec's `ModelContextTool`, so no vendor typings are
4
+ * required), the model-context surface it registers on, and the designer
5
+ * sources a host hands over.
6
+ */
7
+ import type { ActionDesignerHandle, DesignerHandle, SchemaDesignerHandle, ThemeDesignerHandle } from "@widgentic/designer";
8
+ export interface WebMcpToolAnnotations {
9
+ /** The tool changes nothing — agents may run it without a confirmation step. */
10
+ readOnlyHint?: boolean;
11
+ untrustedContentHint?: boolean;
12
+ }
13
+ export interface WebMcpTextContent {
14
+ type: "text";
15
+ text: string;
16
+ }
17
+ /** Every widgentic tool resolves to MCP-shaped text content carrying a JSON document. */
18
+ export interface WebMcpToolResult {
19
+ content: WebMcpTextContent[];
20
+ }
21
+ export interface WebMcpExecuteOptions {
22
+ signal?: AbortSignal;
23
+ }
24
+ export interface WebMcpTool {
25
+ name: string;
26
+ /** Short human label — browsers list it in their "site tools" UI. */
27
+ title?: string;
28
+ description: string;
29
+ /** JSON Schema for the arguments; every widgentic tool's is a closed object schema. */
30
+ inputSchema: Record<string, unknown>;
31
+ annotations?: WebMcpToolAnnotations;
32
+ execute(input: unknown, options?: WebMcpExecuteOptions): Promise<WebMcpToolResult>;
33
+ }
34
+ /**
35
+ * The part of `document.modelContext` / `navigator.modelContext` this package
36
+ * uses. `registerTool` may return a promise (the spec) or nothing (early
37
+ * builds); `unregisterTool` exists only on builds that pre-date the abort
38
+ * signal option.
39
+ */
40
+ export interface ModelContextLike {
41
+ registerTool(tool: WebMcpTool, options?: {
42
+ signal?: AbortSignal;
43
+ }): unknown;
44
+ unregisterTool?(name: string): unknown;
45
+ }
46
+ /**
47
+ * Getters, not handles: hosts remount designers (tab switches), so each call
48
+ * resolves the CURRENT handle. A getter may do work — open the section that
49
+ * mounts the designer — and may return nothing, which the tools report as
50
+ * `NOT_MOUNTED`.
51
+ */
52
+ export interface DesignerSources {
53
+ widget?: () => DesignerHandle | undefined;
54
+ theme?: () => ThemeDesignerHandle | undefined;
55
+ schema?: () => SchemaDesignerHandle | undefined;
56
+ action?: () => ActionDesignerHandle | undefined;
57
+ }
58
+ export interface ToolsOptions {
59
+ /** Tool-name prefix (`<prefix>_widget_draft_get`, …). Default `widgentic`. */
60
+ prefix?: string;
61
+ }
62
+ export interface RegisterOptions {
63
+ /** Explicit model context; wins over feature detection (tests, polyfills). */
64
+ modelContext?: ModelContextLike;
65
+ /** A host signal that also disposes the registration when aborted. */
66
+ signal?: AbortSignal;
67
+ }
68
+ export interface ExposeOptions extends ToolsOptions, RegisterOptions {
69
+ /** Extra host tools registered under the same signal and reported in the same result. */
70
+ tools?: WebMcpTool[];
71
+ }
72
+ export interface RegisterFailure {
73
+ name: string;
74
+ message: string;
75
+ }
76
+ export interface RegisterResult {
77
+ /** False when the page has no model context: nothing was registered, nothing threw. */
78
+ supported: boolean;
79
+ registered: string[];
80
+ failed: RegisterFailure[];
81
+ /** Aborts the signal (and unregisters by name where the context supports it); idempotent. */
82
+ dispose(): void;
83
+ }
84
+ export interface ExposeResult extends RegisterResult {
85
+ /** The descriptors that were offered, registered or not. */
86
+ tools: WebMcpTool[];
87
+ }
88
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,qBAAqB;IACpC,gFAAgF;IAChF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,yFAAyF;AACzF,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACpF;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC;IAC5E,cAAc,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACxC;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,cAAc,GAAG,SAAS,CAAC;IAC1C,KAAK,CAAC,EAAE,MAAM,mBAAmB,GAAG,SAAS,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,oBAAoB,GAAG,SAAS,CAAC;IAChD,MAAM,CAAC,EAAE,MAAM,oBAAoB,GAAG,SAAS,CAAC;CACjD;AAED,MAAM,WAAW,YAAY;IAC3B,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,sEAAsE;IACtE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY,EAAE,eAAe;IAClE,yFAAyF;IACzF,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,uFAAuF;IACvF,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,6FAA6F;IAC7F,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,4DAA4D;IAC5D,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Widget designer tools: read the draft the person is looking at, load a
3
+ * definition into it, replace its example data, set its preview theme. Every
4
+ * edit goes through the designer's own validation and is visible immediately.
5
+ */
6
+ import type { DesignerHandle } from "@widgentic/designer";
7
+ import type { NameOf } from "./tool.js";
8
+ import type { WebMcpTool } from "./types.js";
9
+ export declare function widgetTools(source: () => DesignerHandle | undefined, name: NameOf): WebMcpTool[];
10
+ //# sourceMappingURL=widget-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-tools.d.ts","sourceRoot":"","sources":["../src/widget-tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAuB,cAAc,EAAiC,MAAM,qBAAqB,CAAC;AAK9G,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA2C7C,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,cAAc,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CA+FhG"}
@@ -0,0 +1,135 @@
1
+ import { deriveDiagnostics } from "@widgentic/designer";
2
+ import { isPlainObject } from "@widgentic/core";
3
+ import { argumentsOf, invalidArgument, notMounted, okResult, rejected } from "./result.js";
4
+ import { defineTool, objectSchema, PERSON_SAVES } from "./tool.js";
5
+ /**
6
+ * The designer computes diagnostics on every change and hands them to
7
+ * subscribers; there is no getter. Subscribe once per handle so the tools
8
+ * return exactly what the designer computed for the change they made.
9
+ * Before the first change nothing is cached — then derive without the host's
10
+ * shared entries and say so (`diagnosticsDerived`), because unknown schema or
11
+ * action references may be over-reported there.
12
+ */
13
+ const latest = new WeakMap();
14
+ const tracked = new WeakSet();
15
+ function track(handle) {
16
+ if (tracked.has(handle))
17
+ return;
18
+ tracked.add(handle);
19
+ handle.subscribe((_draft, diagnostics) => {
20
+ latest.set(handle, diagnostics);
21
+ });
22
+ }
23
+ function diagnosticsOf(handle) {
24
+ track(handle);
25
+ const cached = latest.get(handle);
26
+ if (cached !== undefined)
27
+ return { diagnostics: cached, diagnosticsDerived: false };
28
+ return { diagnostics: deriveDiagnostics(handle.getDraft()), diagnosticsDerived: true };
29
+ }
30
+ /** The export shape: what the designer's Export panel and the server's import consume. */
31
+ function definitionOf(draft) {
32
+ return {
33
+ kind: draft.kind,
34
+ template: draft.template,
35
+ descriptor: draft.descriptor,
36
+ ...(draft.load !== undefined ? { load: draft.load } : {})
37
+ };
38
+ }
39
+ const DEFINITION_SHAPE = "{ kind, template, descriptor, load? } — kind: a unique id that is not a built-in (card, table, tree, group); " +
40
+ "template: the widgentic template DSL (data SELECTS, you supply every literal; no expressions); " +
41
+ "descriptor: { description (required), dataSchema? | dataSchemaRef?, dataExample?, … }; load?: an http action binding run on first render.";
42
+ export function widgetTools(source, name) {
43
+ const resolve = () => {
44
+ const handle = source();
45
+ if (handle !== undefined)
46
+ track(handle);
47
+ return handle;
48
+ };
49
+ return [
50
+ defineTool({
51
+ name: name("widget_draft_get"),
52
+ title: "Read the widget draft",
53
+ readOnly: true,
54
+ description: "Read the widget definition currently open in the widget designer, in its export shape " +
55
+ DEFINITION_SHAPE +
56
+ " Returns { definition, diagnostics } — diagnostics is the designer's verdict (previewable, kind/template/example/style issues). " +
57
+ "Call this first: it is what the person is looking at.",
58
+ inputSchema: objectSchema({}),
59
+ execute() {
60
+ const handle = resolve();
61
+ if (handle === undefined)
62
+ return notMounted("widget");
63
+ return okResult({ definition: definitionOf(handle.getDraft()), ...diagnosticsOf(handle) });
64
+ }
65
+ }),
66
+ defineTool({
67
+ name: name("widget_draft_load"),
68
+ title: "Load a widget definition",
69
+ description: "Replace the draft in the widget designer with a complete definition " +
70
+ DEFINITION_SHAPE +
71
+ " The designer validates it: applied → { ok: true, diagnostics } and the person sees it immediately; refused → { ok: false, code: 'REJECTED', errors } with the exact messages the designer shows. " +
72
+ "Keep the person's kind unless asked to change it. " +
73
+ PERSON_SAVES,
74
+ inputSchema: objectSchema({ definition: { type: "object", description: "The widget definition in export shape." } }, ["definition"]),
75
+ execute(input) {
76
+ const handle = resolve();
77
+ if (handle === undefined)
78
+ return notMounted("widget");
79
+ const { definition } = argumentsOf(input);
80
+ if (!isPlainObject(definition))
81
+ return invalidArgument("definition", "object");
82
+ const result = handle.loadWidget(definition);
83
+ if (!result.ok)
84
+ return rejected(result.errors);
85
+ return okResult(diagnosticsOf(handle));
86
+ }
87
+ }),
88
+ defineTool({
89
+ name: name("widget_example_data_set"),
90
+ title: "Set the widget's example data",
91
+ description: "Replace the draft's example data (descriptor.dataExample) — the data the preview renders and the example saved with the widget. " +
92
+ "Send { data } matching the draft's data schema. Returns the diagnostics; a mismatch with the schema is reported in diagnostics.example rather than silently previewed. " +
93
+ PERSON_SAVES,
94
+ inputSchema: objectSchema({ data: { description: "Example data for the widget (any JSON value the data schema accepts)." } }, ["data"]),
95
+ execute(input) {
96
+ const handle = resolve();
97
+ if (handle === undefined)
98
+ return notMounted("widget");
99
+ const args = argumentsOf(input);
100
+ if (!("data" in args) || args.data === undefined)
101
+ return invalidArgument("data", "a JSON value");
102
+ const draft = handle.getDraft();
103
+ const next = {
104
+ ...definitionOf(draft),
105
+ descriptor: { ...draft.descriptor, dataExample: args.data }
106
+ };
107
+ const result = handle.loadWidget(next);
108
+ if (!result.ok)
109
+ return rejected(result.errors);
110
+ return okResult(diagnosticsOf(handle));
111
+ }
112
+ }),
113
+ defineTool({
114
+ name: name("widget_theme_set"),
115
+ title: "Set the widget preview theme",
116
+ description: "Set the theme tokens the widget preview is rendered with: { tokens: { <token>: <css value> } } over the --wg-* tokens " +
117
+ "(list them with the theme_token_specs tool; author variables are x-<name>). Validated by the theming rules; refused → { ok: false, code: 'REJECTED', errors }. " +
118
+ "This is the preview theme of the draft, not a saved theme entry.",
119
+ inputSchema: objectSchema({ tokens: { type: "object", description: "Token name → CSS value.", additionalProperties: { type: "string" } } }, ["tokens"]),
120
+ execute(input) {
121
+ const handle = resolve();
122
+ if (handle === undefined)
123
+ return notMounted("widget");
124
+ const { tokens } = argumentsOf(input);
125
+ if (!isPlainObject(tokens))
126
+ return invalidArgument("tokens", "object of token → value");
127
+ const result = handle.loadTheme(tokens);
128
+ if (!result.ok)
129
+ return rejected(result.errors);
130
+ return okResult({ theme: handle.getDraft().theme ?? {} });
131
+ }
132
+ })
133
+ ];
134
+ }
135
+ //# sourceMappingURL=widget-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-tools.js","sourceRoot":"","sources":["../src/widget-tools.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@widgentic/webmcp",
3
+ "version": "0.1.0",
4
+ "description": "BETA — expose mounted widgentic designers as WebMCP tools (document.modelContext), so a browser-side agent can draft into the designer the person is looking at. API may change in minor versions before 1.0.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md",
16
+ "LICENSE"
17
+ ],
18
+ "sideEffects": false,
19
+ "engines": {
20
+ "node": ">=22"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/widgentic/widgentic.git",
25
+ "directory": "packages/webmcp"
26
+ },
27
+ "homepage": "https://widgentic.dev",
28
+ "keywords": [
29
+ "widgentic",
30
+ "webmcp",
31
+ "widgets",
32
+ "mcp",
33
+ "agents"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public",
37
+ "provenance": true
38
+ },
39
+ "scripts": {
40
+ "build": "tsc -p tsconfig.build.json",
41
+ "clean": "rm -rf dist"
42
+ },
43
+ "dependencies": {
44
+ "@widgentic/core": "^0.7.0",
45
+ "@widgentic/designer": "^0.7.0"
46
+ }
47
+ }