@noodleseed/agent-kit 0.57.1 → 0.58.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 (32) hide show
  1. package/manifest.json +243 -243
  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 +78 -3
  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 +2 -0
  15. package/skills/claude-code/references/verify-and-recover.md +8 -6
  16. package/skills/claude-code/reporting-noodle-feedback/SKILL.md +1 -1
  17. package/skills/claude-code/verifying-mcp-delivery/SKILL.md +1 -1
  18. package/skills/codex/SKILL.md +1 -1
  19. package/skills/codex/authoring-mcp-servers/SKILL.md +1 -1
  20. package/skills/codex/building-mcp-apps/SKILL.md +1 -1
  21. package/skills/codex/connecting-apis-to-mcp/SKILL.md +1 -1
  22. package/skills/codex/debugging-mcp-delivery/SKILL.md +1 -1
  23. package/skills/codex/deploying-mcp-services/SKILL.md +1 -1
  24. package/skills/codex/designing-mcp-products/SKILL.md +1 -1
  25. package/skills/codex/embedding-mcp-assistants/SKILL.md +1 -1
  26. package/skills/codex/examples/customer-auth/README.md +78 -3
  27. package/skills/codex/executing-noodle-plans/SKILL.md +1 -1
  28. package/skills/codex/publishing-mcp-integrations/SKILL.md +1 -1
  29. package/skills/codex/references/authoring-workflow.md +2 -0
  30. package/skills/codex/references/verify-and-recover.md +8 -6
  31. package/skills/codex/reporting-noodle-feedback/SKILL.md +1 -1
  32. 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.57.1",
3
+ "version": "0.58.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.57.1 hash:ec5bfcd0d8165205 -->
6
+ <!-- noodle-skill version:0.58.0 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.57.1 hash:0b2fd8c7e43fc69f -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:f7fa54992c8d7692 -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:1e86b8704f407bd3 -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:aa715bae12041d7c -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:93e735b7ffb45df1 -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:76cce86729cffbee -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:cc54a67f21c0ecdb -->
6
+ <!-- noodle-skill version:0.58.0 hash:cc54a67f21c0ecdb -->
7
7
 
8
8
  # embedding-mcp-assistants
9
9
 
@@ -209,13 +209,84 @@ contract lives in [docs/spec/connectors.md](../../docs/spec/connectors.md).
209
209
  Firebase and Microsoft remain supported managed adapters; their provider-specific contracts and tests live
210
210
  in [docs/spec/auth-and-policy.md](../../docs/spec/auth-and-policy.md) and the SharePoint flagship.
211
211
 
