Skip to content

feat: URL-mode secret collection for create_edge_function_secret - #412

Draft
barryroodt wants to merge 1 commit into
mainfrom
feat/url-mode-secret-collection
Draft

feat: URL-mode secret collection for create_edge_function_secret#412
barryroodt wants to merge 1 commit into
mainfrom
feat/url-mode-secret-collection

Conversation

@barryroodt

Copy link
Copy Markdown
Contributor

Adds create_edge_function_secret({ project_id, name }) so an agent can trigger storing an Edge Function secret without seeing the value. There's no value parameter. Clients that support URL-mode elicitation (protocol 2026-07-28) get an elicitUrl to the dashboard, the user types the secret there, and it never enters the AI client or the model context. Follows the elicitation pattern from #391 and #394.

How it works

  • Tool + URL: the server returns elicitUrl at ${connectBaseUrl}?ref=<project>&name=<secret>. The elicitation message is three short lines with no URL in it. Clients without URL capability get an isError text pointing them to Edge Functions > Secrets in the dashboard.
  • Acceptance via updated_at: stateless v1. On accept, the server reads the named secret's updated_at through the new SecretOperations.getUpdatedAt(projectId, name) (timestamp only, never values). updated_at >= issued_at means stored.
  • Reissue + resume: if nothing was written, the same URL comes back with the original issued_at. A fresh call within 600 s of a write returns { name, stored: true, updated_seconds_ago }. Decline and cancel store nothing.
  • Wiring + gating: new secretCollection?: { connectBaseUrl } option. It requires costConfirmation (shared signed requestState) and throws at construction without it. The tool registers under the functions feature group only when platform.secrets exists. Hosted rollout is flag-gated on the platform side in a separate PR.

v1 limits

The URL carries the project ref and secret name, so it's forgeable; the dashboard session plus write permission is the mitigation. A collaborator writing the same name inside the window reads as stored. A server-side handoff record with an opaque handle is tracked in AI-1170. Studio page wiring on top of supabase/supabase#49954 is AI-1171.

Tests

isUrlCapable table plus 12 integration cases in server.test.ts: URL shape, unsupported clients, no value in schema, accept, reissue, second boundary, decline/cancel, resume-by-key, cross-tool state, config gates. Full suite 157/157, typecheck and biome clean.

@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 33808013145

Coverage decreased (-0.2%) to 96.283%

Details

  • Coverage decreased (-0.2%) from the base build.
  • Patch coverage: 15 uncovered changes across 1 file (236 of 251 lines covered, 94.02%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
packages/mcp-server-supabase/src/tools/secret-tools.ts 179 164 91.62%
Total (5 files) 251 236 94.02%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 3629
Covered Lines: 3512
Line Coverage: 96.78%
Relevant Branches: 514
Covered Branches: 477
Branch Coverage: 92.8%
Branches in Coverage %: Yes
Coverage Strength: 60.09 hits per line

💛 - Coveralls

@barryroodt barryroodt added the publish-preview Runs `publish-preview` workflow to publish preview packages via https://pkg.pr.new/ label Sep 4, 2026
@pkg-pr-new

pkg-pr-new Bot commented Sep 4, 2026

Copy link
Copy Markdown

Open in StackBlitz

pnpm add https://pkg.pr.new/@supabase/mcp-server-postgrest@f47990f
pnpm add https://pkg.pr.new/@supabase/mcp-server-supabase@f47990f
pnpm add https://pkg.pr.new/@supabase/mcp-utils@f47990f

commit: f47990f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

publish-preview Runs `publish-preview` workflow to publish preview packages via https://pkg.pr.new/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants