Every tool on both servers, what each argument means, and what each status is asking you to do.

View as Markdown

MCP reference

Two servers, one product. They are not interchangeable, and the difference is the whole reason the tool names are what they are.

Remote https://app.solospace.dev/mcpLocal stdio
AuthOAuth 2.1, no API keyed25519 agent key
Has a browserNoYes, its own Chromium
Can sign bytesYesYes, via the service
Can complete a sign-in aloneNo — you drive the pageYes, in one call

Remote tools

passkey_howto

The end-to-end procedure: the shim to inject, the object shape to hand back to the page, what every refusal means, and your connectors' operating notes. Optional domain focuses the connector section on one site.

Needs no scope — only a valid token. Gating the manual behind a scope produces exactly the failure it exists to prevent: an agent refused the instructions for the thing it was just granted permission to do.

passkey_listconnectors:read

The connector catalogue, already narrowed to what this grant covers. Per connector:

FieldMeaning
notesProse about that site's flow. Returned first, because it is the field that decides whether the sign-in works.
siteNotesWhat is generally true of this site, present when a human also wrote a connector note. Both are returned: a note saying where the button is does not retract one saying the browser gets blocked.
notesSourceconnector (a human wrote it for this credential — trust it), default (a general note for the site — verify it), none (nobody has written one).
rpIdThe relying party — the domain the passkey belongs to.
credentialIdbase64url. The value passkey_assert takes.
userNameWhich identity this passkey signs in as.
signinUrlWhere to start.
originsThe origins a human observed at enrolment. An assertion for any other origin is refused.
originAdviceWhether signinUrl starts on an enrolled origin, in words. The sign-in URL is where you start; the ceremony origin is wherever the site has navigated to when it asks for the passkey, and only the second one is checked.
modeapproval or silent.
lastUsedAtThe last signature the service allowed for this connector.

A site that is missing was not granted. No rephrasing produces it; the person changes it on their dashboard.

passkey_connector_statusconnectors:read

What the service has recorded about one connector: its mode, its notes, its last successful signature, and whether a signature is waiting on a human *right now*. Use it before raising a second approval.

It cannot tell you whether your browser has a live session. Nothing on the server can see your browser.

passkey_assertsignin

The product. Takes credentialId, clientDataJSON (base64url, byte-for-byte as the page produced it) and origin. Returns one of:

statusMeaningWhat to do
signedauthData, signature, userHandle are in the resultHand them to the page. Each assertion is good once.
waiting_for_approvalA human is being asked, on their phone, right nowSleep retryAfterMs, then call again with byte-identical arguments — at most once per interval — until signed, denied, or the approval expires (~90s).
deniedTerminal. The result carries a code: approval_denied, approval_timeout, policy_denied, origin_rejected, not_foundStop. Report it. Do not retry.

Pass `clientDataJSON` through untouched. The shim builds those bytes inside the page and the page keeps them to hand to the site; the agent's job is to move the base64url string, not to re-create it. Do not decode and re-encode it, reformat the JSON or reorder its keys. The service hashes what it is sent and the site hashes what the page holds; one differing byte produces a signature that verifies against nothing, after every other gate has passed.

The `origin` is the page's, not the connector's. A site may navigate to another host before it asks for a passkey — start at signinUrl, but send whatever origin the ceremony is actually running on. It must be one of the connector's enrolled origins, and originAdvice says whether those two agree. Scheme and host only: no path and no trailing slash, even though signinUrl usually has one.

The credentialId and domain parameters are enumerations built from your grant, per request. A credential you were not granted is not offered in the schema at all — and is refused by the server as "no such credential" if you send it anyway, indistinguishably from one that does not exist.

passkey_approvalsapprovals:read

The approvals this connection has raised that are still open, with the deadline on each. It approves nothing and hurries nobody.

Local tools

passkey_howto

The short local procedure — three calls, in order, and how to read each status.

passkey_list

The same catalogue, over the ed25519 agent key.

passkey_session_status(domain)

Does this agent browser already have a live session? Opens the sign-in URL and reports where it landed. The answer is *inferred*: landing away from a login page is good evidence of a session, not proof of one.

passkey_signin(domain)

The whole ceremony in one call. Statuses: already_signed_in, signed_in, waiting_for_approval, denied, no_assertion (the page never asked for a passkey — read the notes and click the right button first), failed.

About the name passkey_status

It no longer exists on either server. It used to exist on both, answering different questions: locally "is this browser signed in", remotely "what has the service recorded". An agent connected to both saw one name whose meaning depended on which registration won — wrong silently, never with an error. It is now passkey_session_status (local, a question about a browser) and passkey_connector_status (remote, a question about the service's records). No alias is kept: an alias would preserve the collision it exists to fix, and unknown tool is a loud failure a client corrects in one turn.