212
+ ## Supabase direct-OIDC access-token hook
213
+
214
+ Dynamic Client Registration lets any OAuth client register, so the presence of `client_id` is not approval.
215
+ Keep an operator-controlled client-to-audience map and rewrite `aud` only for an exact mapped client. For a
216
+ dynamically registered client, review its generated client ID, name, and exact redirect URIs in the consent
217
+ flow before adding the mapping. Each new registration needs its own row; never approve by name or prefix.
218
+
219
+ Replace `<approved-oauth-client-id>` with the reviewed client ID and `<stable-mcp-audience>` with the exact
220
+ value configured in `customerAuth.oidc`:
221
+
222
+ ```sql
223
+ create table if not exists public.mcp_oauth_client_audiences (
224
+ client_id text primary key check (btrim(client_id) <> ''),
225
+ audience text not null check (btrim(audience) <> '')
226
+ );
227
+
228
+ revoke all on table public.mcp_oauth_client_audiences from authenticated, anon, public;
229
+ grant usage on schema public to supabase_auth_admin;
230
+ grant select on table public.mcp_oauth_client_audiences to supabase_auth_admin;
231
+
232
+ insert into public.mcp_oauth_client_audiences (client_id, audience)
233
+ values ('<approved-oauth-client-id>', '<stable-mcp-audience>')
234
+ on conflict (client_id) do update set audience = excluded.audience;
235
+
236
+ create or replace function public.mcp_access_token_hook(event jsonb)
237
+ returns jsonb
238
+ language plpgsql
239
+ stable
240
+ as $$
241
+ declare
242
+ claims jsonb := coalesce(event->'claims', '{}'::jsonb);
243
+ oauth_client_id text := nullif(btrim(claims->>'client_id'), '');
244
+ mapped_audience text;
245
+ begin
246
+ if oauth_client_id is not null then
247
+ select mapping.audience
248
+ into mapped_audience
249
+ from public.mcp_oauth_client_audiences as mapping
250
+ where mapping.client_id = oauth_client_id;
251
+ end if;
252
+
253
+ if mapped_audience is not null then
254
+ claims := jsonb_set(
255
+ claims,
256
+ '{aud}',
257
+ to_jsonb(mapped_audience),
258
+ true
259
+ );
260
+ end if;
261
+
262
+ return jsonb_build_object('claims', claims);
263
+ end;
264
+ $$;
265
+
266
+ grant execute on function public.mcp_access_token_hook(jsonb) to supabase_auth_admin;
267
+ revoke execute on function public.mcp_access_token_hook(jsonb) from authenticated, anon, public;
268
+ ```
269
+
270
+ | Token source | Mapping | Resulting `aud` |
271
+ | --- | --- | --- |
272
+ | Approved OAuth client | Exact client row | Mapped stable MCP audience |
273
+ | Unrelated or unknown OAuth client | No row | Original Supabase audience |
274
+ | Browser session | No `client_id` | Original Supabase audience |
275
+
276
+ Select this function under Supabase Auth Hooks before completing the interactive verification below.
277
+
212
278
  ## Validate
213
279
 
214
280
  ```bash
215
- noodle auth doctor examples/customer-auth/src/server.ts
216
- noodle validate examples/customer-auth/src/server.ts
281
+ noodle validate examples/customer-auth/src/server.ts --json
282
+ noodle auth doctor examples/customer-auth/src/server.ts --json
283
+ noodle test examples/customer-auth/src/server.ts --json
217
284
  ```
218
285
 
286
+ The doctor proves metadata and JWKS readiness without registering a client. For this protected app,
287
+ `noodle test` proves the anonymous 401 plus exact protected-resource metadata boundary and reports
288
+ `interactiveRequired: true`; neither command proves token issuance or audience verification.
289
+
219
290
  Against a deployed customer-protected environment, set a short-lived real customer token only in
220
291
  `NOODLE_CUSTOMER_TOKEN` and add `--live --org <org> --app <app> --env <env>`. The live doctor performs
221
292
  credential exchanges without invoking any business tool. Add `--version 1` when testing a pinned version;
@@ -224,9 +295,13 @@ the reported customer resource must match that versioned MCP endpoint.
224
295
  ## Run locally
225
296
 
226
297
  ```bash
227
- noodle dev examples/customer-auth/src/server.ts --app noodleseed-customer-auth
298
+ noodle devtools examples/customer-auth/src/server.ts
228
299
  ```
229
300
 
301
+ Complete sign-in in Devtools and load the tool list. That authenticated request is the local proof that DCR,
302
+ PKCE, token issuance, issuer/signature verification, the stable audience, and exact-resource binding work
303
+ together. Invoke a representative safe read when the configured customer API is available.
304
+
230
305
  ## Configuration
231
306
 
232
307
  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.57.1 hash:6a9f132ddb79352e -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:efffbf82007f935d -->
6
+ <!-- noodle-skill version:0.58.0 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
+ 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
+
113
115
  ## Auth-derived customer API endpoints
114
116
 
115
117
  Use a customer endpoint when the verified IdP selects a different API base URL for each SaaS customer. The claim contains the complete base URL; tool input and `${user}` do not select it. Declare one named policy, use that reference as the connector `baseUrl`, and map its claim path in direct OIDC or on every federated issuer:
@@ -22,12 +22,13 @@ Use this ordered evidence ladder. Start at the last known passing layer or the l
22
22
 
