Skip to content
MCP Connectors Guide

One account per call, and the open source rule that picks it

A connector call runs as one account, and a documented rule picks it before the request leaves. That rule is what a team reviews, because a shared account turns every person's request into a single identity. Kortix is the open-source AI Operating System. Your agents, skills, company memory, and connectors live in one git repo you own.

Pick the account by name, then read what ran

The CLI takes a label, a connection id, me or project, and every result reports the identity behind the call.

CLI

terminal
kortix connectors accounts gmail
kortix connectors accounts gmail --default "Support inbox"
kortix connectors call gmail <action> '{}' --account "Support inbox"

Connectors reference

Redirect URI

OAuth app you register
https://api.kortix.com/v1/connectors/oauth2/callback
<KORTIX_URL>/v1/connectors/oauth2/callback

OAuth for MCP servers and direct APIs

Every connector call runs as one account

A call to an MCP server leaves with a single credential, and the server judges the request by whoever owns that credential. The person who typed the prompt can be somebody else entirely. Plenty of setups settle the question by accident, because the first person to press Add account creates the identity every later call inherits.

So the useful question about MCP connector authentication is narrower than whether the server supports OAuth. Which account does each call run as, who else can reach that account, and what does the system do when the answer is unclear? Those three answers decide what the provider sees when an agent acts.

Kortix treats the account as a named object with an owner type, and the rule that picks it is written down. The rule is one part of the open source layer around the call that a reviewer can read before an agent runs, next to the tool list and the agent's grant.

The protocol leaves authentication to the server

Two sentences from Merge's explanation of the specification mark the gap. "Authentication for MCP servers is implementation-specific, since MCP itself doesn't define a built-in authentication mechanism." And: "Tool access control is handled at the MCP server level, since MCP doesn't offer a built-in permissions system."

A server receives a token or a key and decides whether to accept it. It has no view of the person behind the request and no vocabulary for "Alice asked for this". Two clients presenting the same token look identical to it. The specification does put duties on both sides. Servers must validate inputs and implement access controls. Clients should confirm sensitive operations and log tool usage. Neither list names the identity a call carries, because the protocol has nowhere to put it.

That leaves the decision with whichever layer sits over the server: the client, the gateway, or the product that configured the connector. Finding that layer, and reading its rule, is the review worth doing.

Two account types, and the run with nobody present

A connector can hold several accounts at once: a team inbox, your own inbox, a service login. Each account carries an owner type, and the type decides who may run a call as it.

A shared account has owner_type: project. It reaches everyone in the project, and every agent whose connectors grant lists the connector, triggers included. You can narrow it to specific people, groups or agents. A person in the narrowed audience uses it only in a private session. An agent in that audience uses it in all its sessions, triggers included.

A private account has owner_type: member. Only its owner reaches it, and only in the owner's private sessions. One line then decides scheduled work: an unattended run, whether a trigger or code using a service account key (kortix_sa_…), never uses a private account.

Those two types explain most of the confusion in a team. A person who tests a connector with their own login has built something that stops working at the first scheduled job. What an agent can reach through that connector is the tool list, the grant and this account, and the account is the layer with a person's name on it.

How the account is chosen, and the refusal

When a call names no account, or names me or project, Kortix uses an account only when the choice is certain. Exactly one account is reachable, and the call uses it. Several are reachable and exactly one is pinned as the default, and the call uses the default.

Anything else is denied. The reason is account_required, the response lists available_accounts, and the status is 403. The docs state the condition plainly: "Several accounts are reachable, none is named, none is pinned." me limits the choice to your private accounts, and project limits it to shared accounts.

A named account that does not match is denied with connector_not_connected and the names you can use. Kortix never substitutes another account, so an ambiguous connector fails instead of running under a name nobody chose. That refusal is the property worth checking in any product that resolves identities on your behalf.

Every result carries account: { connection_id, label, owner_type }, which is how the transcript shows which identity ran the call.

Where the account comes from

Adding an MCP server from its URL starts a sign-in, and that sign-in creates the account and its audience together. Add account asks for a name and a choice of who can use it: Everyone in project creates a shared account, Only you creates a private one and is the default, and Specific people, groups, or agents creates a shared account for that audience only.

