@noodleseed/agent-kit 0.69.0 → 0.70.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.
Files changed (52) hide show
  1. package/manifest.json +303 -271
  2. package/package.json +1 -1
  3. package/skills/claude-code/SKILL.md +1 -1
  4. package/skills/claude-code/authoring-mcp-servers/SKILL.md +1 -1
  5. package/skills/claude-code/building-mcp-apps/SKILL.md +1 -1
  6. package/skills/claude-code/connecting-apis-to-mcp/SKILL.md +1 -1
  7. package/skills/claude-code/creating-product-agent-guides/SKILL.md +1 -1
  8. package/skills/claude-code/debugging-mcp-delivery/SKILL.md +1 -1
  9. package/skills/claude-code/deploying-mcp-services/SKILL.md +1 -1
  10. package/skills/claude-code/designing-mcp-products/SKILL.md +1 -1
  11. package/skills/claude-code/embedding-mcp-assistants/SKILL.md +1 -1
  12. package/skills/claude-code/examples/acme-discovery/src/knowledge/faq.txt +10 -0
  13. package/skills/claude-code/examples/acme-discovery/src/knowledge/product.md +7 -0
  14. package/skills/claude-code/examples/acme-discovery/src/server.ts +28 -2
  15. package/skills/claude-code/examples/acme-discovery/test/server.test.ts +10 -0
  16. package/skills/claude-code/examples/food-ordering/README.md +46 -13
  17. package/skills/claude-code/examples/food-ordering/src/server.ts +31 -5
  18. package/skills/claude-code/examples/food-ordering/test/server.test.ts +24 -1
  19. package/skills/claude-code/executing-noodle-plans/SKILL.md +1 -1
  20. package/skills/claude-code/publishing-mcp-integrations/SKILL.md +1 -1
  21. package/skills/claude-code/references/authoring-workflow.md +20 -0
  22. package/skills/claude-code/references/compile-errors.md +2 -0
  23. package/skills/claude-code/references/publishing.md +5 -1
  24. package/skills/claude-code/references/sdk-surface.md +3 -0
  25. package/skills/claude-code/reporting-noodle-feedback/SKILL.md +1 -1
  26. package/skills/claude-code/verifying-mcp-delivery/SKILL.md +1 -1
  27. package/skills/claude-code/wrapping-existing-applications/SKILL.md +1 -1
  28. package/skills/codex/SKILL.md +1 -1
  29. package/skills/codex/authoring-mcp-servers/SKILL.md +1 -1
  30. package/skills/codex/building-mcp-apps/SKILL.md +1 -1
  31. package/skills/codex/connecting-apis-to-mcp/SKILL.md +1 -1
  32. package/skills/codex/creating-product-agent-guides/SKILL.md +1 -1
  33. package/skills/codex/debugging-mcp-delivery/SKILL.md +1 -1
  34. package/skills/codex/deploying-mcp-services/SKILL.md +1 -1
  35. package/skills/codex/designing-mcp-products/SKILL.md +1 -1
  36. package/skills/codex/embedding-mcp-assistants/SKILL.md +1 -1
  37. package/skills/codex/examples/acme-discovery/src/knowledge/faq.txt +10 -0
  38. package/skills/codex/examples/acme-discovery/src/knowledge/product.md +7 -0
  39. package/skills/codex/examples/acme-discovery/src/server.ts +28 -2
  40. package/skills/codex/examples/acme-discovery/test/server.test.ts +10 -0
  41. package/skills/codex/examples/food-ordering/README.md +46 -13
  42. package/skills/codex/examples/food-ordering/src/server.ts +31 -5
  43. package/skills/codex/examples/food-ordering/test/server.test.ts +24 -1
  44. package/skills/codex/executing-noodle-plans/SKILL.md +1 -1
  45. package/skills/codex/publishing-mcp-integrations/SKILL.md +1 -1
  46. package/skills/codex/references/authoring-workflow.md +20 -0
  47. package/skills/codex/references/compile-errors.md +2 -0
  48. package/skills/codex/references/publishing.md +5 -1
  49. package/skills/codex/references/sdk-surface.md +3 -0
  50. package/skills/codex/reporting-noodle-feedback/SKILL.md +1 -1
  51. package/skills/codex/verifying-mcp-delivery/SKILL.md +1 -1
  52. 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.69.0",