23
23
  1. **Compile** — the TypeScript build and authoring import surface are valid.
24
24
  2. **Validate** — `noodle validate --json` accepts the Noodle contract.
25
- 3. **Local smoke** — `noodle test --json` starts the local runtime and exercises registration.
26
- 4. **Real API** — a representative safe `noodle tools call` proves connector credentials, transport, observed mapping, and populated data.
27
- 5. **App compliance** — `noodle check --json` and local devtools prove the App contract and intended states.
28
- 6. **Host** — the requested host connects, invokes the expected capability, and renders useful fallback/UI behavior.
29
- 7. **Deploy** — the requested hosted revision and configuration exist and report healthy at the deployment layer.
30
- 8. **Production health** — the live production endpoint and requested user journey are observed on the intended revision.
25
+ 3. **Local smoke** — `noodle test --json` starts the local runtime. Open apps exercise MCP registration; customer-auth apps must instead pass the anonymous 401 plus exact protected-resource metadata boundary and report `interactiveRequired: true`.
26
+ 4. **Customer auth** — when customer auth is declared, run `noodle auth doctor src/server.ts --json` for metadata and JWKS readiness, then run `noodle devtools src/server.ts`, complete sign-in, and make one authenticated `tools/list` request or representative safe read. The doctor does not prove that registration or token issuance succeeds; the authenticated request proves issuer, signature, stable audience, and exact-resource binding together.
27
+ 5. **Real API** — a representative safe `noodle tools call` proves connector credentials, transport, observed mapping, and populated data.
28
+ 6. **App compliance** — `noodle check --json` and local devtools prove the App contract and intended states.
29
+ 7. **Host** — the requested host connects, invokes the expected capability, and renders useful fallback/UI behavior.
30
+ 8. **Deploy** — the requested hosted revision and configuration exist and report healthy at the deployment layer.
31
+ 9. **Production health** — the live production endpoint and requested user journey are observed on the intended revision.
31
32
 
32
33
  For the first failing layer:
33
34
 
@@ -44,6 +45,7 @@ Report a compact ledger for every exercised layer: command/action, target, resul
44
45
 
45
46
  - Compile success does not prove runtime behavior.
46
47
  - Validation and local smoke do not prove a real API mapping or credential path.
48
+ - A protected-boundary smoke or passing auth doctor does not prove DCR, token issuance, token audience, or authenticated MCP access.
47
49
  - Local evidence does not prove hosted or host behavior.
48
50
  - Deployment existence does not prove production health or a user journey.
49
51
  - Report every requested but unperformed or blocked higher layer as not run, with the reason.
@@ -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.57.1 hash:0f404109f4845683 -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:6ef6ef551e26b78e -->
6
+ <!-- noodle-skill version:0.58.0 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.57.1 hash:ec5bfcd0d8165205 -->
6
+ <!-- noodle-skill version:0.58.0 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.57.1 hash:0b2fd8c7e43fc69f -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:f7fa54992c8d7692 -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:1e86b8704f407bd3 -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:aa715bae12041d7c -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:93e735b7ffb45df1 -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:76cce86729cffbee -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:cc54a67f21c0ecdb -->
6
+ <!-- noodle-skill version:0.58.0 hash:cc54a67f21c0ecdb -->
7
7
 
8
8
  # embedding-mcp-assistants
9
9
 
@@ -209,13 +209,84 @@ contract lives in [docs/spec/connectors.md](../../docs/spec/connectors.md).
209
209
  Firebase and Microsoft remain supported managed adapters; their provider-specific contracts and tests live
210
210
  in [docs/spec/auth-and-policy.md](../../docs/spec/auth-and-policy.md) and the SharePoint flagship.
211
211
 
