@noodleseed/agent-kit 0.79.1 → 0.81.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 (46) hide show
  1. package/manifest.json +273 -273
  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/README.md +5 -0
  13. package/skills/claude-code/examples/acme-discovery/src/server.ts +2 -0
  14. package/skills/claude-code/examples/acme-discovery/test/server.test.ts +7 -0
  15. package/skills/claude-code/examples/customer-auth/README.md +3 -1
  16. package/skills/claude-code/examples/customer-auth/src/server.ts +2 -5
  17. package/skills/claude-code/examples/customer-auth/test/server.test.ts +5 -5
  18. package/skills/claude-code/executing-noodle-plans/SKILL.md +1 -1
  19. package/skills/claude-code/publishing-mcp-integrations/SKILL.md +1 -1
  20. package/skills/claude-code/references/authoring-workflow.md +1 -1
  21. package/skills/claude-code/references/embedded-assistant.md +4 -1
  22. package/skills/claude-code/reporting-noodle-feedback/SKILL.md +1 -1
  23. package/skills/claude-code/verifying-mcp-delivery/SKILL.md +1 -1
  24. package/skills/claude-code/wrapping-existing-applications/SKILL.md +1 -1
  25. package/skills/codex/SKILL.md +1 -1
  26. package/skills/codex/authoring-mcp-servers/SKILL.md +1 -1
  27. package/skills/codex/building-mcp-apps/SKILL.md +1 -1
  28. package/skills/codex/connecting-apis-to-mcp/SKILL.md +1 -1
  29. package/skills/codex/creating-product-agent-guides/SKILL.md +1 -1
  30. package/skills/codex/debugging-mcp-delivery/SKILL.md +1 -1
  31. package/skills/codex/deploying-mcp-services/SKILL.md +1 -1
  32. package/skills/codex/designing-mcp-products/SKILL.md +1 -1
  33. package/skills/codex/embedding-mcp-assistants/SKILL.md +1 -1
  34. package/skills/codex/examples/acme-discovery/README.md +5 -0
  35. package/skills/codex/examples/acme-discovery/src/server.ts +2 -0
  36. package/skills/codex/examples/acme-discovery/test/server.test.ts +7 -0
  37. package/skills/codex/examples/customer-auth/README.md +3 -1
  38. package/skills/codex/examples/customer-auth/src/server.ts +2 -5
  39. package/skills/codex/examples/customer-auth/test/server.test.ts +5 -5
  40. package/skills/codex/executing-noodle-plans/SKILL.md +1 -1
  41. package/skills/codex/publishing-mcp-integrations/SKILL.md +1 -1
  42. package/skills/codex/references/authoring-workflow.md +1 -1
  43. package/skills/codex/references/embedded-assistant.md +4 -1
  44. package/skills/codex/reporting-noodle-feedback/SKILL.md +1 -1
  45. package/skills/codex/verifying-mcp-delivery/SKILL.md +1 -1
  46. 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.79.1",
3
+ "version": "0.81.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.79.1 hash:13ddce01769caae4 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:11523cb33b9473c0 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:9fd67d4d24328e15 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:21bbd3ec441ffd30 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:0fa48a82fe836cf0 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:aa715bae12041d7c -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:93e735b7ffb45df1 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:78a6f181b61f92f1 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:cc54a67f21c0ecdb -->
6
+ <!-- noodle-skill version:0.81.0 hash:cc54a67f21c0ecdb -->
7
7
 
8
8
  # embedding-mcp-assistants
9
9
 
@@ -20,10 +20,15 @@ Acme's marketing site for a visitor with **no account and no session backend**:
20
20
  access: publicWebsite({
21
21
  origins: ['https://getaways.acme.example'],
22
22
  capabilities: [discoverGetaways, createHandoff, shortlistGetaway],
23
+ instructions:
24
+ 'Be a friendly, consultative travel guide, never pushy. Help visitors narrow a getaway before suggesting the next useful step.',
23
25
  }),