3
+ "version": "0.70.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.69.0 hash:13ddce01769caae4 -->
6
+ <!-- noodle-skill version:0.70.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.69.0 hash:11523cb33b9473c0 -->
6
+ <!-- noodle-skill version:0.70.0 hash:11523cb33b9473c0 -->
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.69.0 hash:9fd67d4d24328e15 -->
6
+ <!-- noodle-skill version:0.70.0 hash:9fd67d4d24328e15 -->
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.69.0 hash:21bbd3ec441ffd30 -->
6
+ <!-- noodle-skill version:0.70.0 hash:21bbd3ec441ffd30 -->
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.69.0 hash:0fa48a82fe836cf0 -->
6
+ <!-- noodle-skill version:0.70.0 hash:0fa48a82fe836cf0 -->
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.69.0 hash:aa715bae12041d7c -->
6
+ <!-- noodle-skill version:0.70.0 hash:aa715bae12041d7c -->
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.69.0 hash:93e735b7ffb45df1 -->
6
+ <!-- noodle-skill version:0.70.0 hash:93e735b7ffb45df1 -->
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.69.0 hash:78a6f181b61f92f1 -->
6
+ <!-- noodle-skill version:0.70.0 hash:78a6f181b61f92f1 -->
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.69.0 hash:cc54a67f21c0ecdb -->
6
+ <!-- noodle-skill version:0.70.0 hash:cc54a67f21c0ecdb -->
7
7
 
8
8
  # embedding-mcp-assistants
9
9
 
@@ -0,0 +1,10 @@
1
+ ACME GETAWAYS FAQ
2
+
3
+ Q: Does the assistant book and take payment?
4
+ A: No. The assistant shapes the trip and hands off to Acmes own checkout with a signed link.
5
+
6
+ Q: How current are prices?
7
+ A: Starting prices come from Acmes live site; the assistant cites the page it used.
8
+
9
+ Q: Can I compare destinations?
10
+ A: Yes, ask for a shortlist by vibe, month, or budget.
@@ -0,0 +1,7 @@
1
+ # Acme Getaways product guide
2
+
3
+ Acme Getaways curates four destination types: beach, mountains, culture, and city escapes. Every listing shows a real starting price and the best months to travel. Bookings, payments, and date selection happen on Acmes own site through a signed handoff link; the assistant never takes payment details.
4
+
5
+ ## Cancellation and support
6
+
7
+ All trips can be cancelled free within 48 hours of the handoff. Support runs seven days a week through the chat on book.acme.example.
@@ -1,10 +1,13 @@
1
1
  import {
2
2
  annotations,
3
3
  embeddedAssistant,
4
+ file,
5
+ knowledge,
4
6
  openAICompatible,
5
7
  publicWebsite,
6
8
  secret,
7
9
  server,
10
+ site,
8
11
  tool,
9
12
  variable,
10
13
  z,
@@ -196,6 +199,27 @@ const shortlistGetaway = tool('shortlist_getaway', {
196
199
  }),
197
200
  });
198
201
 