212
+ ## Supabase direct-OIDC access-token hook
213
+
214
+ Dynamic Client Registration lets any OAuth client register, so the presence of `client_id` is not approval.
215
+ Keep an operator-controlled client-to-audience map and rewrite `aud` only for an exact mapped client. For a
216
+ dynamically registered client, review its generated client ID, name, and exact redirect URIs in the consent
217
+ flow before adding the mapping. Each new registration needs its own row; never approve by name or prefix.
218
+
219
+ Replace `<approved-oauth-client-id>` with the reviewed client ID and `<stable-mcp-audience>` with the exact
220
+ value configured in `customerAuth.oidc`:
221
+
222
+ ```sql
223
+ create table if not exists public.mcp_oauth_client_audiences (
224
+ client_id text primary key check (btrim(client_id) <> ''),
225
+ audience text not null check (btrim(audience) <> '')
226
+ );
227
+
228
+ revoke all on table public.mcp_oauth_client_audiences from authenticated, anon, public;
229
+ grant usage on schema public to supabase_auth_admin;
230
+ grant select on table public.mcp_oauth_client_audiences to supabase_auth_admin;
231
+
232
+ insert into public.mcp_oauth_client_audiences (client_id, audience)
233
+ values ('<approved-oauth-client-id>', '<stable-mcp-audience>')
234
+ on conflict (client_id) do update set audience = excluded.audience;
235
+
236
+ create or replace function public.mcp_access_token_hook(event jsonb)
237
+ returns jsonb
238
+ language plpgsql
239
+ stable
240
+ as $$
241
+ declare
242
+ claims jsonb := coalesce(event->'claims', '{}'::jsonb);
243
+ oauth_client_id text := nullif(btrim(claims->>'client_id'), '');
244
+ mapped_audience text;
245
+ begin
246
+ if oauth_client_id is not null then
247
+ select mapping.audience
248
+ into mapped_audience
249
+ from public.mcp_oauth_client_audiences as mapping
250
+ where mapping.client_id = oauth_client_id;
251
+ end if;
252
+
253
+ if mapped_audience is not null then
254
+ claims := jsonb_set(
255
+ claims,
256
+ '{aud}',
257
+ to_jsonb(mapped_audience),
258
+ true
259
+ );
260
+ end if;
261
+
262
+ return jsonb_build_object('claims', claims);
263
+ end;
264
+ $$;
265
+
266
+ grant execute on function public.mcp_access_token_hook(jsonb) to supabase_auth_admin;
267
+ revoke execute on function public.mcp_access_token_hook(jsonb) from authenticated, anon, public;
268
+ ```
269
+
270
+ | Token source | Mapping | Resulting `aud` |
271
+ | --- | --- | --- |
272
+ | Approved OAuth client | Exact client row | Mapped stable MCP audience |
273
+ | Unrelated or unknown OAuth client | No row | Original Supabase audience |
274
+ | Browser session | No `client_id` | Original Supabase audience |
275
+
276
+ Select this function under Supabase Auth Hooks before completing the interactive verification below.
277
+
212
278
  ## Validate
213
279
 
214
280
  ```bash
215
- noodle auth doctor examples/customer-auth/src/server.ts
216
- noodle validate examples/customer-auth/src/server.ts
281
+ noodle validate examples/customer-auth/src/server.ts --json
282
+ noodle auth doctor examples/customer-auth/src/server.ts --json
283
+ noodle test examples/customer-auth/src/server.ts --json
217
284
  ```
218
285
 
286
+ The doctor proves metadata and JWKS readiness without registering a client. For this protected app,
287
+ `noodle test` proves the anonymous 401 plus exact protected-resource metadata boundary and reports
288
+ `interactiveRequired: true`; neither command proves token issuance or audience verification.
289
+
219
290
  Against a deployed customer-protected environment, set a short-lived real customer token only in
220
291
  `NOODLE_CUSTOMER_TOKEN` and add `--live --org <org> --app <app> --env <env>`. The live doctor performs
221
292
  credential exchanges without invoking any business tool. Add `--version 1` when testing a pinned version;
@@ -224,9 +295,13 @@ the reported customer resource must match that versioned MCP endpoint.
224
295
  ## Run locally
225
296
 
226
297
  ```bash
227
- noodle dev examples/customer-auth/src/server.ts --app noodleseed-customer-auth
298
+ noodle devtools examples/customer-auth/src/server.ts
228
299
  ```
