> For the complete documentation index, see [llms.txt](https://docs.metacopier.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.metacopier.io/ai/ai/authentication.md).

# Authentication

The MCP server accepts two kinds of credential. They are equivalent in what they can reach, they differ in how the credential gets there and how the project is decided.

<table><thead><tr><th width="150">Mode</th><th width="200">Credential</th><th>Project</th></tr></thead><tbody><tr><td><strong>API key</strong></td><td>A MetaCopier API key you created yourself, sent as a header</td><td>The project the key belongs to</td></tr><tr><td><strong>OAuth</strong></td><td>Your MetaCopier login, exchanged automatically for a short lived credential</td><td>The project in the URL, or the oldest project you own</td></tr></tbody></table>

***

## Mode A: API key

### Creating the key

1. Open the MetaCopier web app.
2. Go to **Projects → API Keys**.
3. Create a key for the project you want the assistant to work on.
4. Copy the key. It is shown once.

{% hint style="info" %}
Give the AI its **own** key. Do not reuse a key that your EA, your website or a partner already uses. A separate key can be revoked without breaking anything else, and the audit log then shows exactly what the assistant did.
{% endhint %}

### Sending the key

Either header works:

```
X-API-KEY: YOUR_API_KEY
```

```
Authorization: Bearer YOUR_API_KEY
```

The second form exists because some MCP clients only offer a generic bearer token field. MetaCopier tells an API key and an OAuth token apart by their shape, so there is no ambiguity.

### What the key may do

Exactly what the key itself may do, no more. That is decided by two things:

* The key's **permission type**, `READ_ONLY` or `READ_WRITE`.
* The key's **access policy**, which can restrict endpoints, account fields, IP addresses and CORS origins.

{% content-ref url="/pages/4TcQLRM0kbdZBZLnhwDE" %}
[Access Policy](/rest-api/access-policy.md)
{% endcontent-ref %}

An access policy is optional, and it applies to both modes. On an OAuth connection it is the policy of the project's AI Apps key that counts.

If you want an assistant that can look but not touch, the cleanest way is a `READ_ONLY` key. A [read only endpoint](/ai/ai/endpoints.md#read-only-endpoints) is a second, independent layer you can add on top.

### When to use this mode

* Your client cannot do OAuth.
* You are building your own agent or automation.
* You want a credential that is not tied to a person and does not expire.
* You want the access policy to do the fine grained restriction for you.

***

## Mode B: OAuth

### How it works

You never handle a token. The flow is:

1. Your AI host asks MetaCopier's MCP server what it needs. The server answers with a standard discovery document ([RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728)) that names MetaCopier's identity provider.
2. The host sends you to the MetaCopier sign in page. You log in and approve the requested permissions.
3. The host receives an access token for the MCP server, and nothing else. That token is only valid for MetaCopier's MCP server, it cannot be replayed anywhere else.
4. On every request, the MCP server exchanges that token for a **short lived MetaCopier credential**, scoped to your project and narrowed to the permissions you approved. It lives for **60 minutes** and is minted fresh, so there is nothing for you to renew.

{% hint style="info" %}
The credential the MCP server uses internally is a child of a key called **AI Apps**, which MetaCopier creates in your project the first time an assistant connects. Revoking that key cuts off every AI connection to the project at once. See [security and limits](/ai/ai/security.md#revoking-access).
{% endhint %}

### Scopes: what the assistant is allowed to do

When you approve the connection, the host asks for one or more of these:

<table><thead><tr><th width="230">Scope</th><th>Grants</th></tr></thead><tbody><tr><td><code>mcp:read</code></td><td>Reading everything the underlying key may read: accounts, copiers, strategies, positions, history, reports, logs, news.</td></tr><tr><td><code>mcp:config.write</code></td><td>Changing configuration: creating and editing accounts, copiers, strategies, templates, dashboards, project features.</td></tr><tr><td><code>mcp:trading.write</code></td><td>Placing, modifying and closing trades. See <a href="/ai/ai/trading.md">trading with AI</a>.</td></tr></tbody></table>

The rules are strict and enforced on MetaCopier's side, not by the assistant:

* Without `mcp:config.write` **and** without `mcp:trading.write`, the credential is read only. Every write is refused.
* Without `mcp:trading.write`, every trading endpoint is refused even if configuration writes are allowed. A conversation about copier settings cannot turn into an order by accident.
* A scope can only ever **narrow** what the underlying key may do. If the project's AI key is read only, `mcp:trading.write` changes nothing.
* On a project with **more than 100 accounts**, both write scopes are dropped and the credential is read only. See [security and limits](/ai/ai/security.md#large-projects-are-read-only).

{% hint style="warning" %}
Grant `mcp:trading.write` only if you really want the assistant to trade. You can always reconnect later with more permissions.
{% endhint %}

### Which project does OAuth use?

**If the project is in the URL**, that project is used:

```
https://ai.metacopier.io/p/{projectId}/mcp
```

**If it is not**, for example because your client cannot store a long URL, MetaCopier resolves the project from your account:

1. Only projects you **own** count.
2. Deleted projects are skipped.
3. **White label projects are skipped**, because they belong to another brand.
4. Of what remains, the **oldest** one is chosen.
5. If nothing remains, the connection fails with `[PROJECT_NOT_FOUND]`.

{% hint style="danger" %}
With more than one project, always pin the project in the URL. The oldest project rule is a convenience for single project customers, not a selection you should rely on.
{% endhint %}

### When to use this mode

* You are a person using ChatGPT, Claude or a similar assistant.
* You want the connection tied to your login, so it ends when your access ends.
* You want to approve permissions explicitly instead of managing key permissions yourself.
* You do not want a long lived secret sitting in a configuration file.

***

## Comparison

<table><thead><tr><th width="240">Property</th><th width="180">API key</th><th>OAuth</th></tr></thead><tbody><tr><td>Setup effort</td><td>Create key, paste it</td><td>Paste the URL, sign in</td></tr><tr><td>Lifetime</td><td>Until you revoke it</td><td>Until you sign out or <a href="/ai/ai/security.md#revoking-access">revoke access</a></td></tr><tr><td>Secret in a config file</td><td>Yes</td><td>No</td></tr><tr><td>Project selection</td><td>The key's project</td><td>URL, otherwise oldest owned project</td></tr><tr><td>Permission control</td><td>Key permission type plus access policy</td><td>Scopes, on top of the key permission and access policy</td></tr><tr><td>Works without a browser</td><td>Yes</td><td>No</td></tr><tr><td>Tied to a person</td><td>No</td><td>Yes</td></tr></tbody></table>