24
26
  ```
25
27
 
26
28
  There is no second tool set and no second app — one `server.ts`, projected onto another front door.
29
+ The surface `instructions` add only the website-specific voice and goal; shared product truth stays in
30
+ `server.instructions`. This public guidance is injected into public assistant turns, never MCP
31
+ `initialize` or another assistant surface.
27
32
  `capabilities` is the entire externally reachable surface, so it stays short enough to review at a glance
28
33
  and closed by default: a tool added to this server later is unreachable from the website until someone
29
34
  lists it. A tool that needed a signed-in user could not be listed here at all (the compiler rejects it);
@@ -257,6 +257,8 @@ export default server(
257
257
  access: publicWebsite({
258
258
  origins: ['https://getaways.acme.example'],
259
259
  capabilities: [destinations, discoverGetaways, createHandoff, shortlistGetaway],
260
+ instructions:
261
+ 'Be a friendly, consultative travel guide, never pushy. Help visitors narrow a getaway before suggesting the next useful step. Ground recommendations in Acme knowledge, and clearly separate discovery from booking.',
260
262
  }),
261
263
  layout: { mode: 'floating', position: 'bottom-right' },
262
264
  labels: { welcomeHeading: 'Where would you like to go?' },
@@ -22,6 +22,13 @@ describe('acme-discovery example', () => {
22
22
  expect(text).toContain('shortlist_getaway');
23
23
  });
24
24
 
25
+ it('gives the public website a consultative surface-specific goal', async () => {
26
+ const manifest = await app.toManifest();
27
+ expect(manifest.server.assistant?.surfaces?.[0]?.instructions).toContain(
28
+ 'friendly, consultative travel guide',
29
+ );
30
+ });
31
+
25
32
  it('declares the grounded knowledge component and its live site scope', async () => {
26
33
  const manifest = (await app.toManifest()) as { server: { knowledge?: unknown[] } };
27
34
  // One declaration: controlled files plus the live public site, compiled later into the
@@ -364,6 +364,7 @@ and passes `routing: { endpoints: { customer_api: cluster.apiBaseUrl } }` to
364
364
  browser. Do not copy the route into page context, session claims, tool input, or model instructions.
365
365
 
366
366
  ```bash
367
+ noodle variables set ASSISTANT_ORIGIN https://app.example.com --scope env
367
368
  noodle variables set ASSISTANT_MODEL_BASE_URL https://model.example.com/v1 --scope env
368
369
  noodle variables set ASSISTANT_MODEL your-model --scope env
369
370
  noodle secrets set ASSISTANT_MODEL_API_KEY --scope env
@@ -372,7 +373,8 @@ noodle secrets set CUSTOMER_API_CLIENT_SECRET --scope env
372
373
  noodle check --target embedded-assistant src/server.ts
373
374
  ```
374
375
 
375
- Assistant origins are exact. Production embedding origins must use HTTPS; plain HTTP is accepted only for
376
+ `ASSISTANT_ORIGIN` is the operator-owned production embedding origin, so one source can serve every customer
377
+ without an application fork. Assistant origins are exact. Production embedding origins must use HTTPS; plain HTTP is accepted only for
376
378
  loopback development origins such as `http://localhost:3000`, `http://127.0.0.1:3000`, or
377
379
  `http://[::1]:3000`. `noodle dev` serves the MCP project, not that separate embedding application.
378
380
 
@@ -16,6 +16,7 @@ import {
16
16
  const customerApi = customerEndpoint('customer_api', {
17
17
  allowedHttpsHostSuffixes: ['api.noodleseed.dev'],
18
18
  });
19
+ const assistantOrigin = variable('ASSISTANT_ORIGIN');
19
20
 
20
21
  const noodleseedApi = connector('noodleseed_app_api')
21
22
  .version('1.0.0')
@@ -170,11 +171,7 @@ export default server(
170
171
  }),