For a server with OAuth metadata, Kortix runs the standard sequence. It discovers the server's metadata (RFC 9728, RFC 8414), registers itself as a client when the server supports dynamic client registration (RFC 7591), and runs PKCE (S256) with a resource parameter (RFC 8707). With registration support, nobody creates an OAuth app.

When the server has no registration, the web app opens credential entry. It asks for the client ID and secret of an OAuth app you create with the provider, and that app needs this redirect URI registered on it: https://api.kortix.com/v1/connectors/oauth2/callback. On a self-hosted instance the URI is <KORTIX_URL>/v1/connectors/oauth2/callback, which is why the docs ask for a KORTIX_URL that never changes.

A server that answers 401 or 403 to a call opens Add account there. That path needs an auth scheme: one you pick under Auth, or one Auto-detect finds in the server's WWW-Authenticate challenge. Without one, the 401 or 403 is shown as the failure. A server that needs no sign-in, such as DeepWiki, is ready when the account exists. A provider: mcp connector is Kortix calling someone else's MCP server, so the identity belongs to Kortix's side of the call, which is a different thing from the server itself. Connector credentials are brokered server-side and never enter the machine.

What one approval covers

An approval covers one exact request: the same connector, action, arguments and account. Change an argument and the decision starts again. After an approval, the identical call runs once when it repeats within 15 minutes, and a held call expires in 24 hours or the project's approvals.ttl.

The account is part of that scope, and that part is easy to miss. On a shared account, the same call from a second person with the same arguments falls inside the same window, because none of the four parts differs. The approval decided a request, and the request named no person. Every action is recorded. Reading, exporting and streaming the audit log depend on the plan.

Approval holds the call; the agent's turn pauses and resumes. Approval gates you set. Off until you set them, since policy.default_mode falls back to allow_all. There is also no session-wide approval. An action that must run with nobody present needs an Allow rule, since an approval needs a person to answer it.

Three arrangements, and the work each one fits

Teams settle into one of three arrangements, and the choice turns on who the work belongs to.

  1. A personal grant per person. Everyone adds an account with Only you, and each call runs as that person. Approvals bind to their account, and a scheduled run cannot use it. This fits mail, calendars and documents, where the data belongs to one person and a wrong identity is a visible mistake.
  2. One shared account, narrowed to an audience. The account belongs to the project and is narrowed to a group, a set of people or a list of agents. People in the audience reach it in their own sessions, and agents in the audience reach it in every session, triggers included. This fits a support inbox or a shared drive, where the work product belongs to a team. Only a person changes the audience, and the change applies at Save.
  3. A service account for unattended code. Code holding a service account key (kortix_sa_…) acts as the service account. It reaches shared accounts nobody narrowed, and never a private or narrowed account. So this arrangement only reaches an account you have deliberately left open to the project. It fits a nightly sync or a backend job, and it is the wrong tool for anything that should run as a person.

Pick the narrowest of the three that the work needs. Start with a private account for each person, move a work product to a narrowed shared account when a team owns it, and add an unnarrowed shared account for the service account only when the job cannot run with a person present.

Kortix names all of it: the account type, the audience and the agent grant are objects on the connector, and the resolution rule is documented. A reviewer can see which arrangement a connector uses before a call runs, and the same three choices answer the next server on the list.

Questions a team asks about connector identity

The three account arrangements, what an approval covers, and what happens when no account matches.

Whose permissions does an MCP connector use?

The permissions of the account the connector authenticated, not those of the person who typed the prompt. The call leaves with that account's credential, so the provider applies that account's scopes and shares.

Does an MCP connector act as me?

Only when the call runs as an account you own and the connector reaches it in your session. On a shared account the call acts as the project's identity, and an unattended run never uses your private account.

Can two people share one connector account?

Yes. A shared account (owner_type: project) is open to the project, and you can narrow it to specific people, groups or agents. Each person then uses it in a private session, and an agent in the audience uses it in all its sessions.

What happens when no account matches?

The call is denied with account_required and the available_accounts it could have used, at HTTP 403. Kortix never substitutes another account, so an ambiguous connector fails instead of running under a name nobody chose.

Give each identity a name in a file you own.

Connectors, accounts, audiences and grants live in one repo.