@noodleseed/agent-kit 0.58.0 → 0.58.2

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 (30) hide show
  1. package/manifest.json +241 -241
  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/debugging-mcp-delivery/SKILL.md +1 -1
  8. package/skills/claude-code/deploying-mcp-services/SKILL.md +1 -1
  9. package/skills/claude-code/designing-mcp-products/SKILL.md +1 -1
  10. package/skills/claude-code/embedding-mcp-assistants/SKILL.md +1 -1
  11. package/skills/claude-code/examples/customer-auth/README.md +23 -0
  12. package/skills/claude-code/executing-noodle-plans/SKILL.md +1 -1
  13. package/skills/claude-code/publishing-mcp-integrations/SKILL.md +1 -1
  14. package/skills/claude-code/references/authoring-workflow.md +19 -2
  15. package/skills/claude-code/reporting-noodle-feedback/SKILL.md +1 -1
  16. package/skills/claude-code/verifying-mcp-delivery/SKILL.md +1 -1
  17. package/skills/codex/SKILL.md +1 -1
  18. package/skills/codex/authoring-mcp-servers/SKILL.md +1 -1
  19. package/skills/codex/building-mcp-apps/SKILL.md +1 -1
  20. package/skills/codex/connecting-apis-to-mcp/SKILL.md +1 -1
  21. package/skills/codex/debugging-mcp-delivery/SKILL.md +1 -1
  22. package/skills/codex/deploying-mcp-services/SKILL.md +1 -1
  23. package/skills/codex/designing-mcp-products/SKILL.md +1 -1
  24. package/skills/codex/embedding-mcp-assistants/SKILL.md +1 -1
  25. package/skills/codex/examples/customer-auth/README.md +23 -0
  26. package/skills/codex/executing-noodle-plans/SKILL.md +1 -1
  27. package/skills/codex/publishing-mcp-integrations/SKILL.md +1 -1
  28. package/skills/codex/references/authoring-workflow.md +19 -2
  29. package/skills/codex/reporting-noodle-feedback/SKILL.md +1 -1
  30. 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.58.0",
3
+ "version": "0.58.2",
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.58.0 hash:ec5bfcd0d8165205 -->
6
+ <!-- noodle-skill version:0.58.2 hash:ec5bfcd0d8165205 -->
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.58.0 hash:0b2fd8c7e43fc69f -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:f7fa54992c8d7692 -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:1e86b8704f407bd3 -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:aa715bae12041d7c -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:93e735b7ffb45df1 -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:76cce86729cffbee -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:cc54a67f21c0ecdb -->
6
+ <!-- noodle-skill version:0.58.2 hash:cc54a67f21c0ecdb -->
7
7
 
8
8
  # embedding-mcp-assistants
9
9
 
@@ -60,6 +60,12 @@ const api = connector('noodleseed_app_api')
60
60
  });
61
61
  ```
62
62
 
63
+ At both connector and operation level, auth must be omitted or use `delegatedTokenExchange`. The compiler
64
+ validates the concrete connector definition emitted from TypeScript, including connector defaults and
65
+ operation overrides, and reports the exact failing auth path and kind. Do not keep a bearer, API-key,
66
+ client-credentials, or managed-provider fallback for local mode; use operation fakes while leaving auth
67
+ declarative.
68
+
63
69
  ## Map the endpoint from verified OIDC
64
70
 
65
71
  The IdP claim contains the complete base URL, including an optional base path. Routing is separate from the
@@ -302,6 +308,23 @@ Complete sign-in in Devtools and load the tool list. That authenticated request
302
308
  PKCE, token issuance, issuer/signature verification, the stable audience, and exact-resource binding work
303
309
  together. Invoke a representative safe read when the configured customer API is available.
304
310
 
311
+ ### Test delegated exchange locally
312
+
313
+ Local customer OIDC sign-in and delegated-exchange assertion trust are two distinct boundaries. OIDC proves
314
+ the caller to the local MCP server; Devtools uses a separate local issuer only for the RFC 8693 assertion
315
+ sent to the downstream token endpoint. This is the canonical local path and requires no `server.ts` change,
316
+ flag, environment variable, or config surface.
317
+
318
+ 1. Configure the OIDC authorization server for the exact loopback callback and RFC 8707 resource. Do not add
319
+ the Devtools assertion key to OIDC issuer metadata or change its signing keys.
320
+ 2. Start Devtools, complete customer sign-in, and copy the displayed `{ issuer, jwks }` from **Local delegated exchange**.
321
+ 3. Pin both values only in the customer-owned development RFC 8693 token endpoint.
322
+ 4. Restrict that trust to development client credentials, audience, API, and data.
323
+ 5. Invoke the delegated `list_org_apps` tool until its binding reads **Exchange verified**.
324
+ 6. Use hosted preview or `noodle auth doctor --live` to prove the production platform issuer.
325
+
326
+ **Never trust the Devtools issuer in production: anyone holding the local private key could impersonate a customer.**
327
+
305
328
  ## Configuration
306
329
 
307
330
  The embedded assistant uses a customer-supplied OpenAI Chat Completions-compatible endpoint. Configure its
@@ -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.58.0 hash:6a9f132ddb79352e -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:efffbf82007f935d -->
6
+ <!-- noodle-skill version:0.58.2 hash:efffbf82007f935d -->
7
7
 
8
8
  # publishing-mcp-integrations
9
9
 
@@ -110,6 +110,8 @@ For `customerAuth.oidc(...)` and `.federatedOidc(...)`, the application develope
110
110
 
111
111
  That metadata must expose HTTPS `authorization_endpoint`, `token_endpoint`, `jwks_uri`, and RFC 7591 `registration_endpoint`; advertise authorization-code and refresh-token grants, Dynamic Client Registration, PKCE with `code_challenge_methods_supported: ["S256"]`, and public clients with `token_endpoint_auth_methods_supported: ["none"]`. Validate the exact RFC 8707 `resource` on authorize, code exchange, and refresh, then map approved versions of one app/environment to the stable audience configured in `customerAuth`; use distinct audiences across apps and environments. Publish only public signing keys in JWKS. Run `noodle auth doctor src/server.ts`; its issuer-readiness probes perform bounded read-only GET checks and never register a client. A successful `noodle deploy --access customers` reports the same readiness without turning a diagnostic failure into a failed deployment.
112
112
 
113
+ The MCP client, or Devtools during local testing, opens the configured `authorization_endpoint`; Noodle does not submit the login form or manage the authorization server's session or CSRF cookies. Keep the login and consent UI plus credential POST on the same origin as the authorization endpoint. If a separate-site UI is unavoidable, the authorization server must explicitly trust the UI origin, use exact credentialed CORS where browser JavaScript calls it, issue the session and CSRF cookies needed by cross-site POSTs as `SameSite=None; Secure`, and return a CSRF token that the UI submits with credentials. Cookies cannot be shared across unrelated registrable domains. Browser privacy controls may still block this cross-site flow, so a same-origin route or reverse proxy remains the reliable design.
114
+
113
115
  Verify customer OAuth in three explicit layers. First run `noodle auth doctor src/server.ts --json`; a pass proves metadata and JWKS readiness, but it does not prove that registration or token issuance succeeds. Next run `noodle test src/server.ts --json`; for a protected app it proves that anonymous MCP access fails closed with exact protected-resource metadata and returns `interactiveRequired: true`. Finally run `noodle devtools src/server.ts`, complete sign-in, and make one authenticated `tools/list` request or one representative safe read. Only that final layer proves issuer, signature, stable audience, and exact-resource binding together. Never report a passing doctor or anonymous boundary smoke as working end-to-end authentication.
114
116
 
115
117
  ## Auth-derived customer API endpoints
@@ -192,6 +194,8 @@ export default server(
192
194
 
193
195
  `customerEndpoint` accepts exactly one non-empty policy arm: exact HTTPS origins, or HTTPS hostname suffixes. Exact policies may authorize an explicit non-default port; suffix policies allow port 443 and match only the exact host or dot-boundary subdomains. Do not add connector `allowedOrigins` to a customer-routed connector. Its fixed credential/token endpoints are validated independently and cannot come from caller claims.
194
196
 
197
+ Customer-routed connector auth must be omitted or use `delegatedTokenExchange` at both connector and operation level. The compiler validates the concrete connector definition emitted from TypeScript, including connector defaults and operation overrides. Do not emit bearer, API-key, client-credentials, or managed-provider fallbacks for local mode; use operation fakes while leaving auth declarative. `customer_endpoint_unsupported_auth` reports the exact failing path and auth kind.
198
+
195
199
  On a bidirectional MCP transport whose client negotiated form elicitation, Noodle sends the standard confirmation form. The current stateless hosted MCP transport cannot initiate that exchange, so the example explicitly declares `server.interactions.confirmationFallback: 'host'`. That fallback trusts the MCP host to have collected native write approval before the tool call reaches Noodle; it is never inferred from client identity and does not replace authentication, authorization, policy, or accurate action/destructive annotations. Omit it when connected hosts are not trusted to provide that approval; confirmation then fails closed with `interaction_unavailable` when the standard exchange is unavailable.
196
200
 
197
201
  Every federated issuer must repeat every endpoint key used by the app, although each issuer may choose a different claim path. Endpoint names use lowercase letters, numbers, and underscores. Resolved claims must be exact absolute HTTPS URLs of at most 2,048 UTF-8 bytes with no userinfo, query, fragment, IP literal, special-use host, or unsafe whitespace/control characters. The runtime preserves a canonical optional base path.
@@ -258,7 +262,7 @@ scope=time_off (space-joined, when configured)
258
262
  audience=example-api (when configured)
259
263
  ```
260
264
 
261
- The `subject_token` claims: `iss` (platform issuer; JWKS at `{iss}/.well-known/jwks.json`), `sub` (verified user id), `aud` (your configured audience or the tokenUrl), `email`, `name`, `claims` (declared session claims), `tenant` (`org/app/env`), `deployment`, `iat`, `exp` (about 120 s), `jti`. A routed exchange adds `route: { key, fingerprint }`, never the customer URL; credential cache and single-flight keys include that route binding. Respond with `{ "access_token": "...", "token_type": "Bearer", "expires_in": 900 }`; the broker caches per user + connector + scopes + route until `expires_in` minus 300 s and presents the token downstream as `Authorization: Bearer`.
265
+ The `subject_token` claims: `iss` (platform issuer; JWKS at `{iss}/.well-known/jwks.json`), `sub` (verified user id), `aud` (your configured audience or the tokenUrl), `email`, `name`, `claims` (declared session claims), `tenant` (`org/app/env`), `deployment`, `customer_identity: { version: 1, issuer }`, `iat`, `exp` (about 120 s), `jti`. Key downstream users by `(customer_identity.issuer, sub)`, never by `sub` alone. Firebase uses `https://securetoken.google.com/<project-id>`; Microsoft uses `https://login.microsoftonline.com/<tenant-id>/v2.0`. A routed exchange adds `route: { key, fingerprint }`, never the customer URL; credential cache and single-flight keys include that route binding. Respond with `{ "access_token": "...", "token_type": "Bearer", "expires_in": 900 }`; the broker caches per user + connector + scopes + route until `expires_in` minus 300 s and presents the token downstream as `Authorization: Bearer`.
262
266
 
263
267
  ### The downstream token endpoint (your backend)
264
268
 
@@ -289,7 +293,20 @@ export async function tokenEndpoint(req: Request): Promise<Response> {
289
293
  }
