# How to connect two accounts of the same app to one agent (/blog/connect-two-accounts-of-the-same-app)

![Illustration: A small friendly robot with a round camera-eye head stands in front of two identical plain mailboxes side by side on one wooden post, one painted solid orange and one painted solid slate blue, their fronts completely blank with nothing written on them.](/blog/connect-two-accounts-of-the-same-app/hero.webp)

One CoreSpeed connector can hold several accounts: two Slack workspaces, or a personal and a company X handle. Each account gets an alias. Connector tools take an optional `account` argument that names the alias. When several accounts are in scope and you name none, the call answers `ambiguous_account` and lists the aliases to choose from.

**Two accounts, one connector**

1. **Connect the first account** (Dashboard, Connectors; private or shared)
2. **Connect the same connector again** (authorize the second account) — Visibility is chosen per account.
3. **Check the index** (cs connectors accounts list, or GET /connectors)
4. **Rename the aliases** (manage\_\_accounts\_rename, under a member session) — Short, lowercase, different early: acme and personal.
5. **Start a new session** (both accounts sit behind the connector's tools)
6. **Pass account on each call** (with several in scope, the argument is required) — Omitted: ambiguous\_account. Unknown alias: account\_not\_found.

Each account gets an alias; the alias is the whole address.

## How do you connect the second account? \[#how-do-you-connect-the-second-account]

1. Connect the first account in Dashboard → Connectors. Pick private or shared visibility as usual.
2. Click Connect on the same connector again and authorize the second account. Visibility is chosen per account, so one can be private and the other shared.
3. Check the index. `cs connectors accounts list` from the CLI, or the authenticated `GET /connectors` route, shows every account on the connector with its alias and its `can_remove` rule.
4. Rename the aliases so prompts can use them. `manage__accounts_rename` runs from a signed-in client under a member session. An API key gets `200` with `isError: true` and the code `jwt_session_required`, so do this from Claude Code, Codex, the dashboard or the CLI, and not from a headless job.
5. Start a new session in the client. `tools/list` is caller-specific, and a fresh session sees the connector's tools with both accounts behind them.

Pick aliases a model will type correctly: `acme` and `personal`, or `eu-workspace` and `us-workspace`. Short, lowercase, and different from each other in the first few characters.

## How do you route a call to the right account? \[#how-do-you-route-a-call-to-the-right-account]

Pass `account` with the alias. When only one account is in scope for the caller, leave it out and the call runs against that one. When several are in scope, the argument is required, and an omitted argument fails rather than guessing.

"In scope" depends on who is calling. A member, whether signed in through the browser or using an `sk-cs-` key, sees their private accounts plus the organization's shared ones. An agent key, `sk-csa-`, sees shared accounts only. So an agent key with one shared Slack account never needs the argument, while the member who also holds a private Slack account does. The [authentication page](/docs/authentication) explains the two principal kinds.

| Situation                                   | What the call returns                                                      | What to do                               |
| ------------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------------- |
| One account in scope, no `account` argument | the tool's result                                                          | nothing                                  |
| Several in scope, no `account` argument     | `ambiguous_account`, with the aliases in `structuredContent.error.aliases` | pass one of them                         |
| An alias that matches nothing               | `account_not_found`, with the `available` aliases                          | fix the spelling or pick a listed alias  |
| The named account is in `needs_reauth`      | the call fails, tools stay listed                                          | reauthorize it in Dashboard → Connectors |

Both error results arrive as HTTP `200` with `result.isError: true`. The code is in `structuredContent.error.code`. Treating the `200` as success is the most common integration bug on `/mcp`; branch on the code. The [errors page](/docs/errors) has the retry rules for every code, and neither of these clears on a plain retry.

```json
{
  "isError": true,
  "structuredContent": {
    "error": {
      "code": "ambiguous_account",
      "aliases": ["acme", "personal"]
    }
  }
}
```

## What should the agent do with ambiguous\_account? \[#what-should-the-agent-do-with-ambiguous\_account]

Read the aliases, pick the right one from the task, and send the call again with `account` set. Nothing ran the first time, so the second call is the first real attempt.

Better still, remove the ambiguity before it happens. Two ways work well.

* Write the routing rule in the project's instruction file: "Posts to the company Slack use `account: "acme"`. Never post to `personal` from this repo."
* Save it as memory with `memory__remember` and `scope: "shared"`, so every agent in the org recalls it at the start of a task: "The company Slack workspace is the alias `acme`; `personal` is a private test workspace."

Memory is context, not policy. A rule in memory tells the agent which alias to use; it does not stop a write to the wrong one. If posting to the wrong workspace matters, name it in your approval policy. Reads are never gated, and a write your policy asks about pauses for a person.

## Does the agent ever see provider ids or tokens? \[#does-the-agent-ever-see-provider-ids-or-tokens]

No. The alias is the whole address. No provider account id, workspace id or token needs to appear in a prompt, and none is returned to the agent. CoreSpeed stores each credential, refreshes it when the provider allows, and exposes the connector's operations as namespaced tools. The agent receives tools, never the token. The [connectors page](/docs/connectors) covers the three ways to connect and the private and shared rules.

## FAQ \[#faq]

**Can the two accounts have different visibility?** Yes. Each account carries its own private-or-shared setting. A common shape is a shared company workspace and a private personal one on the same connector.

**What happens if I disconnect one of them?** The other stays. Disconnecting removes CoreSpeed's stored grant for that account only. For a pasted API key, disconnect deletes CoreSpeed's copy and the key keeps working at the vendor until you revoke it there.

**Does renaming an alias break existing prompts?** It can. The alias is the name every `account` argument uses. After `manage__accounts_rename`, update the instruction file and the memory that mention the old alias.

**Can an agent key reach both accounts?** Only the shared ones. If both accounts are shared, the agent key must pass `account` on every call. If one is private, the agent key sees one account and needs no argument.