Connect Claude & ChatGPT
Hosted agents that speak MCP — Claude, ChatGPT, and others — connect to TAP with one URL:
https://mcp.tap.human.tech/mcpAdd it as a custom connector (leave OAuth Client ID and Secret empty) and authorize in your browser with your normal TAP login. That’s the whole setup — no API key to paste, no per-service configuration.
What your agent gets
Two tools, and every credential in your dashboard is reachable through them:
tap_discover— lists the credentials this connection can use and how to call each.tap_call— calls any API by credential name. TAP injects the secret, enforces your policies, and pauses writes for your approval. The agent never sees the secret.
Reads and writes follow the same policies, approvals, and audit log as every other TAP agent. The connection holds an OAuth token — never an API key or a credential value — and you can revoke it from the dashboard anytime.
OAuth scopes
When you authorize a connection, the consent screen names what it is asking for. Two grants exist, and they are separate on purpose.
| Scope | What it lets the connection do |
|---|---|
tap:full | Act as you: call tap_call / /forward and /sign with your credentials, and manage your workspace’s people on the team routes below. Your policies, approvals and audit log all still apply. |
tap:approve | Approve or deny credential requests that are waiting for you, as you. It opens no credential of its own. |
A client may ask for both — an app that runs the agent and shows you the
approval in its own UI asks for tap:full tap:approve. They are then shown as
two rows on the consent screen, because they are two different things to agree
to. tap:identity (“Sign in with TAP”) is a third, identity-only grant.
What tap:approve does not do. It cannot use a credential: a token holding
only tap:approve is inert at /forward, /sign and every agent endpoint. And
it does not weaken a passkey policy — a credential you protect with a passkey
still requires your passkey, and the host is told to send you to the approval
page instead.
An agent cannot approve its own request. The endpoint this scope unlocks,
POST /agent/approvals/:txn_id/decide,
refuses an agent API key outright and refuses any token that was not granted
tap:approve — including the tap:full token the agent half of the same
connection uses. Approving stays a person’s act.
Revoke a connection any time from the dashboard; that ends both grants at once.
What tap:full may do on team routes
An app that signs you in with TAP holds your access token and no dashboard
session, so it could not previously read your workspace’s people at all. A
tap:full token now authenticates the same person on a named set of team
routes — the ones a Team panel needs and no others:
| Route | |
|---|---|
GET /team/members | members and pending invites |
POST /team/members/invite | invite someone |
POST /team/members/invite/{id}/resend | reissue an invite |
DELETE /team/members/invites/{id} | withdraw a pending invite |
GET /billing (and /billing/status) | plan, seat cap, seats used |
GET /team/credentials | credential names and descriptions — never a value |
GET/POST /team/members/{id}/credentials, PATCH/PUT/DELETE /team/members/{id}/credentials/{name} | which accounts a teammate holds |
Three things this does not change:
- Your role still decides. The token resolves to you, in the workspace it was minted for, and the membership is re-read on every request. A member-tier token cannot invite, exactly as a member-tier login cannot.
- Nothing else moved. Every other team route — policy changes, passkey resets, role changes, approvals, checkout — still requires a dashboard session and, where it already did, a passkey. A token is refused there.
tap:identityandtap:approveare still inert here. A token withouttap:fullis refused withtoken_scope_insufficient, and an expired or revoked token is refused like any other.
Writes made this way are audited, and the audit row names whether the caller authenticated with a dashboard session or a Sign-in-with-TAP token.
Signing in from an app that embeds TAP
An app that hides TAP entirely — a work box — can run the whole sign-in on its
own page and hand the result to /authorize. Both box-hosted ceremonies end the
same way, with a one-time tap_login_code:
- the box-hosted join, for someone accepting an invitation, and
- the returning sign-in, for someone who already has an account.
Attach the code to the normal authorization redirect:
GET {TAP_MCP_PUBLIC_URL}/authorize?response_type=code&client_id=…&redirect_uri=…
&code_challenge=…&code_challenge_method=S256&tap_login_code=<login_code>TAP redeems it internally and redirects straight back to the app’s
redirect_uri with an authorization code — no consent screen and no second
passkey prompt. Exchange that code at /token as usual. The code is single-use,
lives two minutes, is bound to the origin it was minted for, and carries exactly
the scopes that were consented to; any refusal falls through to the normal
consent screen rather than failing the login.
Which connection to use
| Your agent | Use |
|---|---|
| Claude, ChatGPT, other hosted MCP clients | This page — paste the URL, authorize in the browser |
Claude Code, Cursor, scripts, anything that can curl | Quickstart — an API key and /instructions |
Both use the same credentials, policies, approvals, and audit log.
Note — this isn’t a per-service toolbox. You don’t install a separate Gmail, Stripe, and GitHub MCP server, each holding its own copy of your keys. You connect TAP once and reach every API through those two tools. It’s the same idea as TAP’s Socratic API: the agent works from a couple of generic calls and learns the rest from what TAP tells it, instead of a hand-written catalog per service.