290
294
  ```
291
295
 
292
- Diagnose statically with `noodle auth doctor`; set a short-lived real customer token only in `NOODLE_CUSTOMER_TOKEN` and add `--live --org <org> --app <app> --env <env>` to perform one exchange per delegated binding without invoking a business tool. Add `--version <version>` to test that exact pinned MCP resource. Common failures include structured `credential_unavailable` reasons such as `caller_identity_not_customer`. Direct/federated OIDC verification assigns the customer identity at the trusted verifier boundary; never ask an IdP to mint a Noodle-specific classification claim.
296
+ ### Test delegated exchange locally
297
+
298
+ Local customer OIDC sign-in and delegated-exchange assertion trust are two distinct boundaries. OIDC proves the caller to the local MCP server; Devtools uses a separate local issuer only for the RFC 8693 assertion sent to your downstream token endpoint. This requires no `server.ts` change or additional flag, environment variable, or config surface.
299
+
300
+ 1. Configure the OIDC authorization server for the exact loopback callback and RFC 8707 resource. Do not add the Devtools assertion key to OIDC issuer metadata or change its signing keys.
301
+ 2. Start Devtools, complete customer sign-in, and copy the displayed `{ issuer, jwks }` from **Local delegated exchange**.
302
+ 3. Pin both values only in the customer-owned development RFC 8693 token endpoint.
303
+ 4. Restrict that trust to development client credentials, audience, API, and data.
304
+ 5. Run the delegated tool until its binding reads **Exchange verified**.
305
+ 6. Use hosted preview or `noodle auth doctor --live` to prove the production platform issuer.
306
+
307
+ **Never trust the Devtools issuer in production: anyone holding the local private key could impersonate a customer.**
308
+
309
+ Diagnose statically with `noodle auth doctor`; set a short-lived real customer token only in `NOODLE_CUSTOMER_TOKEN` and add `--live --org <org> --app <app> --env <env>` to perform one exchange per delegated binding without invoking a business tool. Add `--version <version>` to test that exact pinned MCP resource. Common failures include structured `credential_unavailable` reasons such as `caller_identity_not_customer`. For a Firebase/Microsoft bridge, `caller_issuer_missing` means the session predates issuer binding: reconnect once through customer authentication, then retry. No IdP custom claim or `server.ts` change is required. Direct/federated OIDC verification assigns the customer identity at the trusted verifier boundary; never ask an IdP to mint a Noodle-specific classification claim.
293
310
 
294
311
  ## Design tools for the model
295
312
 
@@ -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.58.0 hash:0f404109f4845683 -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:6ef6ef551e26b78e -->
6
+ <!-- noodle-skill version:0.58.2 hash:6ef6ef551e26b78e -->
7
7
 
8
8
  # verifying-mcp-delivery
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.58.0 hash:ec5bfcd0d8165205 -->
6
+ <!-- noodle-skill version:0.58.2 hash:ec5bfcd0d8165205 -->
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.58.0 hash:0b2fd8c7e43fc69f -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:f7fa54992c8d7692 -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:1e86b8704f407bd3 -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:aa715bae12041d7c -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:93e735b7ffb45df1 -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:76cce86729cffbee -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:cc54a67f21c0ecdb -->
6
+ <!-- noodle-skill version:0.58.2 hash:cc54a67f21c0ecdb -->
7
7
 
8
8
  # embedding-mcp-assistants
9
9
 
@@ -60,6 +60,12 @@ const api = connector('noodleseed_app_api')
60
60
  });
61
61
  ```
62
62
 
63
+ At both connector and operation level, auth must be omitted or use `delegatedTokenExchange`. The compiler
64
+ validates the concrete connector definition emitted from TypeScript, including connector defaults and
65
+ operation overrides, and reports the exact failing auth path and kind. Do not keep a bearer, API-key,
66
+ client-credentials, or managed-provider fallback for local mode; use operation fakes while leaving auth
67
+ declarative.
68
+
63
69
  ## Map the endpoint from verified OIDC
64
70
 
65
71
  The IdP claim contains the complete base URL, including an optional base path. Routing is separate from the
@@ -302,6 +308,23 @@ Complete sign-in in Devtools and load the tool list. That authenticated request
302
308
  PKCE, token issuance, issuer/signature verification, the stable audience, and exact-resource binding work
303
309
  together. Invoke a representative safe read when the configured customer API is available.
304
310
 
311
+ ### Test delegated exchange locally
312
+
313
+ Local customer OIDC sign-in and delegated-exchange assertion trust are two distinct boundaries. OIDC proves
314
+ the caller to the local MCP server; Devtools uses a separate local issuer only for the RFC 8693 assertion
315
+ sent to the downstream token endpoint. This is the canonical local path and requires no `server.ts` change,
316
+ flag, environment variable, or config surface.
317
+
318
+ 1. Configure the OIDC authorization server for the exact loopback callback and RFC 8707 resource. Do not add
319
+ the Devtools assertion key to OIDC issuer metadata or change its signing keys.
320
+ 2. Start Devtools, complete customer sign-in, and copy the displayed `{ issuer, jwks }` from **Local delegated exchange**.
321
+ 3. Pin both values only in the customer-owned development RFC 8693 token endpoint.
322
+ 4. Restrict that trust to development client credentials, audience, API, and data.
323
+ 5. Invoke the delegated `list_org_apps` tool until its binding reads **Exchange verified**.
324
+ 6. Use hosted preview or `noodle auth doctor --live` to prove the production platform issuer.
325
+
326
+ **Never trust the Devtools issuer in production: anyone holding the local private key could impersonate a customer.**
327
+
305
328
  ## Configuration
306
329
 
307
330
  The embedded assistant uses a customer-supplied OpenAI Chat Completions-compatible endpoint. Configure its
@@ -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.58.0 hash:6a9f132ddb79352e -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:efffbf82007f935d -->
6
+ <!-- noodle-skill version:0.58.2 hash:efffbf82007f935d -->
7
7
 
8
8
  # publishing-mcp-integrations
9
9
 
@@ -110,6 +110,8 @@ For `customerAuth.oidc(...)` and `.federatedOidc(...)`, the application develope
110
110
 
