Repository navigation
Conversation
Introduce HeaderResolver type and extend NewTransport to accept a static-headers + lazy-auth-resolver pair. Each Transport struct gains staticHeaders, resolveAuth, authMu and cachedAuth fields plus effectiveHeaders/ensureAuth helpers. Header reads route through effectiveHeaders so a later commit can flip the auth-retry path on without touching the request-building code again. Behaviour is unchanged: all callers pass nil for resolveAuth so cachedAuth is never populated and effectiveHeaders returns staticHeaders only.
StreamableHTTP.Send now detects 401/403 responses and, if a HeaderResolver is configured and no auth has been resolved yet, invokes the resolver and retries the request once with the freshly cached auth headers. Subsequent requests reuse the cached headers (sticky authenticated state). 401/403 returned after auth is already present is propagated as a genuine failure. runGetStream silently closes on 401/403 (same as 404/405): the optional server-notifications GET never drives auth resolution; the next POST does.
SSETransport.Connect now retries the GET /sse handshake once with resolved auth headers if the unauthenticated GET returns 401/403. SSETransport.Send retries POST /messages the same way. When auth is resolved late (server allowed GET without auth, then demanded it on POST) the long-lived GET stream is NOT reopened with auth. Documented as a known limitation: servers that filter server-initiated notifications on auth should be configured with --transport http instead of --transport sse (or auto).
RunProxy now splits cfg.Headers into static (sent on every request from the start) and templated (resolved on demand from the vault). buildAuthResolver builds a HeaderResolver closure that the transport invokes the first time the remote MCP server returns 401/403. Servers that authorise the MCP initialize handshake without auth (a common pattern) no longer trigger a vault prompt at all until the AI client invokes a tool that requires authorization. Also tightens runLoop's shutdown so the server-message forwarder exits once stdin EOFs (or any send error fires), draining any buffered responses before closing the transport. Without this the new end-to-end proxy tests against a real httptest server would block indefinitely because real Transport implementations never close msgCh on their own.
Document that templated headers (those referencing the vault) are held back until the remote MCP server responds 401/403, and that servers needing auth on long-lived SSE GET streams should use --transport http to avoid the documented limitation.
Extend the MCP wrapper proxy-mode bullet with the auth state machine (static headers eager, templated headers resolved on 401/403, sticky authenticated state). Document the SSE GET reopen limitation and the --transport http workaround.
feat(mcp): lazy auth-header deferral in proxy mode
Add Implemented bool to DetectedVault to distinguish backends with a working plugin (keychain, gopass) from planned ones (1password, gnome-keyring). Auto-mode now requires both Detected and Implemented before adding a vault to SelectedVaults.
Partition vaults into implemented/planned in VaultSelection; only implemented backends appear as multi-select options. Planned backends are shown in the form description note. Add tests covering the new exclusion logic and the no-implemented-vaults error path.
fix(init): block planned vault backends (1password, gnome-keyring)
- CLAUDE.md: new Branching section forbidding direct commits to main outside hotfixes; trimmed redundant Changelog and Final Verification sections. - CONTRIBUTING.md: new Branching model with release/hotfix flows; release-signing inlined as a CI bootstrap; Plugin versioning and Changelog policy compressed (detailed rules now live in the changelog skill); release-prep is the entry point on develop. - new .claude/skills/release-prep: docs-aware release prep that verifies each ## Development bullet has matching docs updates since the last tag, then invokes version-bump. - .claude/skills/changelog: aggressive compression (BREAKING / Features / Fixes), drops internal noise, BREAKING rules embedded. - .claude/skills/version-bump: Step 7 rewritten to match the develop -> PR -> main -> tag flow.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Version v0.3.0 - 2026-05-15
Features
locksmith mcp run- the vault istouched on the first MCP request rather than at startup, in both
local (stdio-shim) and proxy (templated headers deferred until
401/403) modes; the daemon session is transparently refreshed if
it expires between startup and the first fetch (see
docs/architecture.mdanddocs/configuration.md)Fixes
locksmith initno longer offers1passwordorgnome-keyringas selectable vault backends - they appear as "Planned (not yet
supported)" and auto-mode skips them even when
op/secret-toolare in
$PATH