202
+ // Grounding beyond the catalog: two controlled files answer policy/pricing/support questions with
203
+ // citations, and Acme's live public site stays current through its search provider — no sync job,
204
+ // no handwritten search tool. One declaration, one generated `search_destinations` capability.
205
+ const destinations = knowledge('destinations', {
206
+ title: 'Acme Getaways destinations',
207
+ description: 'Public destination, pricing, cancellation, and support information.',
208
+ documents: [
209
+ file('./knowledge/product.md', {
210
+ title: 'Product guide',
211
+ sourceUrl: 'https://getaways.acme.example/product',
212
+ }),
213
+ file('./knowledge/faq.txt', { title: 'FAQ' }),
214
+ ],
215
+ sites: [
216
+ site({
217
+ origin: 'https://getaways.acme.example',
218
+ include: ['/destinations/**', '/pricing', '/support'],
219
+ }),
220
+ ],
221
+ });
222
+
199
223
  export default server(
200
224
  'acme_discovery',
201
225
  {
@@ -217,7 +241,8 @@ export default server(
217
241
  // The same three tools also serve Acme's own marketing site, with no second tool set and no
218
242
  // session backend: a visitor with no account gets the discovery carousel and the booking
219
243
  // handoff. `capabilities` is the whole externally reachable surface — short enough to review in
220
- // one glance, and closed by default when a tool is added to the server later.
244
+ // one glance, and closed by default when a tool is added to the server later. The knowledge
245
+ // component projects its generated search capability the same way a tool does.
221
246
  assistant: embeddedAssistant({
222
247
  model: openAICompatible({
223
248
  baseUrl: variable('ASSISTANT_MODEL_BASE_URL'),
@@ -226,11 +251,12 @@ export default server(
226
251
  }),
227
252
  access: publicWebsite({
228
253
  origins: ['https://getaways.acme.example'],
229
- capabilities: [discoverGetaways, createHandoff, shortlistGetaway],
254
+ capabilities: [destinations, discoverGetaways, createHandoff, shortlistGetaway],
230
255
  }),
231
256
  layout: { mode: 'floating', position: 'bottom-right' },
232
257
  labels: { welcomeHeading: 'Where would you like to go?' },
233
258
  }),
259
+ knowledge: [destinations],
234
260
  },
235
261
  [discoverGetaways, createHandoff, shortlistGetaway],
236
262
  );
@@ -21,4 +21,14 @@ describe('acme-discovery example', () => {
21
21
  expect(text).toContain('create_handoff');
22
22
  expect(text).toContain('shortlist_getaway');
23
23
  });
24
+
25
+ it('declares the grounded knowledge component and its live site scope', async () => {
26
+ const manifest = (await app.toManifest()) as { server: { knowledge?: unknown[] } };
27
+ // One declaration: controlled files plus the live public site, compiled later into the
28
+ // generated `search_destinations` capability with citations.
29
+ expect(manifest.server.knowledge).toHaveLength(1);
30
+ const text = JSON.stringify(manifest);
31
+ expect(text).toContain('knowledge/product.md');
32
+ expect(text).toContain('https://getaways.acme.example');
33
+ });
24
34
  });
@@ -50,8 +50,8 @@ noodle dev
50
50
 
51
51
  The same `server.ts` declares `distribution` metadata for host adapters. It references real packaged images
52
52
  and keeps listing copy, support/legal URLs, and positive/negative review scenarios outside the canonical App
53
- Package and Runtime Artifact. The OpenAI adapter can now project those facts and the generated product skill
54
- into separate local-testing or public-submission archives. A Claude package remains a separate adapter.
53
+ Package and Runtime Artifact. Explicit OpenAI and Claude adapters project those facts with the generated
54
+ product skill; installable plugin archives and directory-submission dossiers remain separate outputs.
55
55
 
56
56
  In another terminal:
57
57
 
@@ -93,6 +93,11 @@ noodle export plugin openai \
93
93
  --output food-ordering-openai.zip
94
94
  ```
95
95
 
96
+ Extract `food-ordering-openai.zip` before using the portal. Upload
97
+ `submission/chatgpt-app-submission.json` to the Codex-assisted import field and
98
+ `submission/food-ordering-skill.zip` to **With MCP → Skills**. The outer ZIP is the complete review kit and
99
+ is not itself a valid skill upload; `submission/README.md` repeats the portal steps.
100
+
96
101
  After registering that same URL in ChatGPT developer mode, substitute its real technical ID to generate the
97
102
  Food Ordering local test package:
98
103
 
@@ -105,6 +110,32 @@ noodle export plugin openai \
105
110
  --output food-ordering-openai-local.zip
106
111
  ```
107
112
 
