@noodleseed/agent-kit 0.48.1 → 0.49.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 +245 -245
- 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/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 +2 -1
- package/skills/claude-code/examples/customer-auth/README.md +26 -0
- package/skills/claude-code/examples/customer-auth/test/server.test.ts +2 -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/references/embedded-assistant.md +37 -3
- package/skills/claude-code/references/troubleshooting.md +7 -0
- package/skills/claude-code/reporting-noodle-feedback/SKILL.md +1 -1
- package/skills/claude-code/verifying-mcp-delivery/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/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 +2 -1
- package/skills/codex/examples/customer-auth/README.md +26 -0
- package/skills/codex/examples/customer-auth/test/server.test.ts +2 -0
- package/skills/codex/executing-noodle-plans/SKILL.md +1 -1
- package/skills/codex/publishing-mcp-integrations/SKILL.md +1 -1
- package/skills/codex/references/embedded-assistant.md +37 -3
- package/skills/codex/references/troubleshooting.md +7 -0
- package/skills/codex/reporting-noodle-feedback/SKILL.md +1 -1
- package/skills/codex/verifying-mcp-delivery/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.49.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.49.0 hash:cd6ca0d915e6acb9 -->
|
|
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.49.0 hash:0b2fd8c7e43fc69f -->
|
|
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.49.0 hash:f7fa54992c8d7692 -->
|
|
7
7
|
|
|
8
8
|
# building-mcp-apps
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: connecting-apis-to-mcp
|
|
|
3
3
|
description: "Use when credentials, an API URL, an OpenAPI document, or an observed response must become real Noodle Seed MCP behavior."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.49.0 hash:1e86b8704f407bd3 -->
|
|
7
7
|
|
|
8
8
|
# connecting-apis-to-mcp
|
|
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.49.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.
|
|
6
|
+
<!-- noodle-skill version:0.49.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.
|
|
6
|
+
<!-- noodle-skill version:0.49.0 hash:76cce86729cffbee -->
|
|
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.49.0 hash:cc54a67f21c0ecdb -->
|
|
7
7
|
|
|
8
8
|
# embedding-mcp-assistants
|
|
9
9
|
|
|
@@ -22,6 +22,7 @@ Deliver the requested assistant embed with identity and credential separation pr
|
|
|
22
22
|
## Required inputs
|
|
23
23
|
|
|
24
24
|
- Application origin and mounting point.
|
|
25
|
+
- Desired built-in or custom browser experience.
|
|
25
26
|
- Identity/session boundary.
|
|
26
27
|
- Requested local or hosted evidence level.
|
|
27
28
|
|
|
@@ -34,6 +34,19 @@ bounded read-only GET checks and never register a client. A successful
|
|
|
34
34
|
`noodle deploy --access customers` reports the same findings as nonblocking warnings; the application team
|
|
35
35
|
repairs the issuer rather than adding a Noodle OAuth proxy.
|
|
36
36
|
|
|
37
|
+
Adding the embedded assistant does not choose or rewrite MCP customer auth. Inspect the exact active
|
|
38
|
+
deployment before changing configuration:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
noodle deployments list --org <org> --app <app> --env <env> --json
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This Firebase bridge intentionally advertises the Noodle authorization server. A direct or federated
|
|
45
|
+
replacement must advertise its configured tenant issuer. If the exact active direct/federated `customers`
|
|
46
|
+
deployment instead advertises the platform issuer, report `customer_auth_state_inconsistent` with only the
|
|
47
|
+
endpoint, deployment ID, server version, and sanitized protected-resource metadata. Do not share tokens or
|
|
48
|
+
secrets, proxy or rewrite metadata, rotate credentials, or redeploy repeatedly to conceal the mismatch.
|
|
49
|
+
|
|
37
50
|
During MCP OAuth login, Noodle Cloud hosts the Firebase bridge page at
|
|
38
51
|
`https://cloud.noodleseed.dev/oauth/customer/firebase/authorize`. The customer app does not add an
|
|
39
52
|
authorization route. The SaaS operator only configures Firebase Auth to allow the Noodle Cloud origin, and
|
|
@@ -335,6 +348,19 @@ rerenders keep the iframe and only a different view or unmount tears down the br
|
|
|
335
348
|
Never inject `part.data.html`, assign it to `srcdoc`, fetch a `ui://` URI, or reproduce the bridge directly. Pages with a
|
|
336
349
|
Content-Security-Policy must include the Noodle service origin in both `connect-src` and `frame-src`.
|
|
337
350
|
|
|
351
|
+
Before the production-equivalent host build, run the presence-only handoff check:
|
|
352
|
+
|
|
353
|
+
```sh
|
|
354
|
+
noodle assistant embed --check --json
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Add application-owned delegated-exchange requirements with repeatable `--require-env NAME` flags. The JSON
|
|
358
|
+
reports required and missing names, CSP status, and post-deploy probes without returning environment values
|
|
359
|
+
or writing scaffold files. Map the names through the production secret manager, CI environment, and any
|
|
360
|
+
secret allowlist; regenerate existing framework-owned environment binding types before the build. Default
|
|
361
|
+
Devtools/model exercises to synthetic data, and obtain approval before sending real connector data to an
|
|
362
|
+
external model.
|
|
363
|
+
|
|
338
364
|
After deployment, verify the public delegated exchange without extracting a customer bearer token or invoking
|
|
339
365
|
a business operation:
|
|
340
366
|
|
|
@@ -24,6 +24,8 @@ describe('customer-auth example', () => {
|
|
|
24
24
|
colorScheme: 'auto',
|
|
25
25
|
});
|
|
26
26
|
expect(manifest.server.auth).toMatchObject({
|
|
27
|
+
kind: 'bridge',
|
|
28
|
+
provider: 'firebase',
|
|
27
29
|
projectId: '${env.FIREBASE_PROJECT_ID}',
|
|
28
30
|
apiKey: '${env.FIREBASE_WEB_API_KEY}',
|
|
29
31
|
authDomain: '${env.FIREBASE_AUTH_DOMAIN}',
|
|
@@ -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.49.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.49.0 hash:efffbf82007f935d -->
|
|
7
7
|
|
|
8
8
|
# publishing-mcp-integrations
|
|
9
9
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
## Contents
|
|
4
4
|
|
|
5
5
|
- Architecture
|
|
6
|
+
- Choose the host experience
|
|
6
7
|
- Author and validate
|
|
7
8
|
- Customize the presentation
|
|
8
9
|
- Configure and deploy
|
|
@@ -13,6 +14,7 @@
|
|
|
13
14
|
- Verified session context (identity and claims)
|
|
14
15
|
- The session response
|
|
15
16
|
- Choose a browser renderer
|
|
17
|
+
- Host readiness and promotion
|
|
16
18
|
- Toolchain requirements
|
|
17
19
|
- Verify the boundary
|
|
18
20
|
- Troubleshooting: symptom to diagnosis
|
|
@@ -21,12 +23,19 @@
|
|
|
21
23
|
|
|
22
24
|
The browser never receives a model key, assistant client secret, MCP token, or raw application session. The embedding SaaS authenticates its own user, its backend exchanges that verified identity through `@noodleseed/assistant/server`, and the browser receives only a short-lived assistant session.
|
|
23
25
|
|
|
24
|
-
Keep
|
|
26
|
+
Keep every credential and identity layer separate:
|
|
25
27
|
|
|
26
28
|
| Owner | Values | Destination |
|
|
27
29
|
| --- | --- | --- |
|
|
30
|
+
| Noodle operator | Login, selected org/app/env | Plugin-managed CLI profile and explicit target; never the SaaS runtime |
|
|
28
31
|
| Noodle deployment | `ASSISTANT_MODEL_BASE_URL`, `ASSISTANT_MODEL`, `ASSISTANT_MODEL_API_KEY` | `noodle variables set` / `noodle secrets set`; never the SaaS environment |
|
|
29
|
-
|
|
|
32
|
+
| Connector/delegated exchange | Connector credentials and any customer-owned token-exchange client | Noodle managed configuration plus the matching customer backend secret manager |
|
|
33
|
+
| SaaS backend | `NOODLE_SERVICE_URL`, `NOODLE_ASSISTANT_CLIENT_ID`, `NOODLE_ASSISTANT_CLIENT_SECRET`, `PUBLIC_APP_ORIGIN` | Backend-only environment or secret manager; never browser code or public-prefixed variables |
|
|
34
|
+
| Browser | Short-lived assistant session only | In memory; never a client secret, model key, connector credential, or raw application session |
|
|
35
|
+
|
|
36
|
+
## Choose the host experience
|
|
37
|
+
|
|
38
|
+
Before choosing code, ask the user which experience belongs in the existing product: the built-in floating, inline, or drawer assistant; a custom chat-first renderer; or a headless client feeding application-owned UI. Default to the built-in floating assistant only when the user has no preference. Preserve the host application until the user opens or submits into the assistant; do not copy one flagship layout into every product.
|
|
30
39
|
|
|
31
40
|
## Author and validate
|
|
32
41
|
|
|
@@ -101,7 +110,9 @@ Do not put these model values in the embedding SaaS environment. A production de
|
|
|
101
110
|
|
|
102
111
|
## Access modes and customer auth
|
|
103
112
|
|
|
104
|
-
Session exchange authenticates with the backend client credentials, so the embed works under any `--access` mode.
|
|
113
|
+
Session exchange authenticates with the backend client credentials, so the embed works under any `--access` mode. The assistant does not select direct MCP access or protected-resource discovery. If protected-resource metadata advertises an unexpected issuer, inspect the exact active deployment before changing auth by following `references/troubleshooting.md`.
|
|
114
|
+
|
|
115
|
+
Add `--access customers` only when verified end customers should also call the MCP endpoint directly. That mode requires `server.auth`; `noodle deploy` preflights the rule locally and fails with `server_auth_required` before contacting the service. Fix by adding auth to server options:
|
|
105
116
|
|
|
106
117
|
```ts
|
|
107
118
|
auth: customerAuth.federatedOidc({
|
|
@@ -464,6 +475,23 @@ assistant.subscribe((event) => {
|
|
|
464
475
|
|
|
465
476
|
`clientContext` and typed `pageContext` are recomputed for each turn. `updateContext(...)` remains the legacy session-exchange context; `updatePageContext(...)` replaces the fresh per-turn application hint. `updateModelContext({ content, structuredContent })` publishes one cohesive renderer snapshot for later message turns without starting a turn; every call replaces the prior snapshot rather than merging fields. These are untrusted data, not conversation history or authorization input, and the boundaries reject credential-shaped or unbounded updates. A message may re-exchange once after a pre-execution `401`; the client never auto-retries interaction decisions. `tool_proposed.arguments` is a complete schema-aware review projection and, for connector-backed tools, names the sole exact connector version/operation/resolved arguments. Sensitive/write-only fields are redacted; truncating or omitting any non-sensitive action field fails closed. Accept is bound to the server-held action and claims at most one execution attempt—clients cannot replace it. Normal terminal outcomes scrub private arguments and continuations immediately; only an accepted action still executing retains them for the one-hour unknown-outcome recovery window, after which it records `interaction_outcome_unknown` and scrubs. Without downstream idempotency this is not an exactly-once business-effect guarantee. To reconcile a lost response, explicitly repeat the same id and decision: the service returns its durable stored outcome without re-execution.
|
|
466
477
|
|
|
478
|
+
## Host readiness and promotion
|
|
479
|
+
|
|
480
|
+
Run the non-mutating host preflight from the embedding application before its production build:
|
|
481
|
+
|
|
482
|
+
```sh
|
|
483
|
+
noodle assistant embed --check --json
|
|
484
|
+
noodle assistant embed --check --json --require-env EXAMPLE_DELEG_CLIENT_SECRET
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
The check reports only required and missing environment names, never their values. It checks both `connect-src` and `frame-src` when a common static host CSP is determinable, fails on missing directives, and marks a dynamic expression unverified instead of guessing. Additional `--require-env` names are application-owned; use them for the customer side of delegated exchange or other backend-only integration requirements.
|
|
488
|
+
|
|
489
|
+
Inspect the host repository for generated environment bindings after adding names. Run its existing generator, review the diff, commit generated types only when that repository requires them, then run the production-equivalent host build. Do not invent a framework command or add a second generator.
|
|
490
|
+
|
|
491
|
+
Promotion checklist: provision each environment in the backend secret manager; map names through the CI environment and any secret allowlist or secrets file; run the presence-only preflight before asset upload; promote configuration before code; run the post-deploy probes from the JSON contract; rotate the assistant client and delegated credential independently, then rerun the same checks.
|
|
492
|
+
|
|
493
|
+
Devtools privacy gate: default model and connector exercises to synthetic or mock data. Before Devtools Chat sends real connector data to an external model, disclose the data flow and obtain the user's approval. A local validation pass is not that approval.
|
|
494
|
+
|
|
467
495
|
## Toolchain requirements
|
|
468
496
|
|
|
469
497
|
- Node.js 20+ for `@noodleseed/assistant/server`.
|
|
@@ -479,6 +507,8 @@ assistant.subscribe((event) => {
|
|
|
479
507
|
- An expired turn re-exchanges once; interaction decisions never auto-retry. An explicit same-decision repeat returns the stored outcome without executing again.
|
|
480
508
|
- Accept, decline, and cancel are single-use. Only accept executes; the server ignores replacement tool arguments.
|
|
481
509
|
- Wrong-origin and malformed-origin requests fail closed.
|
|
510
|
+
- Run the production-equivalent host build after regenerating environment bindings.
|
|
511
|
+
- In a real browser, submit with the keyboard, inspect console and network failures, complete session exchange and one tool turn, and render one linked App before claiming the host works.
|
|
482
512
|
|
|
483
513
|
## Troubleshooting: symptom to diagnosis
|
|
484
514
|
|
|
@@ -492,6 +522,10 @@ assistant.subscribe((event) => {
|
|
|
492
522
|
| Validate rejects an origin | Non-loopback HTTP origin in `allowedOrigins` | Use the exact HTTPS production origin; HTTP is only for `localhost`/`127.0.0.1` |
|
|
493
523
|
| Session exchange returns 404 | `serviceUrl` points at the deployment MCP endpoint | Use the control-plane service URL printed by `noodle assistant clients create` |
|
|
494
524
|
| Session exchange returns 403 `origin is not allowed` | Request origin differs from `allowedOrigins` character-for-character | Align the exact scheme/host/port on both sides and redeploy |
|
|
525
|
+
| Host session 503 | A required backend environment name is absent or mapped into the wrong deployment environment | Run `noodle assistant embed --check --json`, repair the host CI mapping, then probe the session route again |
|
|
526
|
+
| `HEAD` on a widget or session path looks broken | The route contract is `GET` for the hosted sandbox/widget document or `POST` for session exchange; `HEAD` is not the product flow | Exercise the documented method and inspect its response instead of inferring readiness from `HEAD` |
|
|
527
|
+
| Local server reports `listen EPERM` | The coding sandbox blocked loopback binding before application behavior ran | Rerun the same local/browser test with approved loopback permissions; do not change product code |
|
|
528
|
+
| Tool succeeds but the widget is empty | The linked App delivery layer failed: result shape, resource link, CSP frame, or bridge hydration | Inspect the typed result, `view_available`, resource URI, browser console, and hosted frame separately |
|
|
495
529
|
| Hydration or `HTMLElement is not defined` errors | The component mounted during server rendering | Mount client-only (`"use client"` or `next/dynamic` with `ssr: false`) |
|
|
496
530
|
| A tool runs without the expected confirmation | Its compiled annotations omit `confirm: true` or explicitly set `false` | Pass `{ confirm: true }` to the action helper; action hints alone never gate. `noodle check --target embedded-assistant` lists every confirm-gated tool |
|
|
497
531
|
| `${user.claims.<key>}` is empty | Claim not declared in `sessionClaims` (or key typo) — undeclared claims are dropped at exchange | Declare the key in `embeddedAssistant({ sessionClaims })` and redeploy |
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
## Contents
|
|
4
4
|
|
|
5
5
|
- First moves
|
|
6
|
+
- Customer-auth metadata
|
|
6
7
|
- Symptom map
|
|
7
8
|
|
|
8
9
|
## First moves
|
|
@@ -11,6 +12,12 @@ Re-run the local gates before debugging in-host: `noodle validate`, `noodle chec
|
|
|
11
12
|
|
|
12
13
|
For protocol/conformance checks, the headless harness is `@mcpjam/cli`, not a `noodle` subcommand. Use it against a local `noodle dev` URL without an access token, or against hosted URLs through the host/OAuth flow printed by `noodle connect`.
|
|
13
14
|
|
|
15
|
+
## Customer-auth metadata
|
|
16
|
+
|
|
17
|
+
Adding `embeddedAssistant(...)` does not select the MCP access mode or authorization server. Before changing auth, inspect the exact active deployment with `noodle deployments list --org <org> --app <app> --env <env> --json` and match its active deployment ID, server version, and access mode to the endpoint being tested.
|
|
18
|
+
|
|
19
|
+
For `customers` access, Direct or federated customer auth must advertise the configured tenant issuer; a managed Noodle bridge must advertise the Noodle authorization server. Owner-only access advertises the platform authorization server. If a direct or federated `customers` deployment still advertises the platform issuer, treat it as `customer_auth_state_inconsistent` and escalate with the endpoint, active deployment ID, and sanitized protected-resource metadata. Do not proxy, rewrite, rotate, or redeploy to hide the mismatch. Never share bearer tokens, refresh tokens, client secrets, or credential files.
|
|
20
|
+
|
|
14
21
|
## Symptom map
|
|
15
22
|
|
|
16
23
|
| Symptom | Likely cause | Fix |
|
|
@@ -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.49.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.
|
|
6
|
+
<!-- noodle-skill version:0.49.0 hash:6ef6ef551e26b78e -->
|
|
7
7
|
|
|
8
8
|
# verifying-mcp-delivery
|
|
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.49.0 hash:cd6ca0d915e6acb9 -->
|
|
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.49.0 hash:0b2fd8c7e43fc69f -->
|
|
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.49.0 hash:f7fa54992c8d7692 -->
|
|
7
7
|
|
|
8
8
|
# building-mcp-apps
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: connecting-apis-to-mcp
|
|
|
3
3
|
description: "Use when credentials, an API URL, an OpenAPI document, or an observed response must become real Noodle Seed MCP behavior."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- noodle-skill version:0.
|
|
6
|
+
<!-- noodle-skill version:0.49.0 hash:1e86b8704f407bd3 -->
|
|
7
7
|
|
|
8
8
|
# connecting-apis-to-mcp
|
|
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.49.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.
|
|
6
|
+
<!-- noodle-skill version:0.49.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.
|
|
6
|
+
<!-- noodle-skill version:0.49.0 hash:76cce86729cffbee -->
|
|
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.49.0 hash:cc54a67f21c0ecdb -->
|
|
7
7
|
|
|
8
8
|
# embedding-mcp-assistants
|
|
9
9
|
|
|
@@ -22,6 +22,7 @@ Deliver the requested assistant embed with identity and credential separation pr
|
|
|
22
22
|
## Required inputs
|
|
23
23
|
|
|
24
24
|
- Application origin and mounting point.
|
|
25
|
+
- Desired built-in or custom browser experience.
|
|
25
26
|
- Identity/session boundary.
|
|
26
27
|
- Requested local or hosted evidence level.
|
|
27
28
|
|
|
@@ -34,6 +34,19 @@ bounded read-only GET checks and never register a client. A successful
|
|
|
34
34
|
`noodle deploy --access customers` reports the same findings as nonblocking warnings; the application team
|
|
35
35
|
repairs the issuer rather than adding a Noodle OAuth proxy.
|
|
36
36
|
|
|
37
|
+
Adding the embedded assistant does not choose or rewrite MCP customer auth. Inspect the exact active
|
|
38
|
+
deployment before changing configuration:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
noodle deployments list --org <org> --app <app> --env <env> --json
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This Firebase bridge intentionally advertises the Noodle authorization server. A direct or federated
|
|
45
|
+
replacement must advertise its configured tenant issuer. If the exact active direct/federated `customers`
|
|
46
|
+
deployment instead advertises the platform issuer, report `customer_auth_state_inconsistent` with only the
|
|
47
|
+
endpoint, deployment ID, server version, and sanitized protected-resource metadata. Do not share tokens or
|
|
48
|
+
secrets, proxy or rewrite metadata, rotate credentials, or redeploy repeatedly to conceal the mismatch.
|
|
49
|
+
|
|
37
50
|
During MCP OAuth login, Noodle Cloud hosts the Firebase bridge page at
|
|
38
51
|
`https://cloud.noodleseed.dev/oauth/customer/firebase/authorize`. The customer app does not add an
|
|
39
52
|
authorization route. The SaaS operator only configures Firebase Auth to allow the Noodle Cloud origin, and
|
|
@@ -335,6 +348,19 @@ rerenders keep the iframe and only a different view or unmount tears down the br
|
|
|
335
348
|
Never inject `part.data.html`, assign it to `srcdoc`, fetch a `ui://` URI, or reproduce the bridge directly. Pages with a
|
|
336
349
|
Content-Security-Policy must include the Noodle service origin in both `connect-src` and `frame-src`.
|
|
337
350
|
|
|
351
|
+
Before the production-equivalent host build, run the presence-only handoff check:
|
|
352
|
+
|
|
353
|
+
```sh
|
|
354
|
+
noodle assistant embed --check --json
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Add application-owned delegated-exchange requirements with repeatable `--require-env NAME` flags. The JSON
|
|
358
|
+
reports required and missing names, CSP status, and post-deploy probes without returning environment values
|
|
359
|
+
or writing scaffold files. Map the names through the production secret manager, CI environment, and any
|
|
360
|
+
secret allowlist; regenerate existing framework-owned environment binding types before the build. Default
|
|
361
|
+
Devtools/model exercises to synthetic data, and obtain approval before sending real connector data to an
|
|
362
|
+
external model.
|
|
363
|
+
|
|
338
364
|
After deployment, verify the public delegated exchange without extracting a customer bearer token or invoking
|
|
339
365
|
a business operation:
|
|
340
366
|
|
|
@@ -24,6 +24,8 @@ describe('customer-auth example', () => {
|
|
|
24
24
|
colorScheme: 'auto',
|
|
25
25
|
});
|
|
26
26
|
expect(manifest.server.auth).toMatchObject({
|
|
27
|
+
kind: 'bridge',
|
|
28
|
+
provider: 'firebase',
|
|
27
29
|
projectId: '${env.FIREBASE_PROJECT_ID}',
|
|
28
30
|
apiKey: '${env.FIREBASE_WEB_API_KEY}',
|
|
29
31
|
authDomain: '${env.FIREBASE_AUTH_DOMAIN}',
|
|
@@ -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.49.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.49.0 hash:efffbf82007f935d -->
|
|
7
7
|
|
|
8
8
|
# publishing-mcp-integrations
|
|
9
9
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
## Contents
|
|
4
4
|
|
|
5
5
|
- Architecture
|
|
6
|
+
- Choose the host experience
|
|
6
7
|
- Author and validate
|
|
7
8
|
- Customize the presentation
|
|
8
9
|
- Configure and deploy
|
|
@@ -13,6 +14,7 @@
|
|
|
13
14
|
- Verified session context (identity and claims)
|
|
14
15
|
- The session response
|
|
15
16
|
- Choose a browser renderer
|
|
17
|
+
- Host readiness and promotion
|
|
16
18
|
- Toolchain requirements
|
|
17
19
|
- Verify the boundary
|
|
18
20
|
- Troubleshooting: symptom to diagnosis
|
|
@@ -21,12 +23,19 @@
|
|
|
21
23
|
|
|
22
24
|
The browser never receives a model key, assistant client secret, MCP token, or raw application session. The embedding SaaS authenticates its own user, its backend exchanges that verified identity through `@noodleseed/assistant/server`, and the browser receives only a short-lived assistant session.
|
|
23
25
|
|
|
24
|
-
Keep
|
|
26
|
+
Keep every credential and identity layer separate:
|
|
25
27
|
|
|
26
28
|
| Owner | Values | Destination |
|
|
27
29
|
| --- | --- | --- |
|
|
30
|
+
| Noodle operator | Login, selected org/app/env | Plugin-managed CLI profile and explicit target; never the SaaS runtime |
|
|
28
31
|
| Noodle deployment | `ASSISTANT_MODEL_BASE_URL`, `ASSISTANT_MODEL`, `ASSISTANT_MODEL_API_KEY` | `noodle variables set` / `noodle secrets set`; never the SaaS environment |
|
|
29
|
-
|
|
|
32
|
+
| Connector/delegated exchange | Connector credentials and any customer-owned token-exchange client | Noodle managed configuration plus the matching customer backend secret manager |
|
|
33
|
+
| SaaS backend | `NOODLE_SERVICE_URL`, `NOODLE_ASSISTANT_CLIENT_ID`, `NOODLE_ASSISTANT_CLIENT_SECRET`, `PUBLIC_APP_ORIGIN` | Backend-only environment or secret manager; never browser code or public-prefixed variables |
|
|
34
|
+
| Browser | Short-lived assistant session only | In memory; never a client secret, model key, connector credential, or raw application session |
|
|
35
|
+
|
|
36
|
+
## Choose the host experience
|
|
37
|
+
|
|
38
|
+
Before choosing code, ask the user which experience belongs in the existing product: the built-in floating, inline, or drawer assistant; a custom chat-first renderer; or a headless client feeding application-owned UI. Default to the built-in floating assistant only when the user has no preference. Preserve the host application until the user opens or submits into the assistant; do not copy one flagship layout into every product.
|
|
30
39
|
|
|
31
40
|
## Author and validate
|
|
32
41
|
|
|
@@ -101,7 +110,9 @@ Do not put these model values in the embedding SaaS environment. A production de
|
|
|
101
110
|
|
|
102
111
|
## Access modes and customer auth
|
|
103
112
|
|
|
104
|
-
Session exchange authenticates with the backend client credentials, so the embed works under any `--access` mode.
|
|
113
|
+
Session exchange authenticates with the backend client credentials, so the embed works under any `--access` mode. The assistant does not select direct MCP access or protected-resource discovery. If protected-resource metadata advertises an unexpected issuer, inspect the exact active deployment before changing auth by following `references/troubleshooting.md`.
|
|
114
|
+
|
|
115
|
+
Add `--access customers` only when verified end customers should also call the MCP endpoint directly. That mode requires `server.auth`; `noodle deploy` preflights the rule locally and fails with `server_auth_required` before contacting the service. Fix by adding auth to server options:
|
|
105
116
|
|
|
106
117
|
```ts
|
|
107
118
|
auth: customerAuth.federatedOidc({
|
|
@@ -464,6 +475,23 @@ assistant.subscribe((event) => {
|
|
|
464
475
|
|
|
465
476
|
`clientContext` and typed `pageContext` are recomputed for each turn. `updateContext(...)` remains the legacy session-exchange context; `updatePageContext(...)` replaces the fresh per-turn application hint. `updateModelContext({ content, structuredContent })` publishes one cohesive renderer snapshot for later message turns without starting a turn; every call replaces the prior snapshot rather than merging fields. These are untrusted data, not conversation history or authorization input, and the boundaries reject credential-shaped or unbounded updates. A message may re-exchange once after a pre-execution `401`; the client never auto-retries interaction decisions. `tool_proposed.arguments` is a complete schema-aware review projection and, for connector-backed tools, names the sole exact connector version/operation/resolved arguments. Sensitive/write-only fields are redacted; truncating or omitting any non-sensitive action field fails closed. Accept is bound to the server-held action and claims at most one execution attempt—clients cannot replace it. Normal terminal outcomes scrub private arguments and continuations immediately; only an accepted action still executing retains them for the one-hour unknown-outcome recovery window, after which it records `interaction_outcome_unknown` and scrubs. Without downstream idempotency this is not an exactly-once business-effect guarantee. To reconcile a lost response, explicitly repeat the same id and decision: the service returns its durable stored outcome without re-execution.
|
|
466
477
|
|
|
478
|
+
## Host readiness and promotion
|
|
479
|
+
|
|
480
|
+
Run the non-mutating host preflight from the embedding application before its production build:
|
|
481
|
+
|
|
482
|
+
```sh
|
|
483
|
+
noodle assistant embed --check --json
|
|
484
|
+
noodle assistant embed --check --json --require-env EXAMPLE_DELEG_CLIENT_SECRET
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
The check reports only required and missing environment names, never their values. It checks both `connect-src` and `frame-src` when a common static host CSP is determinable, fails on missing directives, and marks a dynamic expression unverified instead of guessing. Additional `--require-env` names are application-owned; use them for the customer side of delegated exchange or other backend-only integration requirements.
|
|
488
|
+
|
|
489
|
+
Inspect the host repository for generated environment bindings after adding names. Run its existing generator, review the diff, commit generated types only when that repository requires them, then run the production-equivalent host build. Do not invent a framework command or add a second generator.
|
|
490
|
+
|
|
491
|
+
Promotion checklist: provision each environment in the backend secret manager; map names through the CI environment and any secret allowlist or secrets file; run the presence-only preflight before asset upload; promote configuration before code; run the post-deploy probes from the JSON contract; rotate the assistant client and delegated credential independently, then rerun the same checks.
|
|
492
|
+
|
|
493
|
+
Devtools privacy gate: default model and connector exercises to synthetic or mock data. Before Devtools Chat sends real connector data to an external model, disclose the data flow and obtain the user's approval. A local validation pass is not that approval.
|
|
494
|
+
|
|
467
495
|
## Toolchain requirements
|
|
468
496
|
|
|
469
497
|
- Node.js 20+ for `@noodleseed/assistant/server`.
|
|
@@ -479,6 +507,8 @@ assistant.subscribe((event) => {
|
|
|
479
507
|
- An expired turn re-exchanges once; interaction decisions never auto-retry. An explicit same-decision repeat returns the stored outcome without executing again.
|
|
480
508
|
- Accept, decline, and cancel are single-use. Only accept executes; the server ignores replacement tool arguments.
|
|
481
509
|
- Wrong-origin and malformed-origin requests fail closed.
|
|
510
|
+
- Run the production-equivalent host build after regenerating environment bindings.
|
|
511
|
+
- In a real browser, submit with the keyboard, inspect console and network failures, complete session exchange and one tool turn, and render one linked App before claiming the host works.
|
|
482
512
|
|
|
483
513
|
## Troubleshooting: symptom to diagnosis
|
|
484
514
|
|
|
@@ -492,6 +522,10 @@ assistant.subscribe((event) => {
|
|
|
492
522
|
| Validate rejects an origin | Non-loopback HTTP origin in `allowedOrigins` | Use the exact HTTPS production origin; HTTP is only for `localhost`/`127.0.0.1` |
|
|
493
523
|
| Session exchange returns 404 | `serviceUrl` points at the deployment MCP endpoint | Use the control-plane service URL printed by `noodle assistant clients create` |
|
|
494
524
|
| Session exchange returns 403 `origin is not allowed` | Request origin differs from `allowedOrigins` character-for-character | Align the exact scheme/host/port on both sides and redeploy |
|
|
525
|
+
| Host session 503 | A required backend environment name is absent or mapped into the wrong deployment environment | Run `noodle assistant embed --check --json`, repair the host CI mapping, then probe the session route again |
|
|
526
|
+
| `HEAD` on a widget or session path looks broken | The route contract is `GET` for the hosted sandbox/widget document or `POST` for session exchange; `HEAD` is not the product flow | Exercise the documented method and inspect its response instead of inferring readiness from `HEAD` |
|
|
527
|
+
| Local server reports `listen EPERM` | The coding sandbox blocked loopback binding before application behavior ran | Rerun the same local/browser test with approved loopback permissions; do not change product code |
|
|
528
|
+
| Tool succeeds but the widget is empty | The linked App delivery layer failed: result shape, resource link, CSP frame, or bridge hydration | Inspect the typed result, `view_available`, resource URI, browser console, and hosted frame separately |
|
|
495
529
|
| Hydration or `HTMLElement is not defined` errors | The component mounted during server rendering | Mount client-only (`"use client"` or `next/dynamic` with `ssr: false`) |
|
|
496
530
|
| A tool runs without the expected confirmation | Its compiled annotations omit `confirm: true` or explicitly set `false` | Pass `{ confirm: true }` to the action helper; action hints alone never gate. `noodle check --target embedded-assistant` lists every confirm-gated tool |
|
|
497
531
|
| `${user.claims.<key>}` is empty | Claim not declared in `sessionClaims` (or key typo) — undeclared claims are dropped at exchange | Declare the key in `embeddedAssistant({ sessionClaims })` and redeploy |
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
## Contents
|
|
4
4
|
|
|
5
5
|
- First moves
|
|
6
|
+
- Customer-auth metadata
|
|
6
7
|
- Symptom map
|
|
7
8
|
|
|
8
9
|
## First moves
|
|
@@ -11,6 +12,12 @@ Re-run the local gates before debugging in-host: `noodle validate`, `noodle chec
|
|
|
11
12
|
|
|
12
13
|
For protocol/conformance checks, the headless harness is `@mcpjam/cli`, not a `noodle` subcommand. Use it against a local `noodle dev` URL without an access token, or against hosted URLs through the host/OAuth flow printed by `noodle connect`.
|
|
13
14
|
|
|
15
|
+
## Customer-auth metadata
|
|
16
|
+
|
|
17
|
+
Adding `embeddedAssistant(...)` does not select the MCP access mode or authorization server. Before changing auth, inspect the exact active deployment with `noodle deployments list --org <org> --app <app> --env <env> --json` and match its active deployment ID, server version, and access mode to the endpoint being tested.
|
|
18
|
+
|
|
19
|
+
For `customers` access, Direct or federated customer auth must advertise the configured tenant issuer; a managed Noodle bridge must advertise the Noodle authorization server. Owner-only access advertises the platform authorization server. If a direct or federated `customers` deployment still advertises the platform issuer, treat it as `customer_auth_state_inconsistent` and escalate with the endpoint, active deployment ID, and sanitized protected-resource metadata. Do not proxy, rewrite, rotate, or redeploy to hide the mismatch. Never share bearer tokens, refresh tokens, client secrets, or credential files.
|
|
20
|
+
|
|
14
21
|
## Symptom map
|
|
15
22
|
|
|
16
23
|
| Symptom | Likely cause | Fix |
|
|
@@ -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.49.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.
|
|
6
|
+
<!-- noodle-skill version:0.49.0 hash:6ef6ef551e26b78e -->
|
|
7
7
|
|
|
8
8
|
# verifying-mcp-delivery
|
|
9
9
|
|