111
111
  That metadata must expose HTTPS `authorization_endpoint`, `token_endpoint`, `jwks_uri`, and RFC 7591 `registration_endpoint`; advertise authorization-code and refresh-token grants, Dynamic Client Registration, PKCE with `code_challenge_methods_supported: ["S256"]`, and public clients with `token_endpoint_auth_methods_supported: ["none"]`. Validate the exact RFC 8707 `resource` on authorize, code exchange, and refresh, then map approved versions of one app/environment to the stable audience configured in `customerAuth`; use distinct audiences across apps and environments. Publish only public signing keys in JWKS. Run `noodle auth doctor src/server.ts`; its issuer-readiness probes perform bounded read-only GET checks and never register a client. A successful `noodle deploy --access customers` reports the same readiness without turning a diagnostic failure into a failed deployment.
112
112
 
113
+ The MCP client, or Devtools during local testing, opens the configured `authorization_endpoint`; Noodle does not submit the login form or manage the authorization server's session or CSRF cookies. Keep the login and consent UI plus credential POST on the same origin as the authorization endpoint. If a separate-site UI is unavoidable, the authorization server must explicitly trust the UI origin, use exact credentialed CORS where browser JavaScript calls it, issue the session and CSRF cookies needed by cross-site POSTs as `SameSite=None; Secure`, and return a CSRF token that the UI submits with credentials. Cookies cannot be shared across unrelated registrable domains. Browser privacy controls may still block this cross-site flow, so a same-origin route or reverse proxy remains the reliable design.
114
+
113
115
  Verify customer OAuth in three explicit layers. First run `noodle auth doctor src/server.ts --json`; a pass proves metadata and JWKS readiness, but it does not prove that registration or token issuance succeeds. Next run `noodle test src/server.ts --json`; for a protected app it proves that anonymous MCP access fails closed with exact protected-resource metadata and returns `interactiveRequired: true`. Finally run `noodle devtools src/server.ts`, complete sign-in, and make one authenticated `tools/list` request or one representative safe read. Only that final layer proves issuer, signature, stable audience, and exact-resource binding together. Never report a passing doctor or anonymous boundary smoke as working end-to-end authentication.
114
116
 
115
117
  ## Auth-derived customer API endpoints