171
172
  // Production origins are exact HTTPS; http://localhost:<port> is allowed for local development.
172
173
  access: authenticatedWebsite({
173
- origins: [
174
- 'https://app.noodleseed.com',
175
- 'https://dev.noodleseed.com',
176
- 'http://localhost:3000',
177
- ],
174
+ origins: [assistantOrigin, 'https://dev.noodleseed.com', 'http://localhost:3000'],
178
175
  }),
179
176
  layout: { mode: 'floating', position: 'bottom-right', panelWidth: 420 },
180
177
  labels: {
@@ -14,11 +14,11 @@ describe('customer-auth example', () => {
14
14
  header: { mark: 'status', badge: { text: 'Workspace online', tone: 'success' } },
15
15
  },
16
16
  });
17
- expect(
18
- manifest.server.assistant?.allowedOrigins.every(
19
- (origin) => origin.startsWith('https://') || origin.startsWith('http://localhost:'),
20
- ),
21
- ).toBe(true);
17
+ expect(manifest.server.assistant?.allowedOrigins).toEqual([
18
+ '${env.ASSISTANT_ORIGIN}',
19
+ 'https://dev.noodleseed.com',
20
+ 'http://localhost:3000',
21
+ ]);
22
22
  expect(manifest.server.branding).toMatchObject({
23
23
  name: 'Noodle Seed Assistant',
24
24
  colorScheme: 'auto',
@@ -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.79.1 hash:6a9f132ddb79352e -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:efffbf82007f935d -->
6
+ <!-- noodle-skill version:0.81.0 hash:efffbf82007f935d -->
7
7
 
8
8
  # publishing-mcp-integrations
9
9
 
@@ -105,7 +105,7 @@ export default server('support', { title: 'Support', version: '1.0.0', use: { cr
105
105
  ]);
106
106
  ```
107
107
 
108
- Naming: connector operation names and tool names are lowercase-with-underscores. Map with `${args.field}` for tool/operation inputs and `${response.path}` for the response — the parsed JSON body is bound directly to `${response}`, so there is **no `.body` envelope**; use bracket syntax for array indices (`${response.data[0].id}`) — a dotted numeric index like `.0.` is invalid. Declare URL query parameters with the operation-level `query: ["arg"]` array, **not** inside `request` (which builds only the JSON body). `allowedOrigins` must be literal origin URLs (the SSRF allowlist); `baseUrl` may be a `variable(...)` that differs by env.
108
+ Naming: connector operation names and tool names are lowercase-with-underscores. Map with `${args.field}` for tool/operation inputs and `${response.path}` for the response — the parsed JSON body is bound directly to `${response}`, so there is **no `.body` envelope**; use bracket syntax for array indices (`${response.data[0].id}`) — a dotted numeric index like `.0.` is invalid. Declare URL query parameters with the operation-level `query: ["arg"]` array, **not** inside `request` (which builds only the JSON body). `allowedOrigins` is the SSRF allowlist: use literal exact origins, or the same `variable("STORE_ORIGIN")` as `baseUrl` when one reusable single-origin app is bound per business. A managed origin must resolve to one canonical bare HTTPS origin (exact loopback HTTP is the development exception); never use a wildcard, path, or tenant source edit.
109
109
 
110
110
  More: `auth.kind` is `bearer` | `apiKey` (needs `header`) | `clientCredentials` | `delegatedOAuth` | `delegatedSessionCookie` | `delegatedTokenExchange`. For client credentials use `{ kind: "clientCredentials", tokenUrl, clientId, clientSecret, scopes? }` (RFC-6749 grant); for a non-standard partner token endpoint add `profile: "custom"` with a `custom: { requestFormat, clientIdField, clientSecretField, tokenResponsePath, expirySource }` descriptor. Do not put credential headers in operation `headers`; use connector `auth`. Use `.compute(name, { input, output, run })` for a sandboxed transform; `provides:` (instead of `use:`) exposes a connector only to compute `callOperation`; and `noodle import openapi <file>` generates a connector from an OpenAPI spec.
111
111
 
@@ -60,7 +60,7 @@ assistant: embeddedAssistant({
60
60
  }),
61
61
  ```
62
62
 
63
- Origins are exact: scheme, host, and optional port, with no path, trailing slash, or wildcard. Production origins must be HTTPS; plain HTTP is accepted only for loopback development origins (`http://localhost:<port>`, `http://127.0.0.1:<port>`). `noodle dev` serves the MCP project, not the embedding SaaS.
63
+ Origins are exact: scheme, host, and optional port, with no path, trailing slash, or wildcard. Production origins must be HTTPS; plain HTTP is accepted only for loopback development origins (`http://localhost:<port>`, `http://127.0.0.1:<port>`). `noodle dev` serves the MCP project, not the embedding SaaS. For a public surface it also prints a process-local Embed ID and script; mount that script on the separately running loopback website to test anonymous mint, chat, widgets, and confirmation. The local ID is ephemeral, while a hosted deploy provisions the stable ID behind durable admission counters.
64
64
 
65
65
  ## Product workflow guidance
66
66
 
@@ -79,6 +79,7 @@ access: [
79
79
  publicWebsite({
80
80
  origins: ["https://www.example.com"],
81
81
  capabilities: [answerProductQuestion, requestDemo],
82
+ instructions: "Help visitors understand the best workflow for their goal before inviting a next step.",
82
83
  }),
83
84
  authenticatedWebsite({
84
85
  origins: ["https://app.example.com"],
@@ -89,6 +90,8 @@ access: [
89
90
 
90
91
  At most one public surface (`public` or `mixed`) and at most one authenticated surface, and no origin may appear on two surfaces — otherwise "which projection is this request?" would be ambiguous. Each gets its own embed snippet, budget, and kill switch.
91
92
 
93
+ Keep shared, host-neutral product truth in `server.instructions`. Use a surface `instructions` value only for the voice, goals, boundaries, and next-step invitations appropriate to that front door. It is trimmed, non-empty, and at most 4,000 characters. The service injects it only after binding the exact website surface; it never enters MCP `initialize` or another assistant surface. For a public sales assistant, be consultative rather than pushy: deliver useful diagnosis or guidance before asking for contact details, and never put secrets in instructions.
94
+
92
95
  `publicWebsite` is for a page with no signed-in user. The visitor is an **anonymous principal**, not an empty user: there is no `${user}`, no roles, no scopes, no customer routing, and no delegated credentials. A tool that needs identity — because it reads `${user}` or declares an `authorization` requirement — cannot be projected to a `public` surface, and the compiler says so.
93
96
 
94
97
  A public surface **must** declare `capabilities`: the exact positive allowlist it may reach. It is required by the type, and it is the whole externally reachable surface — a reviewer should read it in one screenful. Anything absent stays private, and a capability added to the server later is excluded until someone lists it. `authenticatedWebsite` may also take `capabilities` to narrow the in-app surface; omitted, it projects the whole server.
@@ -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.79.1 hash:0f404109f4845683 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:6ef6ef551e26b78e -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:eccc3c158dcafba8 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:13ddce01769caae4 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:11523cb33b9473c0 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:9fd67d4d24328e15 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:21bbd3ec441ffd30 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:0fa48a82fe836cf0 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:aa715bae12041d7c -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:93e735b7ffb45df1 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:78a6f181b61f92f1 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:cc54a67f21c0ecdb -->
6
+ <!-- noodle-skill version:0.81.0 hash:cc54a67f21c0ecdb -->
7
7
 
8
8
  # embedding-mcp-assistants
9
9
 
@@ -20,10 +20,15 @@ Acme's marketing site for a visitor with **no account and no session backend**:
20
20
  access: publicWebsite({
21
21
  origins: ['https://getaways.acme.example'],
22
22
  capabilities: [discoverGetaways, createHandoff, shortlistGetaway],
23
+ instructions:
24
+ 'Be a friendly, consultative travel guide, never pushy. Help visitors narrow a getaway before suggesting the next useful step.',
23
25
  }),
24
26
  ```
25
27
 
26
28
  There is no second tool set and no second app — one `server.ts`, projected onto another front door.
29
+ The surface `instructions` add only the website-specific voice and goal; shared product truth stays in
30
+ `server.instructions`. This public guidance is injected into public assistant turns, never MCP
31
+ `initialize` or another assistant surface.
27
32
  `capabilities` is the entire externally reachable surface, so it stays short enough to review at a glance
28
33
  and closed by default: a tool added to this server later is unreachable from the website until someone
29
34
  lists it. A tool that needed a signed-in user could not be listed here at all (the compiler rejects it);
@@ -257,6 +257,8 @@ export default server(
257
257
  access: publicWebsite({
258
258
  origins: ['https://getaways.acme.example'],
259
259
  capabilities: [destinations, discoverGetaways, createHandoff, shortlistGetaway],
260
+ instructions:
261
+ 'Be a friendly, consultative travel guide, never pushy. Help visitors narrow a getaway before suggesting the next useful step. Ground recommendations in Acme knowledge, and clearly separate discovery from booking.',
260
262
  }),
261
263
  layout: { mode: 'floating', position: 'bottom-right' },
262
264
  labels: { welcomeHeading: 'Where would you like to go?' },
@@ -22,6 +22,13 @@ describe('acme-discovery example', () => {
22
22
  expect(text).toContain('shortlist_getaway');
23
23
  });
24
24
 
25
+ it('gives the public website a consultative surface-specific goal', async () => {
26
+ const manifest = await app.toManifest();
27
+ expect(manifest.server.assistant?.surfaces?.[0]?.instructions).toContain(
28
+ 'friendly, consultative travel guide',
29
+ );
30
+ });
31
+
25
32
  it('declares the grounded knowledge component and its live site scope', async () => {
26
33
  const manifest = (await app.toManifest()) as { server: { knowledge?: unknown[] } };
27
34
  // One declaration: controlled files plus the live public site, compiled later into the
@@ -364,6 +364,7 @@ and passes `routing: { endpoints: { customer_api: cluster.apiBaseUrl } }` to
364
364
  browser. Do not copy the route into page context, session claims, tool input, or model instructions.
365
365
 
366
366
  ```bash
367
+ noodle variables set ASSISTANT_ORIGIN https://app.example.com --scope env
367
368
  noodle variables set ASSISTANT_MODEL_BASE_URL https://model.example.com/v1 --scope env
368
369
  noodle variables set ASSISTANT_MODEL your-model --scope env
369
370
  noodle secrets set ASSISTANT_MODEL_API_KEY --scope env
@@ -372,7 +373,8 @@ noodle secrets set CUSTOMER_API_CLIENT_SECRET --scope env
372
373
  noodle check --target embedded-assistant src/server.ts
373
374
  ```
374
375
 
375
- Assistant origins are exact. Production embedding origins must use HTTPS; plain HTTP is accepted only for
376
+ `ASSISTANT_ORIGIN` is the operator-owned production embedding origin, so one source can serve every customer
377
+ without an application fork. Assistant origins are exact. Production embedding origins must use HTTPS; plain HTTP is accepted only for
376
378
  loopback development origins such as `http://localhost:3000`, `http://127.0.0.1:3000`, or
377
379
  `http://[::1]:3000`. `noodle dev` serves the MCP project, not that separate embedding application.
378
380
 
@@ -16,6 +16,7 @@ import {
16
16
  const customerApi = customerEndpoint('customer_api', {
17
17
  allowedHttpsHostSuffixes: ['api.noodleseed.dev'],
18
18
  });
19
+ const assistantOrigin = variable('ASSISTANT_ORIGIN');
19
20
 
20
21
  const noodleseedApi = connector('noodleseed_app_api')
21
22
  .version('1.0.0')
@@ -170,11 +171,7 @@ export default server(
170
171
  }),
171
172
  // Production origins are exact HTTPS; http://localhost:<port> is allowed for local development.
172
173
  access: authenticatedWebsite({
173
- origins: [
174
- 'https://app.noodleseed.com',
175
- 'https://dev.noodleseed.com',
176
- 'http://localhost:3000',
177
- ],
174
+ origins: [assistantOrigin, 'https://dev.noodleseed.com', 'http://localhost:3000'],
178
175
  }),
179
176
  layout: { mode: 'floating', position: 'bottom-right', panelWidth: 420 },
180
177
  labels: {
@@ -14,11 +14,11 @@ describe('customer-auth example', () => {
14
14
  header: { mark: 'status', badge: { text: 'Workspace online', tone: 'success' } },
15
15
  },
16
16
  });
17
- expect(
18
- manifest.server.assistant?.allowedOrigins.every(
19
- (origin) => origin.startsWith('https://') || origin.startsWith('http://localhost:'),
20
- ),
21
- ).toBe(true);
17
+ expect(manifest.server.assistant?.allowedOrigins).toEqual([
18
+ '${env.ASSISTANT_ORIGIN}',
19
+ 'https://dev.noodleseed.com',
20
+ 'http://localhost:3000',
21
+ ]);
22
22
  expect(manifest.server.branding).toMatchObject({
23
23
  name: 'Noodle Seed Assistant',
24
24
  colorScheme: 'auto',
@@ -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.79.1 hash:6a9f132ddb79352e -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:efffbf82007f935d -->
6
+ <!-- noodle-skill version:0.81.0 hash:efffbf82007f935d -->
7
7
 
8
8
  # publishing-mcp-integrations
9
9
 
@@ -105,7 +105,7 @@ export default server('support', { title: 'Support', version: '1.0.0', use: { cr
105
105
  ]);
106
106
  ```
107
107
 
108
- Naming: connector operation names and tool names are lowercase-with-underscores. Map with `${args.field}` for tool/operation inputs and `${response.path}` for the response — the parsed JSON body is bound directly to `${response}`, so there is **no `.body` envelope**; use bracket syntax for array indices (`${response.data[0].id}`) — a dotted numeric index like `.0.` is invalid. Declare URL query parameters with the operation-level `query: ["arg"]` array, **not** inside `request` (which builds only the JSON body). `allowedOrigins` must be literal origin URLs (the SSRF allowlist); `baseUrl` may be a `variable(...)` that differs by env.
108
+ Naming: connector operation names and tool names are lowercase-with-underscores. Map with `${args.field}` for tool/operation inputs and `${response.path}` for the response — the parsed JSON body is bound directly to `${response}`, so there is **no `.body` envelope**; use bracket syntax for array indices (`${response.data[0].id}`) — a dotted numeric index like `.0.` is invalid. Declare URL query parameters with the operation-level `query: ["arg"]` array, **not** inside `request` (which builds only the JSON body). `allowedOrigins` is the SSRF allowlist: use literal exact origins, or the same `variable("STORE_ORIGIN")` as `baseUrl` when one reusable single-origin app is bound per business. A managed origin must resolve to one canonical bare HTTPS origin (exact loopback HTTP is the development exception); never use a wildcard, path, or tenant source edit.
109
109
 
110
110
  More: `auth.kind` is `bearer` | `apiKey` (needs `header`) | `clientCredentials` | `delegatedOAuth` | `delegatedSessionCookie` | `delegatedTokenExchange`. For client credentials use `{ kind: "clientCredentials", tokenUrl, clientId, clientSecret, scopes? }` (RFC-6749 grant); for a non-standard partner token endpoint add `profile: "custom"` with a `custom: { requestFormat, clientIdField, clientSecretField, tokenResponsePath, expirySource }` descriptor. Do not put credential headers in operation `headers`; use connector `auth`. Use `.compute(name, { input, output, run })` for a sandboxed transform; `provides:` (instead of `use:`) exposes a connector only to compute `callOperation`; and `noodle import openapi <file>` generates a connector from an OpenAPI spec.
111
111
 
@@ -60,7 +60,7 @@ assistant: embeddedAssistant({
60
60
  }),
61
61
  ```
62
62
 
63
- Origins are exact: scheme, host, and optional port, with no path, trailing slash, or wildcard. Production origins must be HTTPS; plain HTTP is accepted only for loopback development origins (`http://localhost:<port>`, `http://127.0.0.1:<port>`). `noodle dev` serves the MCP project, not the embedding SaaS.
63
+ Origins are exact: scheme, host, and optional port, with no path, trailing slash, or wildcard. Production origins must be HTTPS; plain HTTP is accepted only for loopback development origins (`http://localhost:<port>`, `http://127.0.0.1:<port>`). `noodle dev` serves the MCP project, not the embedding SaaS. For a public surface it also prints a process-local Embed ID and script; mount that script on the separately running loopback website to test anonymous mint, chat, widgets, and confirmation. The local ID is ephemeral, while a hosted deploy provisions the stable ID behind durable admission counters.
64
64
 
65
65
  ## Product workflow guidance
66
66
 
@@ -79,6 +79,7 @@ access: [
79
79
  publicWebsite({
80
80
  origins: ["https://www.example.com"],
81
81
  capabilities: [answerProductQuestion, requestDemo],
82
+ instructions: "Help visitors understand the best workflow for their goal before inviting a next step.",
82
83
  }),
83
84
  authenticatedWebsite({
84
85
  origins: ["https://app.example.com"],
@@ -89,6 +90,8 @@ access: [
89
90
 
90
91
  At most one public surface (`public` or `mixed`) and at most one authenticated surface, and no origin may appear on two surfaces — otherwise "which projection is this request?" would be ambiguous. Each gets its own embed snippet, budget, and kill switch.
91
92
 
93
+ Keep shared, host-neutral product truth in `server.instructions`. Use a surface `instructions` value only for the voice, goals, boundaries, and next-step invitations appropriate to that front door. It is trimmed, non-empty, and at most 4,000 characters. The service injects it only after binding the exact website surface; it never enters MCP `initialize` or another assistant surface. For a public sales assistant, be consultative rather than pushy: deliver useful diagnosis or guidance before asking for contact details, and never put secrets in instructions.
94
+
92
95
  `publicWebsite` is for a page with no signed-in user. The visitor is an **anonymous principal**, not an empty user: there is no `${user}`, no roles, no scopes, no customer routing, and no delegated credentials. A tool that needs identity — because it reads `${user}` or declares an `authorization` requirement — cannot be projected to a `public` surface, and the compiler says so.
93
96
 
94
97
  A public surface **must** declare `capabilities`: the exact positive allowlist it may reach. It is required by the type, and it is the whole externally reachable surface — a reviewer should read it in one screenful. Anything absent stays private, and a capability added to the server later is excluded until someone lists it. `authenticatedWebsite` may also take `capabilities` to narrow the in-app surface; omitted, it projects the whole server.
@@ -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.79.1 hash:0f404109f4845683 -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:6ef6ef551e26b78e -->
6
+ <!-- noodle-skill version:0.81.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.79.1 hash:eccc3c158dcafba8 -->
6
+ <!-- noodle-skill version:0.81.0 hash:eccc3c158dcafba8 -->
7
7
 
8
8
  # wrapping-existing-applications
9
9