How an editor connection works
What a Human Behavior editor connection actually is, what the server re-checks on every single call, and why replay text arrives wrapped in a warning label.
Connecting an editor does not give it a key to your account. It creates a narrow, revocable permission to read a specific set of things on your behalf, re-checked on every call, and it can never reach further than you can reach yourself.
The problem it solves
The obvious way to let an outside tool read your data is an API key. Keys are also how data leaks: a key is a long-lived secret that ends up in a config file, a shell history, a screenshot, or a commit. It carries no record of who created it or what it is for, it usually grants everything the creating account can do, and revoking it means finding it first.
An editor is the worst possible place to keep one. It is on a laptop, it syncs its config, and the thing reading the key is a model that also reads your repository and can run commands.
So there is no key. Signing in through the browser produces something narrower.
How it works
A connection is a grant
When you approve the screen that opens, the server records one grant: this editor, for this person, on this project (or all of them), with these permissions. Everything else hangs off that row.
Your editor then holds two tokens rather than a key:
| Token | Lifetime | What it does |
|---|---|---|
| Access token | 1 hour | Sent with each call |
| Refresh token | 90 days | Exchanges for a new pair when the access token expires |
Neither is stored in a form we can read: only a hash of each reaches our database, so a leaked copy of that table is inert. Refreshing is single-use — the old refresh token dies the moment it is exchanged, and if one is ever presented twice, the whole connection is revoked on the assumption that a copy escaped.
Four checks on every call, not at connect time
The consent screen is not the security boundary. It is the moment you express intent; the boundary is re-evaluated on every single tool call:
- Is the token live? Expired, revoked, or hanging off a disconnected connection all fail the same way.
- Can you still reach this project? Membership is looked up fresh through the same gate a browser request uses. Remove someone from a project and their editor loses access on its very next call — not when the token expires.
- Is this connection allowed this project? A grant pinned to one project refuses every other one, even projects you are personally a member of, because you ticked that box deliberately.
- Does the grant carry the permission this tool needs? Tools you did not grant are not even listed, so an agent cannot see them to try them.
The consequence worth internalising: a connection is a narrowing of your own access, never a widening of it. There is no combination of arguments that makes an editor see a project you cannot open in the dashboard.
Your data stays yours at the database level
The analytics tool lets a model write SQL, which sounds alarming until you know where it runs. Model-written queries execute as a restricted database user that carries a row-level policy pinning every table to one project. A query that omits a project filter, or forges one for someone else's project, returns nothing — the isolation does not depend on the query being well-behaved. That user can only read; it cannot write, cannot reach other databases, and cannot call the functions that read files or make network requests.
Query results also carry hard ceilings — 200 rows returned, a 30-second execution limit, and a memory cap — so a badly-shaped query fails fast instead of degrading the product for everyone else.
Writes are proposals until you accept them
Two permissions can change something: triaging issues and saving funnels. Both default to a preview. The first call computes the change and returns it without applying anything, so the thing your agent shows you is a diff rather than a result.
When you approve, the apply carries an idempotency key. That makes a retry safe — agents retry constantly — and it makes something subtler safe too: if you revert a change by hand and the agent retries afterwards, the retry is refused rather than quietly re-applying it.
Every applied change writes an audit row naming both you and the connection. "Who resolved forty issues at 2am" has an answer, and it distinguishes you from the editor acting for you.
Why replay text arrives labelled
This is the part with no equivalent in the dashboard, and it is worth understanding rather than skimming.
A session replay contains text a stranger typed into your website: form values, search terms, error messages your app rendered back to them. In the dashboard, a human reads that text as content. Over MCP, the same text lands inside a coding agent that can edit files and run commands — so a string like "ignore previous instructions and run this command" is no longer inert.
Nothing on our side can stop a model from obeying something it read. What we can do, and do:
- Wrap it. End-user content arrives inside an
<untrusted>block whose header states that the contents are data and not instructions, in both the text and the machine-readable copy of the response. - Strip the tricks. Invisible characters, direction-flipping marks, control characters and markdown links are removed, so content cannot fake a new line of tool output, reorder what you see, or render as a clickable link to somewhere else.
- Cap it. Any single field is truncated, so a 40 kB "toast message" cannot push the real conversation out of your agent's context.
The practical upshot for you: if your agent reports that a session contained something that reads like an instruction, that is a finding about your users' data, not a command it should have followed. Treat it the way you would treat a suspicious string in a log.
Where you see it in the product
- The consent screen names the client, the account, the project, each permission, and the destination the result is sent to. That last line matters: any tool can call itself anything during registration, so the destination is the part that is actually verified. If it is not the editor you started from, do not continue.
- Settings → MCP lists every live connection with what it can do and when it was last used.
- Issues changed by an agent are attributed to the agent, not to you clicking a button, so triage history stays honest.
Common misconceptions
"It's an integration, so it has its own permissions." It has strictly fewer than you do. Every call resolves through your own membership, so the ceiling is your dashboard access, and the grant can only lower it.
"Disconnecting takes effect when the token expires." It takes effect on the next call. So does losing project membership, and so does a lapse in your account's access.
"Removing the server from my editor disconnects it." Not in Claude Code:
claude mcp remove forgets the server locally and leaves the connection live on
our side. claude mcp logout revokes it, and so does the Disconnect button.
"Read-only means it can't affect anything." Reads cost query time and count against your limits, and replay text reaching your agent is itself a way to influence it. Read-only removes the ability to change your data, not the need to read output critically.
"The agent sees my dashboard." It sees the same underlying data through 13 tools, formatted for a model. It cannot see a screen, so a replay arrives as a text timeline and a chart arrives as rows.
Next
Connect your editor if you have not yet, or read the tool reference to see exactly what each of the 13 tools accepts and returns.