229
300
 
301
+ Complete sign-in in Devtools and load the tool list. That authenticated request is the local proof that DCR,
302
+ PKCE, token issuance, issuer/signature verification, the stable audience, and exact-resource binding work
303
+ together. Invoke a representative safe read when the configured customer API is available.
304
+
230
305
  ## Configuration
231
306
 
232
307
  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.57.1 hash:6a9f132ddb79352e -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:efffbf82007f935d -->
6
+ <!-- noodle-skill version:0.58.0 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
+ 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
+
113
115
  ## Auth-derived customer API endpoints
114
116
 
115
117
  Use a customer endpoint when the verified IdP selects a different API base URL for each SaaS customer. The claim contains the complete base URL; tool input and `${user}` do not select it. Declare one named policy, use that reference as the connector `baseUrl`, and map its claim path in direct OIDC or on every federated issuer:
@@ -22,12 +22,13 @@ Use this ordered evidence ladder. Start at the last known passing layer or the l
22
22
 
23
23
  1. **Compile** — the TypeScript build and authoring import surface are valid.
24
24
  2. **Validate** — `noodle validate --json` accepts the Noodle contract.
25
- 3. **Local smoke** — `noodle test --json` starts the local runtime and exercises registration.
26
- 4. **Real API** — a representative safe `noodle tools call` proves connector credentials, transport, observed mapping, and populated data.
27
- 5. **App compliance** — `noodle check --json` and local devtools prove the App contract and intended states.
28
- 6. **Host** — the requested host connects, invokes the expected capability, and renders useful fallback/UI behavior.
29
- 7. **Deploy** — the requested hosted revision and configuration exist and report healthy at the deployment layer.
30
- 8. **Production health** — the live production endpoint and requested user journey are observed on the intended revision.
25
+ 3. **Local smoke** — `noodle test --json` starts the local runtime. Open apps exercise MCP registration; customer-auth apps must instead pass the anonymous 401 plus exact protected-resource metadata boundary and report `interactiveRequired: true`.
26
+ 4. **Customer auth** — when customer auth is declared, run `noodle auth doctor src/server.ts --json` for metadata and JWKS readiness, then run `noodle devtools src/server.ts`, complete sign-in, and make one authenticated `tools/list` request or representative safe read. The doctor does not prove that registration or token issuance succeeds; the authenticated request proves issuer, signature, stable audience, and exact-resource binding together.
27
+ 5. **Real API** — a representative safe `noodle tools call` proves connector credentials, transport, observed mapping, and populated data.
28
+ 6. **App compliance** — `noodle check --json` and local devtools prove the App contract and intended states.
29
+ 7. **Host** — the requested host connects, invokes the expected capability, and renders useful fallback/UI behavior.
30
+ 8. **Deploy** — the requested hosted revision and configuration exist and report healthy at the deployment layer.
31
+ 9. **Production health** — the live production endpoint and requested user journey are observed on the intended revision.
31
32
 
32
33
  For the first failing layer:
33
34
 
@@ -44,6 +45,7 @@ Report a compact ledger for every exercised layer: command/action, target, resul
44
45
 
45
46
  - Compile success does not prove runtime behavior.
46
47
  - Validation and local smoke do not prove a real API mapping or credential path.
48
+ - A protected-boundary smoke or passing auth doctor does not prove DCR, token issuance, token audience, or authenticated MCP access.
47
49
  - Local evidence does not prove hosted or host behavior.
48
50
  - Deployment existence does not prove production health or a user journey.
49
51
  - Report every requested but unperformed or blocked higher layer as not run, with the reason.
@@ -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.57.1 hash:0f404109f4845683 -->
6
+ <!-- noodle-skill version:0.58.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.57.1 hash:6ef6ef551e26b78e -->
6
+ <!-- noodle-skill version:0.58.0 hash:6ef6ef551e26b78e -->
7
7
 
8
8
  # verifying-mcp-delivery
9
9