@@ -192,6 +194,8 @@ export default server(
192
194
 
193
195
  `customerEndpoint` accepts exactly one non-empty policy arm: exact HTTPS origins, or HTTPS hostname suffixes. Exact policies may authorize an explicit non-default port; suffix policies allow port 443 and match only the exact host or dot-boundary subdomains. Do not add connector `allowedOrigins` to a customer-routed connector. Its fixed credential/token endpoints are validated independently and cannot come from caller claims.
194
196
 
197
+ Customer-routed connector auth must be omitted or use `delegatedTokenExchange` at both connector and operation level. The compiler validates the concrete connector definition emitted from TypeScript, including connector defaults and operation overrides. Do not emit bearer, API-key, client-credentials, or managed-provider fallbacks for local mode; use operation fakes while leaving auth declarative. `customer_endpoint_unsupported_auth` reports the exact failing path and auth kind.
198
+
195
199
  On a bidirectional MCP transport whose client negotiated form elicitation, Noodle sends the standard confirmation form. The current stateless hosted MCP transport cannot initiate that exchange, so the example explicitly declares `server.interactions.confirmationFallback: 'host'`. That fallback trusts the MCP host to have collected native write approval before the tool call reaches Noodle; it is never inferred from client identity and does not replace authentication, authorization, policy, or accurate action/destructive annotations. Omit it when connected hosts are not trusted to provide that approval; confirmation then fails closed with `interaction_unavailable` when the standard exchange is unavailable.
196
200
 
197
201
  Every federated issuer must repeat every endpoint key used by the app, although each issuer may choose a different claim path. Endpoint names use lowercase letters, numbers, and underscores. Resolved claims must be exact absolute HTTPS URLs of at most 2,048 UTF-8 bytes with no userinfo, query, fragment, IP literal, special-use host, or unsafe whitespace/control characters. The runtime preserves a canonical optional base path.
@@ -258,7 +262,7 @@ scope=time_off (space-joined, when configured)
258
262
  audience=example-api (when configured)
259
263
  ```
260
264
 
261
- The `subject_token` claims: `iss` (platform issuer; JWKS at `{iss}/.well-known/jwks.json`), `sub` (verified user id), `aud` (your configured audience or the tokenUrl), `email`, `name`, `claims` (declared session claims), `tenant` (`org/app/env`), `deployment`, `iat`, `exp` (about 120 s), `jti`. A routed exchange adds `route: { key, fingerprint }`, never the customer URL; credential cache and single-flight keys include that route binding. Respond with `{ "access_token": "...", "token_type": "Bearer", "expires_in": 900 }`; the broker caches per user + connector + scopes + route until `expires_in` minus 300 s and presents the token downstream as `Authorization: Bearer`.
265
+ The `subject_token` claims: `iss` (platform issuer; JWKS at `{iss}/.well-known/jwks.json`), `sub` (verified user id), `aud` (your configured audience or the tokenUrl), `email`, `name`, `claims` (declared session claims), `tenant` (`org/app/env`), `deployment`, `customer_identity: { version: 1, issuer }`, `iat`, `exp` (about 120 s), `jti`. Key downstream users by `(customer_identity.issuer, sub)`, never by `sub` alone. Firebase uses `https://securetoken.google.com/<project-id>`; Microsoft uses `https://login.microsoftonline.com/<tenant-id>/v2.0`. A routed exchange adds `route: { key, fingerprint }`, never the customer URL; credential cache and single-flight keys include that route binding. Respond with `{ "access_token": "...", "token_type": "Bearer", "expires_in": 900 }`; the broker caches per user + connector + scopes + route until `expires_in` minus 300 s and presents the token downstream as `Authorization: Bearer`.
262
266
 
263
267
  ### The downstream token endpoint (your backend)
264
268
 
@@ -289,7 +293,20 @@ export async function tokenEndpoint(req: Request): Promise<Response> {
289
293
  }
290
294
  ```
291
295
 
292
- Diagnose statically with `noodle auth doctor`; set a short-lived real customer token only in `NOODLE_CUSTOMER_TOKEN` and add `--live --org <org> --app <app> --env <env>` to perform one exchange per delegated binding without invoking a business tool. Add `--version <version>` to test that exact pinned MCP resource. Common failures include structured `credential_unavailable` reasons such as `caller_identity_not_customer`. Direct/federated OIDC verification assigns the customer identity at the trusted verifier boundary; never ask an IdP to mint a Noodle-specific classification claim.
296
+ ### Test delegated exchange locally
297
+
298
+ Local customer OIDC sign-in and delegated-exchange assertion trust are two distinct boundaries. OIDC proves the caller to the local MCP server; Devtools uses a separate local issuer only for the RFC 8693 assertion sent to your downstream token endpoint. This requires no `server.ts` change or additional flag, environment variable, or config surface.
299
+
300
+ 1. Configure the OIDC authorization server for the exact loopback callback and RFC 8707 resource. Do not add the Devtools assertion key to OIDC issuer metadata or change its signing keys.
301
+ 2. Start Devtools, complete customer sign-in, and copy the displayed `{ issuer, jwks }` from **Local delegated exchange**.
302
+ 3. Pin both values only in the customer-owned development RFC 8693 token endpoint.
303
+ 4. Restrict that trust to development client credentials, audience, API, and data.
304
+ 5. Run the delegated tool until its binding reads **Exchange verified**.
305
+ 6. Use hosted preview or `noodle auth doctor --live` to prove the production platform issuer.
306
+
307
+ **Never trust the Devtools issuer in production: anyone holding the local private key could impersonate a customer.**
308
+
309
+ Diagnose statically with `noodle auth doctor`; set a short-lived real customer token only in `NOODLE_CUSTOMER_TOKEN` and add `--live --org <org> --app <app> --env <env>` to perform one exchange per delegated binding without invoking a business tool. Add `--version <version>` to test that exact pinned MCP resource. Common failures include structured `credential_unavailable` reasons such as `caller_identity_not_customer`. For a Firebase/Microsoft bridge, `caller_issuer_missing` means the session predates issuer binding: reconnect once through customer authentication, then retry. No IdP custom claim or `server.ts` change is required. Direct/federated OIDC verification assigns the customer identity at the trusted verifier boundary; never ask an IdP to mint a Noodle-specific classification claim.
293
310
 
294
311
  ## Design tools for the model
295
312
 
@@ -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.58.0 hash:0f404109f4845683 -->
6
+ <!-- noodle-skill version:0.58.2 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.58.0 hash:6ef6ef551e26b78e -->
6
+ <!-- noodle-skill version:0.58.2 hash:6ef6ef551e26b78e -->
7
7
 
8
8
  # verifying-mcp-delivery
9
9