Skip to content

Validate vault fill inputs and pass API errors through - #247

Merged
rgarcia merged 4 commits into
mainfrom
hypeship/mcp-vault-fill-validation
Oct 14, 2026
Merged

rgarcia merged 4 commits into
mainfrom
hypeship/mcp-vault-fill-validation

Conversation

@rgarcia

@rgarcia rgarcia commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Four changes to the vault and browser tools, all aimed at the same problem: misshaped input was either passed through to the API verbatim or silently dropped, and the tool then layered its own guidance on top of the API's answer.

1. Strict fill inputs (manage_vault_items)

inputs for operation: "fill" was spread into the request body unvalidated. It is now parsed against a strict zod schema mirroring the API's FillVaultItemOperationRequest before any request is sent:

{ browser_id, page_url?, fields: [{ field, selector, format? }], timeout_ms? }
  • browser_id non-empty; page_url an http(s) URL; fields 1–32 strict objects; format only MM/YY / MM/YYYY (the API's card-expiration option); timeout_ms 1–30000.
  • Unknown keys are rejected client-side and named, e.g. unknown key "bindings" in fill inputs. expected { browser_id, page_url?, fields: [{ field, selector, format? }], timeout_ms? }.
  • Only top-level keys are named in messages, consistent with the existing rule that vault validation errors never serialize values or nested keys.
  • The inputs description now states the fill shape literally.

2. API errors pass through unchanged (throwVaultError)

Every vault API error previously had a fixed sentence appended, including "fill may have written some fields … so it is safe to retry", which is wrong for a request the API rejected without doing anything. Status, code, and message now pass through exactly as returned. The only added text is for a request that got no response at all (connection error, timeout, abort): no response was received from the api[ after the operation was submitted]. No retry advice.

3. Strict manage_browsers arguments

The input schema was a plain z.object, so unknown keys were dropped silently; passing vault instead of vaults created a browser with no vault attached. The schema is now strict and names the key: unknown key "vault": did you mean "vaults" (array of { id } or { name })?. This applies to every action that shares the schema; all known keys are unchanged, so update, list, get, get_telemetry, and delete behave as before.

The schema also declares an optional context string. PostHog's MCP instrumentation adds a required context argument to every tool it wraps and rejects the call if the schema doesn't accept it. Declaring it here makes PostHog skip its injection for this tool. PostHog's own intent capture only reads context for tools whose context it owns, so intent for manage_browsers is recorded from the declared field through the intentFallback option in analytics.ts ($mcp_intent_source is inferred). The value is never sent to the API: the config builders pick named fields, so context is not forwarded.

Note: prettier reindents the schema block when the object gains a second argument. git diff -w shows the real change (a helper, the context declaration, and two lines).

4. manage_vaults description

The 1password sentence said to create a browser and then request access in it. Access requests need no browser. It now matches manage_vault_items: connect the account, create the credential, request access with 1pw_create_access_request, and create a browser with the vault attached only when ready for 1pw_fill.

Tests

  • bun test: 1013 pass, 0 fail (new tests for unknown fill keys, malformed fill inputs, the full fill request shape, and unknown manage_browsers keys including vault).
  • browser-vaults.test.ts: a call with context set parses and succeeds for create and update, and the API request body has no context property.
  • bun x tsc --noEmit: clean.
  • bun x prettier --check "src/**/*.ts": clean. bun run format:check fails only on AGENTS.md, which is pre-existing on main.
  • bun run lint fails on main already (next lint was removed in Next 16).

- Reject fill inputs that do not match the API request shape before any
  request is sent, naming unknown keys and the expected shape.
- Pass vault API errors through as returned; only a request with no
  response at all gets a note, with no retry advice.
- Reject unknown manage_browsers keys instead of silently dropping them,
  pointing "vault" at "vaults".
- Correct the 1password flow order in the manage_vaults description:
  access requests need no browser.
@vercel

vercel Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
mcp Ready Ready Preview Oct 13, 2026 9:50pm UTC

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread src/lib/mcp/tools/browsers.ts
@rgarcia
rgarcia requested a review from hiroTamada October 12, 2026 16:12

@hiroTamada hiroTamada left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed — no blocking issues found. full test suite passes (936 tests), and the TypeScript check passes.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9a0712d. Configure here.

Comment thread src/lib/mcp/tools/browsers.ts

@vercel vercel Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestion:

manage_browsers declares its own context field but is not listed in the intentFallback handler, so $mcp_intent/userIntent analytics are silently dropped for every manage_browsers call.

Fix on Vercel

@hiroTamada hiroTamada left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed — no blocking issues found. full test suite passes (941 tests), and the TypeScript check passes.

Resolve vault-responses.ts: keep the Kernel-provider error helpers from main,
and keep the pass-through throwVaultError. Update the preflight redaction test
so its fill call supplies valid inputs, since fill inputs are now validated
before any request.
@rgarcia
rgarcia merged commit 6529745 into main Oct 14, 2026
10 checks passed
@rgarcia
rgarcia deleted the hypeship/mcp-vault-fill-validation branch October 14, 2026 00:26

This branch was successfully deployed

1 active deployment
Preview — 7c26b982 Deployed Oct 13, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants