@noodleseed/agent-kit 0.92.0 → 0.93.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/manifest.json +349 -317
- package/package.json +1 -1
- package/skills/claude-code/SKILL.md +1 -1
- package/skills/claude-code/authoring-mcp-servers/SKILL.md +1 -1
- package/skills/claude-code/building-mcp-apps/SKILL.md +1 -1
- package/skills/claude-code/connecting-apis-to-mcp/SKILL.md +1 -1
- package/skills/claude-code/creating-product-agent-guides/SKILL.md +1 -1
- package/skills/claude-code/debugging-mcp-delivery/SKILL.md +1 -1
- package/skills/claude-code/deploying-mcp-services/SKILL.md +1 -1
- package/skills/claude-code/designing-mcp-products/SKILL.md +1 -1
- package/skills/claude-code/embedding-mcp-assistants/SKILL.md +1 -1
- package/skills/claude-code/examples/acme-discovery/README.md +39 -1
- package/skills/claude-code/examples/acme-discovery/site/index.html +189 -0
- package/skills/claude-code/examples/acme-discovery/src/server.ts +5 -0
- package/skills/claude-code/examples/acme-discovery/test/server.test.ts +18 -0
- package/skills/claude-code/examples/acme-discovery/test/site-page.test.ts +50 -0
- package/skills/claude-code/executing-noodle-plans/SKILL.md +1 -1
- package/skills/claude-code/publishing-mcp-integrations/SKILL.md +1 -1
- package/skills/claude-code/reporting-noodle-feedback/SKILL.md +1 -1
- package/skills/claude-code/verifying-mcp-delivery/SKILL.md +1 -1
- package/skills/claude-code/wrapping-existing-applications/SKILL.md +1 -1
- package/skills/codex/SKILL.md +1 -1
- package/skills/codex/authoring-mcp-servers/SKILL.md +1 -1
- package/skills/codex/building-mcp-apps/SKILL.md +1 -1
- package/skills/codex/connecting-apis-to-mcp/SKILL.md +1 -1
- package/skills/codex/creating-product-agent-guides/SKILL.md +1 -1
- package/skills/codex/debugging-mcp-delivery/SKILL.md +1 -1
- package/skills/codex/deploying-mcp-services/SKILL.md +1 -1
- package/skills/codex/designing-mcp-products/SKILL.md +1 -1
- package/skills/codex/embedding-mcp-assistants/SKILL.md +1 -1
- package/skills/codex/examples/acme-discovery/README.md +39 -1
- package/skills/codex/examples/acme-discovery/site/index.html +189 -0
- package/skills/codex/examples/acme-discovery/src/server.ts +5 -0
- package/skills/codex/examples/acme-discovery/test/server.test.ts +18 -0
- package/skills/codex/examples/acme-discovery/test/site-page.test.ts +50 -0
- package/skills/codex/executing-noodle-plans/SKILL.md +1 -1
- package/skills/codex/publishing-mcp-integrations/SKILL.md +1 -1
- package/skills/codex/reporting-noodle-feedback/SKILL.md +1 -1
- package/skills/codex/verifying-mcp-delivery/SKILL.md +1 -1
- package/skills/codex/wrapping-existing-applications/SKILL.md +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noodleseed/agent-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.93.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Self-checking, self-updating agent skills for the Noodle Seed CLI. Authored in this repo by @noodle-borg/agent-kit; this is the published, independently-versioned canonical skills artifact the CLI fetches and verifies.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -3,7 +3,7 @@ name: noodle-seed
|
|
|
3
3
|
description: "Use when building, validating, testing, deploying, or operating a local or hosted Noodle Seed MCP server or app authored in TypeScript with the noodle CLI."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:13ddce01769caae4 -->
|
|
7
7
|
|
|
8
8
|
# Noodle Seed
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: authoring-mcp-servers
|
|
|
3
3
|
description: "Use when creating or extending a headless Noodle Seed MCP server, tool, resource, prompt, or typed model-facing capability."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:dd57a15df15d10b2 -->
|
|
7
7
|
|
|
8
8
|
# authoring-mcp-servers
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: building-mcp-apps
|
|
|
3
3
|
description: "Use when a Noodle Seed MCP App, widget, interactive card, visual interaction, or host-visible UI is the primary requested outcome."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:98c7b07c82a7d7ce -->
|
|
7
7
|
|
|
8
8
|
# building-mcp-apps
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: connecting-apis-to-mcp
|
|
|
3
3
|
description: "Use when all four API-evidence inputs exist—and only then: API base URL, authentication scheme, representative safe read, and observed response."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:8020811f1769c538 -->
|
|
7
7
|
|
|
8
8
|
# connecting-apis-to-mcp
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: creating-product-agent-guides
|
|
|
3
3
|
description: "Use when a Noodle Seed MCP server needs a new or revised product agent guide, App Package skill, or explicit product-skill regeneration."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:0e06e11254563b6a -->
|
|
7
7
|
|
|
8
8
|
# creating-product-agent-guides
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: debugging-mcp-delivery
|
|
|
3
3
|
description: "Use when an existing Noodle Seed MCP project has a concrete validation, runtime, connector, App, host, deployment, or production failure."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:8d75ad13f4b3120a -->
|
|
7
7
|
|
|
8
8
|
# debugging-mcp-delivery
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: deploying-mcp-services
|
|
|
3
3
|
description: "Use when the user explicitly requests a Noodle Seed hosted link, configuration write, deployment, access change, rollback, or connection write."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:3a1e14ff9b98ddbd -->
|
|
7
7
|
|
|
8
8
|
# deploying-mcp-services
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: designing-mcp-products
|
|
|
3
3
|
description: "Use when a Noodle Seed MCP product idea needs conversational fit, user benefit, scope, interaction, or evidence design before implementation."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:a21b2ed9997f9454 -->
|
|
7
7
|
|
|
8
8
|
# designing-mcp-products
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: embedding-mcp-assistants
|
|
|
3
3
|
description: "Use when embedding a Noodle assistant into an existing SaaS or web application with browser, identity, session, and credential boundaries."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:d554d661ed7ac7be -->
|
|
7
7
|
|
|
8
8
|
# embedding-mcp-assistants
|
|
9
9
|
|
|
@@ -7,7 +7,8 @@ deep link. It pairs a `tool` discovery carousel with a model-visible `create_han
|
|
|
7
7
|
server-level `handoff.allowedDomains`.
|
|
8
8
|
|
|
9
9
|
Capability slots: top-of-funnel funnel discipline, discovery carousel widget, `create_handoff` deep-link
|
|
10
|
-
handoff with attribution, `handoff.allowedDomains`, the **public website assistant surface
|
|
10
|
+
handoff with attribution, `handoff.allowedDomains`, the **public website assistant surface** with its
|
|
11
|
+
**WebMCP browser-agent bridge** on a real demo page (`site/index.html`), and a worked
|
|
11
12
|
**design-first** artifact (the UX spec + wireframe below). It shows the "design the experience, then build
|
|
12
13
|
it" flow the `noodle-seed` skill's `references/experience-design.md` teaches.
|
|
13
14
|
|
|
@@ -64,6 +65,43 @@ on whichever origin the backend designates:
|
|
|
64
65
|
The ticket spend after account creation is identical to the one after sign-in; the service never
|
|
65
66
|
operates a login of its own.
|
|
66
67
|
|
|
68
|
+
## Browser agents on Acme's page
|
|
69
|
+
|
|
70
|
+
`site/index.html` is the marketing page itself: static markup, four listings, and the one line a
|
|
71
|
+
customer pastes.
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<script src="https://cloud.noodleseed.dev/v1/assistant/embed.js" data-embed-id="pub_…"></script>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Because the marketing surface sets `webmcp: { enabled: true }`, that same line does a second job in a
|
|
78
|
+
browser that supports WebMCP: the embed registers the session's projected tools with
|
|
79
|
+
`document.modelContext`, so a browser agent — Gemini-in-Chrome, Claude-in-Chrome — can call
|
|
80
|
+
`discover_getaways` or `create_handoff` without a human typing in the panel.
|
|
81
|
+
|
|
82
|
+
What it does **not** do is widen anything. A bridged call carries exactly the embed session's
|
|
83
|
+
authority: the surface's six-capability allowlist, the same policy and budgets, the same audit trail,
|
|
84
|
+
and the same confirmation card on `capture_lead` — the visitor still approves the lead in the panel,
|
|
85
|
+
because a browser agent's consent is not the visitor's. The switch governs *discovery*, not
|
|
86
|
+
permission: it decides whether an agent learns the tools are there. The signed-in account surface
|
|
87
|
+
below leaves it off, which is the point of setting it per surface.
|
|
88
|
+
|
|
89
|
+
Browsers without `document.modelContext` are unaffected; the page and the panel behave exactly as
|
|
90
|
+
they did before.
|
|
91
|
+
|
|
92
|
+
To run it:
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
noodle dev # the server, in one terminal
|
|
96
|
+
npx serve site # the page, in another (any static server works)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`noodle dev` serves the MCP endpoint, not HTML, so the page needs its own server. For a real
|
|
100
|
+
end-to-end run, `noodle deploy` this example, paste the minted `pub_…` id into `site/index.html`, and
|
|
101
|
+
add the origin you serve the page from to the `publicWebsite` `origins` list — the session exchange
|
|
102
|
+
refuses any origin that is not listed. WebMCP itself ships behind an origin trial in Chrome 149+, so
|
|
103
|
+
a browser without the trial enabled shows the assistant panel and no bridge.
|
|
104
|
+
|
|
67
105
|
## The consultative sales gateway
|
|
68
106
|
|
|
69
107
|
When a visitor's plans firm up but they would rather not sign up, the assistant may — with explicit
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>Acme Getaways — small-group trips</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root {
|
|
9
|
+
--ac-teal: #0ea5a4;
|
|
10
|
+
--ac-ink: #0b1b1b;
|
|
11
|
+
--ac-slate: #234a48;
|
|
12
|
+
--ac-line: #e6e8ec;
|
|
13
|
+
}
|
|
14
|
+
* {
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
}
|
|
17
|
+
body {
|
|
18
|
+
margin: 0;
|
|
19
|
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
20
|
+
background: #f4f5f7;
|
|
21
|
+
color: #1a1d22;
|
|
22
|
+
line-height: 1.55;
|
|
23
|
+
}
|
|
24
|
+
header {
|
|
25
|
+
background: var(--ac-ink);
|
|
26
|
+
color: #fff;
|
|
27
|
+
border-bottom: 3px solid var(--ac-teal);
|
|
28
|
+
padding: 34px 24px 30px;
|
|
29
|
+
}
|
|
30
|
+
header .wrap,
|
|
31
|
+
main {
|
|
32
|
+
max-width: 900px;
|
|
33
|
+
margin: 0 auto;
|
|
34
|
+
}
|
|
35
|
+
header h1 {
|
|
36
|
+
margin: 0;
|
|
37
|
+
font-size: 28px;
|
|
38
|
+
letter-spacing: -0.5px;
|
|
39
|
+
}
|
|
40
|
+
header h1 span {
|
|
41
|
+
color: var(--ac-teal);
|
|
42
|
+
}
|
|
43
|
+
header p {
|
|
44
|
+
margin: 6px 0 0;
|
|
45
|
+
font-size: 14px;
|
|
46
|
+
color: #9db3b1;
|
|
47
|
+
}
|
|
48
|
+
main {
|
|
49
|
+
padding: 32px 24px 96px;
|
|
50
|
+
}
|
|
51
|
+
.lede {
|
|
52
|
+
font-size: 16px;
|
|
53
|
+
color: var(--ac-slate);
|
|
54
|
+
margin: 0 0 28px;
|
|
55
|
+
max-width: 60ch;
|
|
56
|
+
}
|
|
57
|
+
.listings {
|
|
58
|
+
display: grid;
|
|
59
|
+
gap: 16px;
|
|
60
|
+
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
|
61
|
+
list-style: none;
|
|
62
|
+
margin: 0;
|
|
63
|
+
padding: 0;
|
|
64
|
+
}
|
|
65
|
+
.listing {
|
|
66
|
+
background: #fff;
|
|
67
|
+
border: 1px solid var(--ac-line);
|
|
68
|
+
border-radius: 12px;
|
|
69
|
+
padding: 18px 20px;
|
|
70
|
+
}
|
|
71
|
+
.listing-name {
|
|
72
|
+
margin: 0;
|
|
73
|
+
font-size: 18px;
|
|
74
|
+
color: var(--ac-ink);
|
|
75
|
+
}
|
|
76
|
+
.listing-region {
|
|
77
|
+
margin: 2px 0 12px;
|
|
78
|
+
font-size: 12px;
|
|
79
|
+
letter-spacing: 0.6px;
|
|
80
|
+
text-transform: uppercase;
|
|
81
|
+
color: var(--ac-teal);
|
|
82
|
+
font-weight: 700;
|
|
83
|
+
}
|
|
84
|
+
.listing p {
|
|
85
|
+
margin: 0 0 12px;
|
|
86
|
+
font-size: 14px;
|
|
87
|
+
color: #4a545c;
|
|
88
|
+
}
|
|
89
|
+
.listing dl {
|
|
90
|
+
display: flex;
|
|
91
|
+
gap: 20px;
|
|
92
|
+
margin: 0;
|
|
93
|
+
font-size: 13px;
|
|
94
|
+
color: var(--ac-slate);
|
|
95
|
+
}
|
|
96
|
+
.listing dt {
|
|
97
|
+
font-size: 11px;
|
|
98
|
+
letter-spacing: 0.5px;
|
|
99
|
+
text-transform: uppercase;
|
|
100
|
+
color: #8a929c;
|
|
101
|
+
}
|
|
102
|
+
.listing dd {
|
|
103
|
+
margin: 0;
|
|
104
|
+
font-weight: 600;
|
|
105
|
+
}
|
|
106
|
+
footer {
|
|
107
|
+
border-top: 1px solid var(--ac-line);
|
|
108
|
+
margin-top: 40px;
|
|
109
|
+
padding-top: 20px;
|
|
110
|
+
font-size: 13px;
|
|
111
|
+
color: #8a929c;
|
|
112
|
+
}
|
|
113
|
+
</style>
|
|
114
|
+
</head>
|
|
115
|
+
<body>
|
|
116
|
+
<header>
|
|
117
|
+
<div class="wrap">
|
|
118
|
+
<h1><span>Acme</span> Getaways</h1>
|
|
119
|
+
<p>Small-group trips, planned in a conversation.</p>
|
|
120
|
+
</div>
|
|
121
|
+
</header>
|
|
122
|
+
|
|
123
|
+
<main>
|
|
124
|
+
<p class="lede">
|
|
125
|
+
Four places we know well. Ask the assistant in the corner to narrow them down, or let the
|
|
126
|
+
browser agent you already run do it for you — it can call the same tools, under the same
|
|
127
|
+
rules.
|
|
128
|
+
</p>
|
|
129
|
+
|
|
130
|
+
<ul class="listings">
|
|
131
|
+
<li class="listing">
|
|
132
|
+
<h3 class="listing-name">Coral Bay</h3>
|
|
133
|
+
<p class="listing-region">Adriatic coast</p>
|
|
134
|
+
<p>Calm swimming coves and a walkable old town — easy for a relaxed first trip.</p>
|
|
135
|
+
<dl>
|
|
136
|
+
<div><dt>From</dt><dd>$890</dd></div>
|
|
137
|
+
<div><dt>Best months</dt><dd>May–Sep</dd></div>
|
|
138
|
+
</dl>
|
|
139
|
+
</li>
|
|
140
|
+
<li class="listing">
|
|
141
|
+
<h3 class="listing-name">Monte Alto</h3>
|
|
142
|
+
<p class="listing-region">Northern Alps</p>
|
|
143
|
+
<p>Ski-in village with beginner slopes and long groomed runs.</p>
|
|
144
|
+
<dl>
|
|
145
|
+
<div><dt>From</dt><dd>$1,120</dd></div>
|
|
146
|
+
<div><dt>Best months</dt><dd>Dec–Mar</dd></div>
|
|
147
|
+
</dl>
|
|
148
|
+
</li>
|
|
149
|
+
<li class="listing">
|
|
150
|
+
<h3 class="listing-name">Old Quarter</h3>
|
|
151
|
+
<p class="listing-region">Central Europe</p>
|
|
152
|
+
<p>Dense museum district and food halls, all reachable on foot.</p>
|
|
153
|
+
<dl>
|
|
154
|
+
<div><dt>From</dt><dd>$640</dd></div>
|
|
155
|
+
<div><dt>Best months</dt><dd>Apr–Oct</dd></div>
|
|
156
|
+
</dl>
|
|
157
|
+
</li>
|
|
158
|
+
<li class="listing">
|
|
159
|
+
<h3 class="listing-name">Harbor City</h3>
|
|
160
|
+
<p class="listing-region">Pacific rim</p>
|
|
161
|
+
<p>Waterfront nightlife and day-trip islands a short ferry away.</p>
|
|
162
|
+
<dl>
|
|
163
|
+
<div><dt>From</dt><dd>$980</dd></div>
|
|
164
|
+
<div><dt>Best months</dt><dd>Sep–Nov</dd></div>
|
|
165
|
+
</dl>
|
|
166
|
+
</li>
|
|
167
|
+
</ul>
|
|
168
|
+
|
|
169
|
+
<footer>
|
|
170
|
+
A fictional brand, for demonstration. Every destination, price, and link is invented.
|
|
171
|
+
</footer>
|
|
172
|
+
</main>
|
|
173
|
+
|
|
174
|
+
<!--
|
|
175
|
+
The whole integration: one line, the same one a customer pastes.
|
|
176
|
+
|
|
177
|
+
The embed mounts <noodle-assistant>, mints a session against the public surface declared in
|
|
178
|
+
`src/server.ts`, and — because that surface sets `webmcp: { enabled: true }` — registers the
|
|
179
|
+
session's projected tools with `document.modelContext` where the browser offers it. A browser
|
|
180
|
+
agent then sees `discover_getaways`, `create_handoff`, `capture_lead` and the rest, and calling
|
|
181
|
+
one carries exactly this session's authority: the same allowlist, the same confirmation cards,
|
|
182
|
+
the same budgets and audit trail as the panel. Browsers without the API ignore all of it.
|
|
183
|
+
|
|
184
|
+
The id below is fictional. Run `noodle deploy` on this example to mint your own, paste it here,
|
|
185
|
+
and add this page's origin to the `publicWebsite` origins list.
|
|
186
|
+
-->
|
|
187
|
+
<script src="https://cloud.noodleseed.dev/v1/assistant/embed.js" data-embed-id="pub_examplepublicembedid00"></script>
|
|
188
|
+
</body>
|
|
189
|
+
</html>
|
|
@@ -343,6 +343,11 @@ export default server(
|
|
|
343
343
|
access: [
|
|
344
344
|
publicWebsite({
|
|
345
345
|
origins: ['https://getaways.acme.example'],
|
|
346
|
+
// A browser agent on Acme's marketing page (Gemini-in-Chrome, Claude-in-Chrome) discovers
|
|
347
|
+
// exactly the capabilities listed below and reaches them over the same authorization,
|
|
348
|
+
// confirmation, budget, and audit path the panel's own calls take: `capture_lead` still
|
|
349
|
+
// stops for its confirmation card. `site/index.html` is the page this runs on.
|
|
350
|
+
webmcp: { enabled: true },
|
|
346
351
|
capabilities: [
|
|
347
352
|
destinations,
|
|
348
353
|
discoverGetaways,
|
|
@@ -69,6 +69,24 @@ describe('acme-discovery example', () => {
|
|
|
69
69
|
expect(manifest.server.assistant?.labels?.signUpAction).toBe('Create free account');
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
+
it('opens the marketing surface to browser agents and leaves the account surface closed', async () => {
|
|
73
|
+
const manifest = await app.toManifest();
|
|
74
|
+
const surfaces = manifest.server.assistant?.surfaces ?? [];
|
|
75
|
+
|
|
76
|
+
// Both front doors, asserted by count first: without it the per-surface claims below read a
|
|
77
|
+
// missing surface as `undefined` and pass, so deleting a surface would silently satisfy them.
|
|
78
|
+
expect(surfaces).toHaveLength(2);
|
|
79
|
+
// ADR 0220: the opt-in governs *discovery* — whether the embed registers this session's already
|
|
80
|
+
// projected tools with `document.modelContext`. A browser agent on Acme's marketing page reaches
|
|
81
|
+
// exactly the six capabilities above, over the same authorization, confirmation, and budget path
|
|
82
|
+
// the panel's own calls take. `capture_lead` still stops for its confirmation card.
|
|
83
|
+
expect(surfaces[0]?.webmcp).toEqual({ enabled: true });
|
|
84
|
+
// Per-surface opt-in exists so the two front doors can answer differently, and here they do: the
|
|
85
|
+
// signed-in account surface carries a traveler's identity, so its tools are not advertised to
|
|
86
|
+
// whatever agent happens to be running in that browser.
|
|
87
|
+
expect(surfaces[1]?.webmcp).toBeUndefined();
|
|
88
|
+
});
|
|
89
|
+
|
|
72
90
|
it('declares the grounded knowledge component and its live site scope', async () => {
|
|
73
91
|
const manifest = (await app.toManifest()) as { server: { knowledge?: unknown[] } };
|
|
74
92
|
// One declaration: controlled files plus the live public site, compiled later into the
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
import app from '../src/server.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `site/index.html` is the demo half of the WebMCP story (ADR 0220): the marketing page a browser
|
|
8
|
+
* agent actually visits. The compiled server says the marketing surface opts in; only a real page
|
|
9
|
+
* running the real snippet shows what that buys.
|
|
10
|
+
*
|
|
11
|
+
* These guard the two properties that make the demo honest rather than the markup, which is meant to
|
|
12
|
+
* be edited: the page mounts the published one-liner and nothing else, and it never advertises a
|
|
13
|
+
* getaway the server cannot discuss.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const page = readFileSync(join(import.meta.dirname, '..', 'site', 'index.html'), 'utf8');
|
|
17
|
+
|
|
18
|
+
describe('the acme-discovery demo page', () => {
|
|
19
|
+
it('mounts the assistant with the published one-line snippet', () => {
|
|
20
|
+
expect(page).toContain('<script src="https://cloud.noodleseed.dev/v1/assistant/embed.js"');
|
|
21
|
+
expect(page).toMatch(/data-embed-id="pub_[a-z0-9]{20,64}"/u);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('carries bootstrap markup only, so the page never borrows the session itself', () => {
|
|
25
|
+
// The bridge lives in the embed bundle, where it runs under the session's authority and budgets.
|
|
26
|
+
// Page-local JavaScript reaching for the same tools would carry none of that, so there is none:
|
|
27
|
+
// the demo's only script is the snippet above, and it has no body of its own.
|
|
28
|
+
expect(page.match(/<script\b/gu)).toHaveLength(1);
|
|
29
|
+
expect(page).toMatch(/data-embed-id="pub_[a-z0-9]{20,64}"><\/script>/u);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('is a placeholder deployment, not a live embed anyone can point at', () => {
|
|
33
|
+
// Copying this file must not aim a stranger's page at a real deployment, so the id is fictional
|
|
34
|
+
// and the README says how to mint your own.
|
|
35
|
+
expect(page).toContain('pub_examplepublicembedid00');
|
|
36
|
+
expect(page).toContain('noodle deploy');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('offers only getaways the server can actually discuss', async () => {
|
|
40
|
+
const catalog = JSON.stringify(await app.toManifest());
|
|
41
|
+
const offered = [...page.matchAll(/<h3 class="listing-name">([^<]+)<\/h3>/gu)].map(
|
|
42
|
+
(match) => match[1],
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
expect(offered.length).toBeGreaterThan(2);
|
|
46
|
+
for (const name of offered) {
|
|
47
|
+
expect(catalog, `${name} is on the page but not in the server's catalog`).toContain(name);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -3,7 +3,7 @@ name: executing-noodle-plans
|
|
|
3
3
|
description: "Use when the user asks to execute an approved, decision-complete implementation plan for a Noodle Seed project task by task with test-first changes, review, recovery, and final verification."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:6a9f132ddb79352e -->
|
|
7
7
|
|
|
8
8
|
# Execute a Noodle Seed implementation plan
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: publishing-mcp-integrations
|
|
|
3
3
|
description: "Use when preparing, reviewing, or submitting a Noodle Seed MCP integration to a host or app directory."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:0ccafb222038f553 -->
|
|
7
7
|
|
|
8
8
|
# publishing-mcp-integrations
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: reporting-noodle-feedback
|
|
|
3
3
|
description: "Use when a Noodle Seed bug, misleading instruction, missing capability, or concrete product improvement should be proposed to the user."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:660cc6ad9469d90f -->
|
|
7
7
|
|
|
8
8
|
# reporting-noodle-feedback
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: verifying-mcp-delivery
|
|
|
3
3
|
description: "Use when proving a Noodle Seed MCP project works at a named compile, local, connector, App, host, deployment, or production evidence level."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:292253cbaed9a3c5 -->
|
|
7
7
|
|
|
8
8
|
# verifying-mcp-delivery
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: wrapping-existing-applications
|
|
|
3
3
|
description: "Use when an existing application has no stable usable API and needs a read-only, identity-first Noodle Seed integration plan before implementation."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:379ab9f64878f1fe -->
|
|
7
7
|
|
|
8
8
|
# wrapping-existing-applications
|
|
9
9
|
|
package/skills/codex/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: noodle-seed
|
|
|
3
3
|
description: "Use when building, validating, testing, deploying, or operating a local or hosted Noodle Seed MCP server or app authored in TypeScript with the noodle CLI."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:13ddce01769caae4 -->
|
|
7
7
|
|
|
8
8
|
# Noodle Seed
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: authoring-mcp-servers
|
|
|
3
3
|
description: "Use when creating or extending a headless Noodle Seed MCP server, tool, resource, prompt, or typed model-facing capability."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:dd57a15df15d10b2 -->
|
|
7
7
|
|
|
8
8
|
# authoring-mcp-servers
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: building-mcp-apps
|
|
|
3
3
|
description: "Use when a Noodle Seed MCP App, widget, interactive card, visual interaction, or host-visible UI is the primary requested outcome."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:98c7b07c82a7d7ce -->
|
|
7
7
|
|
|
8
8
|
# building-mcp-apps
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: connecting-apis-to-mcp
|
|
|
3
3
|
description: "Use when all four API-evidence inputs exist—and only then: API base URL, authentication scheme, representative safe read, and observed response."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:8020811f1769c538 -->
|
|
7
7
|
|
|
8
8
|
# connecting-apis-to-mcp
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: creating-product-agent-guides
|
|
|
3
3
|
description: "Use when a Noodle Seed MCP server needs a new or revised product agent guide, App Package skill, or explicit product-skill regeneration."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:0e06e11254563b6a -->
|
|
7
7
|
|
|
8
8
|
# creating-product-agent-guides
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: debugging-mcp-delivery
|
|
|
3
3
|
description: "Use when an existing Noodle Seed MCP project has a concrete validation, runtime, connector, App, host, deployment, or production failure."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:8d75ad13f4b3120a -->
|
|
7
7
|
|
|
8
8
|
# debugging-mcp-delivery
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: deploying-mcp-services
|
|
|
3
3
|
description: "Use when the user explicitly requests a Noodle Seed hosted link, configuration write, deployment, access change, rollback, or connection write."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:3a1e14ff9b98ddbd -->
|
|
7
7
|
|
|
8
8
|
# deploying-mcp-services
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: designing-mcp-products
|
|
|
3
3
|
description: "Use when a Noodle Seed MCP product idea needs conversational fit, user benefit, scope, interaction, or evidence design before implementation."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:a21b2ed9997f9454 -->
|
|
7
7
|
|
|
8
8
|
# designing-mcp-products
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: embedding-mcp-assistants
|
|
|
3
3
|
description: "Use when embedding a Noodle assistant into an existing SaaS or web application with browser, identity, session, and credential boundaries."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.93.0 hash:d554d661ed7ac7be -->
|
|
7
7
|
|
|
8
8
|
# embedding-mcp-assistants
|
|
9
9
|
|
|
@@ -7,7 +7,8 @@ deep link. It pairs a `tool` discovery carousel with a model-visible `create_han
|
|
|
7
7
|
server-level `handoff.allowedDomains`.
|
|
8
8
|
|
|
9
9
|
Capability slots: top-of-funnel funnel discipline, discovery carousel widget, `create_handoff` deep-link
|
|
10
|
-
handoff with attribution, `handoff.allowedDomains`, the **public website assistant surface
|
|
10
|
+
handoff with attribution, `handoff.allowedDomains`, the **public website assistant surface** with its
|
|
11
|
+
**WebMCP browser-agent bridge** on a real demo page (`site/index.html`), and a worked
|
|
11
12
|
**design-first** artifact (the UX spec + wireframe below). It shows the "design the experience, then build
|
|
12
13
|
it" flow the `noodle-seed` skill's `references/experience-design.md` teaches.
|
|
13
14
|
|
|
@@ -64,6 +65,43 @@ on whichever origin the backend designates:
|
|
|
64
65
|
The ticket spend after account creation is identical to the one after sign-in; the service never
|
|
65
66
|
operates a login of its own.
|
|
66
67
|
|
|
68
|
+
## Browser agents on Acme's page
|
|
69
|
+
|
|
70
|
+
`site/index.html` is the marketing page itself: static markup, four listings, and the one line a
|
|
71
|
+
customer pastes.
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<script src="https://cloud.noodleseed.dev/v1/assistant/embed.js" data-embed-id="pub_…"></script>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Because the marketing surface sets `webmcp: { enabled: true }`, that same line does a second job in a
|
|
78
|
+
browser that supports WebMCP: the embed registers the session's projected tools with
|
|
79
|
+
`document.modelContext`, so a browser agent — Gemini-in-Chrome, Claude-in-Chrome — can call
|
|
80
|
+
`discover_getaways` or `create_handoff` without a human typing in the panel.
|
|
81
|
+
|
|
82
|
+
What it does **not** do is widen anything. A bridged call carries exactly the embed session's
|
|
83
|
+
authority: the surface's six-capability allowlist, the same policy and budgets, the same audit trail,
|
|
84
|
+
and the same confirmation card on `capture_lead` — the visitor still approves the lead in the panel,
|
|
85
|
+
because a browser agent's consent is not the visitor's. The switch governs *discovery*, not
|
|
86
|
+
permission: it decides whether an agent learns the tools are there. The signed-in account surface
|
|
87
|
+
below leaves it off, which is the point of setting it per surface.
|
|
88
|
+
|
|
89
|
+
Browsers without `document.modelContext` are unaffected; the page and the panel behave exactly as
|
|
90
|
+
they did before.
|
|
91
|
+
|
|
92
|
+
To run it:
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
noodle dev # the server, in one terminal
|
|
96
|
+
npx serve site # the page, in another (any static server works)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`noodle dev` serves the MCP endpoint, not HTML, so the page needs its own server. For a real
|
|
100
|
+
end-to-end run, `noodle deploy` this example, paste the minted `pub_…` id into `site/index.html`, and
|
|
101
|
+
add the origin you serve the page from to the `publicWebsite` `origins` list — the session exchange
|
|
102
|
+
refuses any origin that is not listed. WebMCP itself ships behind an origin trial in Chrome 149+, so
|
|
103
|
+
a browser without the trial enabled shows the assistant panel and no bridge.
|
|
104
|
+
|
|
67
105
|
## The consultative sales gateway
|
|
68
106
|
|
|
69
107
|
When a visitor's plans firm up but they would rather not sign up, the assistant may — with explicit
|