113
+ ## Export for Claude
114
+
115
+ Claude Code plugin packaging and Anthropic Connector Directory review are separate outputs. Generate the
116
+ installable plugin repository with:
117
+
118
+ ```sh
119
+ noodle export plugin claude \
120
+ --mcp-url https://food-ordering.noodleseed.app/mcp \
121
+ --output food-ordering-claude.zip
122
+ ```
123
+
124
+ Generate the credential-free operator dossier for the remote Connector Directory with:
125
+
126
+ ```sh
127
+ noodle export connector claude \
128
+ --mcp-url https://food-ordering.noodleseed.app/mcp \
129
+ --auth none \
130
+ --category "Food & Drink" \
131
+ --output food-ordering-anthropic-connector.zip
132
+ ```
133
+
134
+ The dossier is deliberately marked `portalUploadable: false`: it gathers the listing, tool annotations,
135
+ use cases, allowed-link candidates, test-account guidance, and MCP App screenshot evidence, but a human must
136
+ verify ownership/compliance and enter the final answers in Anthropic's portal. The plugin ZIP does not
137
+ contain this dossier.
138
+
108
139
  ## Client Setup
109
140
 
110
141
  Use the CLI to print the exact setup flow for your MCP client:
@@ -129,19 +160,21 @@ connector secrets and does not include tokens, caller-key mechanisms, or `.env.n
129
160
 
130
161
  ## Demo Assets
131
162
 
132
- The packaged demo images live under `assets/` and are public web assets when deployed. The current app uses
133
- `assets/noodle-bowl.jpg` as the server branding image.
163
+ The packaged demo images live under `assets/`. The current app uses `assets/noodle-bowl.jpg` as the server
164
+ branding image. Its three distribution screenshots are real, response-only MCP App captures from Noodle
165
+ Devtools at 2× device scale; each is 1640×970 PNG and has the producing user prompt next to its `asset(...)`
166
+ reference in `server.ts`.
134
167
 
135
168
  Image sources:
136
169
 
137
170
  - `assets/noodle-bowl.jpg` — Unsplash photo
138
171
  [`IRv8V9Hb8gI`](https://unsplash.com/photos/IRv8V9Hb8gI), downloaded from Unsplash.
139
- - `assets/lentil-soup.jpg` — Unsplash image
140
- [`photo-1510431198580-7727c9fa1e3a`](https://images.unsplash.com/photo-1510431198580-7727c9fa1e3a), downloaded from Unsplash.
141
- - `assets/mint-lemonade.jpg` — Unsplash photo
142
- [`X7Nx327NtuA`](https://unsplash.com/photos/X7Nx327NtuA) by Imad 786.
143
- - `assets/lentil-soup-openai.png` and `assets/mint-lemonade-openai.png` PNG screenshot renditions
144
- produced from the two corresponding Unsplash references for OpenAI plugin packaging.
145
-
146
- Unsplash photos are free to use under the [Unsplash License](https://unsplash.com/license); attribution is
147
- not required, but source notes are kept here for provenance.
172
+ - `assets/food-ordering-stores.png` — store-discovery state produced by “Help me build a noodle order for
173
+ pickup.”
174
+ - `assets/food-ordering-menu.png` — Harbor Noodles menu state produced by “Show me the Harbor Noodles
175
+ menu.”
176
+ - `assets/food-ordering-handoff.png` checkout-handoff state produced by “Review my spicy miso bowl order
177
+ before checkout.”
178
+
179
+ The Unsplash branding photo is free to use under the [Unsplash License](https://unsplash.com/license);
180
+ attribution is not required, but the source note is kept here for provenance.
@@ -2,8 +2,9 @@ import { annotations, asset, connector, resource, server, tool, z } from '@noodl
2
2
  import { FOOD_ORDERING_AGENT_GUIDE } from './agent-guide.js';
3
3
 
4
4
  const heroImage = asset('assets/noodle-bowl.jpg');
5
- const menuScreenshot = asset('assets/lentil-soup-openai.png');
6
- const cartScreenshot = asset('assets/mint-lemonade-openai.png');
5
+ const storesScreenshot = asset('assets/food-ordering-stores.png');
6
+ const menuScreenshot = asset('assets/food-ordering-menu.png');
7
+ const handoffScreenshot = asset('assets/food-ordering-handoff.png');
7
8
 
8
9
  const state = connector('noodle_state')
9
10
  .version('1.0.0')
@@ -208,7 +209,7 @@ export default server(
208
209
  agentGuide: FOOD_ORDERING_AGENT_GUIDE,
209
210
  distribution: {
210
211
  listing: {
211
- summary: 'Browse local food, build a cart, and review checkout in conversation.',
212
+ summary: 'Build a pickup noodle order.',
212
213
  description:
213
214
  'Food Ordering is a synthetic MCP App that demonstrates store discovery, menu browsing, a caller-scoped cart, fulfilment planning, and explicit checkout handoff.',
214
215
  keywords: ['food', 'ordering', 'delivery'],
@@ -228,8 +229,21 @@ export default server(
228
229
  assets: {
229
230
  icon: { source: heroImage, alt: 'Food Ordering noodle bowl' },
230
231
  screenshots: [
231
- { source: menuScreenshot, alt: 'A featured lentil soup menu item' },
232
- { source: cartScreenshot, alt: 'A mint lemonade shown with the order' },
232
+ {
233
+ source: storesScreenshot,
234
+ alt: 'Food Ordering MCP App showing nearby stores',
235
+ prompt: 'Help me build a noodle order for pickup.',
236
+ },
237
+ {
238
+ source: menuScreenshot,
239
+ alt: 'Food Ordering MCP App showing the Harbor Noodles menu',
240
+ prompt: 'Show me the Harbor Noodles menu.',
241
+ },
242
+ {
243
+ source: handoffScreenshot,
244
+ alt: 'Food Ordering MCP App reviewing a checkout handoff',
245
+ prompt: 'Review my spicy miso bowl order before checkout.',
246
+ },
233
247
  ],
234
248
  },
235
249
  review: {
@@ -242,31 +256,37 @@ export default server(
242
256
  expected:
243
257
  'The ordering app opens with stores and menu items; checkout remains a handoff.',
244
258
  shouldInvoke: true,
259
+ tools: ['open_ordering'],
245
260
  },
246
261
  {
247
262
  id: 'browse_menu',
248
263
  prompt: 'Show me vegetarian menu options nearby.',
249
264
  expected: 'The app shows matching stores and bounded menu choices.',
250
265
  shouldInvoke: true,
266
+ tools: ['search_stores', 'load_menu'],
251
267
  },
252
268
  {
253
269
  id: 'compare_options',
254
270
  prompt: 'Compare the quickest open food options for me.',
255
271
  expected: 'The app grounds its comparison in the synthetic store data.',
256
272
  shouldInvoke: true,
273
+ tools: ['search_stores', 'summarize_ordering_options'],
257
274
  },
258
275
  {
259
276
  id: 'plan_pickup',
260
277
  prompt: 'Plan a pickup order for Friday.',
261
278
  expected: 'The app collects the missing fulfilment details before planning the order.',
262
279
  shouldInvoke: true,
280
+ tools: ['plan_order'],
263
281
  },
264
282
  {
265
283
  id: 'review_checkout',
266
284
  prompt: 'Review my cart before I continue to checkout.',
267
285
  expected: 'The app shows the cart and keeps payment on the explicit external handoff.',
268
286
  shouldInvoke: true,
287
+ tools: ['read_cart', 'prepare_checkout'],
269
288
  },
289
+ // Negative scenarios are non-invocation cases, so they never declare expected tools.
270
290
  {
271
291
  id: 'unrelated_weather',
272
292
  prompt: 'Will it rain tomorrow?',
@@ -373,6 +393,7 @@ export default server(
373
393
  permissions: { clipboardWrite: {} },
374
394
  }),
375
395
  tool('search_stores', {
396
+ title: 'Search stores',
376
397
  visibility: ['app'],
377
398
  description: 'Filter synthetic restaurants for the ordering widget.',
378
399
  annotations: readOnly,
@@ -384,6 +405,7 @@ export default server(
384
405
  fulfil: () => ({ stores }),
385
406
  }),
386
407
  tool('load_menu', {
408
+ title: 'Load store menu',
387
409
  visibility: ['app'],
388
410
  description: 'Load synthetic menu categories and items for one store.',
389
411
  annotations: readOnly,
@@ -396,6 +418,7 @@ export default server(
396
418
  fulfil: ({ input }) => ({ storeId: input.storeId, stores, items: menu }),
397
419
  }),
398
420
  tool('load_item', {
421
+ title: 'Load menu item',
399
422
  visibility: ['app'],
400
423
  description: 'Load item details and modifier options for the ordering widget.',
401
424
  annotations: readOnly,
@@ -404,6 +427,7 @@ export default server(
404
427
  fulfil: ({ input }) => ({ itemId: input.itemId, items: menu }),
405
428
  }),
406
429
  tool('read_cart', {
430
+ title: 'Read ordering cart',
407
431
  visibility: ['app'],
408
432
  description: 'Read the caller-scoped ordering cart state.',
409
433
  annotations: readOnly,
@@ -419,6 +443,7 @@ export default server(
419
443
  },
420
444
  }),
421
445
  tool('sync_cart', {
446
+ title: 'Update ordering cart',
422
447
  visibility: ['app'],
423
448
  description: 'Patch the caller-scoped ordering cart with the widget cart mirror.',
424
449
  annotations: action,
@@ -439,6 +464,7 @@ export default server(
439
464
  },
440
465
  }),
441
466
  tool('prepare_checkout', {
467
+ title: 'Prepare checkout handoff',
442
468
  visibility: ['app'],
443
469
  description: 'Prepare the caller-scoped cart for checkout handoff.',
444
470
  annotations: action,
@@ -24,6 +24,7 @@ describe('food-ordering example', () => {
24
24
  connectors?: Record<string, { id: string; version: string }>;
25
25
  tools: Array<{
26
26
  name: string;
27
+ title?: string;
27
28
  visibility?: string[];
28
29
  annotations?: Record<string, unknown>;
29
30
  output?: unknown;
@@ -103,6 +104,7 @@ describe('food-ordering example', () => {
103
104
  },
104
105
  });
105
106
  expect(manifest.widgets?.map((widget) => widget.name)).toContain('capabilities_card');
107
+ expect(manifest.tools.every((tool) => typeof tool.title === 'string')).toBe(true);
106
108
  });
107
109
 
108
110
  it('projects host distribution metadata separately from the runtime manifest', () => {
@@ -110,7 +112,23 @@ describe('food-ordering example', () => {
110
112
  expect(distribution).toMatchObject({
111
113
  schemaVersion: 1,
112
114
  listing: { summary: expect.stringContaining('Browse local food') },
113
- assets: { icon: { alt: 'Food Ordering noodle bowl' }, screenshots: expect.any(Array) },
115
+ assets: {
116
+ icon: { alt: 'Food Ordering noodle bowl' },
117
+ screenshots: [
118
+ expect.objectContaining({
119
+ alt: 'Food Ordering MCP App showing nearby stores',
120
+ prompt: 'Help me build a noodle order for pickup.',
121
+ }),
122
+ expect.objectContaining({
123
+ alt: 'Food Ordering MCP App showing the Harbor Noodles menu',
124
+ prompt: 'Show me the Harbor Noodles menu.',
125
+ }),
126
+ expect.objectContaining({
127
+ alt: 'Food Ordering MCP App reviewing a checkout handoff',
128
+ prompt: 'Review my spicy miso bowl order before checkout.',
129
+ }),
130
+ ],
131
+ },
114
132
  });
115
133
  const scenarios = distribution?.review.scenarios ?? [];
116
134
  expect(scenarios.filter(({ shouldInvoke }) => shouldInvoke).map(({ id }) => id)).toEqual([
@@ -125,5 +143,10 @@ describe('food-ordering example', () => {
125
143
  'unrelated_email',
126
144
  'unrelated_travel',
127
145
  ]);
146
+ expect(
147
+ scenarios
148
+ .filter(({ shouldInvoke }) => !shouldInvoke)
149
+ .every((scenario) => !('tools' in scenario)),
150
+ ).toBe(true);
128
151
  });
129
152
  });
@@ -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.69.0 hash:6a9f132ddb79352e -->
6
+ <!-- noodle-skill version:0.70.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.69.0 hash:efffbf82007f935d -->
6
+ <!-- noodle-skill version:0.70.0 hash:efffbf82007f935d -->
7
7
 
8
8
  # publishing-mcp-integrations
9
9
 
@@ -405,6 +405,26 @@ Author managed config as `secret("NAME")` / `variable("NAME")` and operate it wi
405
405
 
406
406
  To place the same server tools inside a SaaS web app, declare `assistant: embeddedAssistant(...)` alongside the one server-level brand kit. Read `embedded-assistant.md` before integrating: it owns the HTTPS-origin rule, managed model configuration, required deploy-before-client sequence, customer-backend exchange, browser mount, and verification checklist.
407
407
 
408
+ ## Knowledge components
409
+
410
+ Ground an assistant in controlled documents and the customer's live public site with one declaration — never a handwritten `search`/`fetch` tool pair, a provider name, a sync job, or an index manifest. Declare `knowledge(...)` with `file(...)` documents (UTF-8 `.md`/`.txt`, project-root relative, ≤100 files, ≤1 MiB each, ≤25 MiB per component) and `site(...)` live scopes (exact HTTPS origin plus positive path globs), pass the declaration in the server's `knowledge` array, and include it in a public website surface's `capabilities` to project the generated `search_<name>` capability:
411
+
412
+ ```ts
413
+ const product = knowledge('product', {
414
+ title: 'Product knowledge',
415
+ description: 'Public product, pricing, and support information.',
416
+ documents: [
417
+ file('./knowledge/product.md', { title: 'Product guide' }),
418
+ file('./knowledge/faq.txt', { title: 'FAQ' }),
419
+ ],
420
+ sites: [
421
+ site({ origin: 'https://www.acme.example', include: ['/docs/**', '/pricing'] }),
422
+ ],
423
+ });
424
+ ```
425
+
426
+ The compiler validates and hashes every document at build time (bad extensions, root escapes, symlinks, oversize, and non-UTF-8 fail `noodle validate` with the exact path); deployment publishes versioned files transactionally with the app and the provider keeps live-site content current. Component names are lowercase snake-case; each component implies exactly one generated bounded search capability with cited results.
427
+
408
428
  ## Boundaries
409
429
 
410
430
  Do not hand-author manifest JSON/YAML, runtime artifacts, connector IR, or hosted asset metadata. Do not read or copy secrets, bearer tokens, refresh tokens, static access keys, `.env`, `.env.noodle`, or `~/.noodle/config.json`. Hosted access is identity-based — do not add static data-plane credential paths.
@@ -56,6 +56,8 @@ Run `noodle validate` (add `--json` for the machine-readable envelope, `--fix-pr
56
56
  | `invalid_asset` | Fix the `asset("./path")` reference; the file must exist and be a supported asset type. |
57
57
  | `invalid_capability_requirement` | Correct the declared capability/permission requirement to a supported value. |
58
58
  | `state_secret_field` | Remove the secret-shaped field from widget/handle state; secrets must never be stored in state or sent to widgets. |
59
+ | `invalid_knowledge` | Fix the `knowledge()` declaration: documents must be existing UTF-8 `.md`/`.txt` files inside the project root (no symlinks), within the 100-file / 1 MiB / 25 MiB bounds, and sites need an exact HTTPS origin plus at least one include glob. |
60
+ | `knowledge_unhashed` | Compile from the project root (`noodle validate`/`noodle dev`) so declared knowledge documents can be read and hashed. |
59
61
  | `unknown_connector_alias` | The tool calls a connector alias not declared in `use`/`provides`; add it or fix the alias (see `suggestions`). |
60
62
  | `connector_not_in_catalog` | The referenced connector is not in the resolved catalog; add it to the project connectors or correct the reference. |
61
63
  | `unknown_operation` | The connector has no such operation; use an operation declared on that connector (see `didYouMean`/`suggestions`). |
@@ -23,14 +23,18 @@ Prepare evidence for a reachable production MCP endpoint, accurate capability de
23
23
 
24
24
  When the user explicitly prepares host packaging, author the host-neutral `distribution` option in the same `server.ts`; do not add it during an ordinary build that has no distribution goal. It contains listing, publisher, support, legal, assets, and review facts that cannot be derived safely from MCP capability descriptions.
25
25
 
26
- Reference real packaged images with `asset(...)`, write useful alt text, and include realistic positive and negative review scenarios. Keep reviewer credentials, tokens, secrets, personal data, and test-account passwords out of metadata and source control; supply any authorized reviewer credential out of band.
26
+ Reference real packaged images with `asset(...)`, write useful alt text, and include realistic positive and negative review scenarios. Name the exact expected MCP tools in each positive scenario’s `tools` array. A negative scenario is a non-invocation case: set `shouldInvoke: false` and do not define `tools`. For each MCP App screenshot, add the separate user `prompt` that produces that exact state. Capture only the rendered MCP App response—never the enclosing website, Devtools shell, host conversation, or an unrelated product photo—and meet the selected directory’s current format, dimension, and count limits. Keep reviewer credentials, tokens, secrets, personal data, and test-account passwords out of metadata and source control; supply any authorized reviewer credential out of band.
27
27
 
28
28
  `distribution` is projected separately. It leaves the canonical App Package and Runtime Artifact unchanged, so editing listing copy cannot change deployment execution or product-skill identity. A product package still needs the separately judged `agentGuide`; do not duplicate capability schemas or workflow truth in listing metadata.
29
29
 
30
30
  The shared framework can validate metadata and resolved image bytes, run an available target adapter, and create a reproducible archive. Target-specific availability and exact flags live in `references/cli-commands.md` and the live command catalog (`noodle commands --json`); never invent an unlisted target, bundle, filename, or acceptance claim.
31
31
 
32
+ When a directory has separate installable-plugin and remote-connector submission projections, generate each with its own exact live-catalog command. Never combine their archives or describe an operator dossier as directly portal-uploadable.
33
+
32
34
  Local or repository testing and public-directory submission are distinct packaging states with distinct required inputs. An export command only compiles local source and writes the requested archive. It does not deploy, register, upload, submit, review, or publish the package.
33
35
 
36
+ When an export reports `uploadArtifacts`, treat its output archive as an outer review kit. Extract it, follow the generated instructions, and upload only the named inner artifacts to their matching fields. Never substitute the outer kit for a nested single-purpose upload.
37
+
34
38
  ## Directory-specific evidence
35
39
 
36
40
  Read the selected directory’s current official submission documentation at review time. Record each additional requirement separately from the shared checklist, including listing fields, identity verification, test credentials, screenshots, policy declarations, review limits, and appeal or resubmission steps. Never project one directory’s requirements onto another.
@@ -58,10 +58,13 @@ Platform helper connectors are explicit subpath imports from `@noodleseed/one/pl
58
58
  - `customerEndpoint`
59
59
  - `embeddedAssistant`
60
60
  - `externalExchange`
61
+ - `file`
61
62
  - `gmailConnector`
63
+ - `knowledge`
62
64
  - `managedSecret`
63
65
  - `openAICompatible`
64
66
  - `publicWebsite`
67
+ - `site`
65
68
 
66
69
  ## Authoring signatures
67
70
 
@@ -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.69.0 hash:0f404109f4845683 -->
6
+ <!-- noodle-skill version:0.70.0 hash:0f404109f4845683 -->
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.69.0 hash:6ef6ef551e26b78e -->
6
+ <!-- noodle-skill version:0.70.0 hash:6ef6ef551e26b78e -->
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.69.0 hash:eccc3c158dcafba8 -->
6
+ <!-- noodle-skill version:0.70.0 hash:eccc3c158dcafba8 -->
7
7
 
8
8
  # wrapping-existing-applications
9
9
 
@@ -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.69.0 hash:13ddce01769caae4 -->
6
+ <!-- noodle-skill version:0.70.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.69.0 hash:11523cb33b9473c0 -->
6
+ <!-- noodle-skill version:0.70.0 hash:11523cb33b9473c0 -->
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.69.0 hash:9fd67d4d24328e15 -->
6
+ <!-- noodle-skill version:0.70.0 hash:9fd67d4d24328e15 -->
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.69.0 hash:21bbd3ec441ffd30 -->
6
+ <!-- noodle-skill version:0.70.0 hash:21bbd3ec441ffd30 -->
7
7
 
8
8
  # connecting-apis-to-mcp
9
9