# Authentication (/docs/authentication)



The server authenticates to Delta's API with an **API key + secret**. You
never paste credentials into the AI model. They are
supplied once at install time — through the bundle's form, your editor's masked
prompt, or your client's config file — and read into the server at startup.

From v0.6.0 there is a second place they can live: one file the server keeps for
every client on the machine. [Where the key goes](#where-the-key-goes) below
covers both, and which one wins when you use both.



## Which tools need what [#which-tools-need-what]

| Group        | Key required                               | Examples                                                                    |
| ------------ | ------------------------------------------ | --------------------------------------------------------------------------- |
| Setup        | No                                         | `setup_credentials`, `get_connection_status`                                |
| Market data  | No                                         | `get_ticker`, `get_orderbook`, `get_candles`, `get_options_chain`           |
| Account data | Yes                                        | `get_positions`, `get_wallet_balances`, `get_fills`, `bulk_fills_export`    |
| Trading      | Yes, and **Trading** permission to execute | `place_order`, `cancel_order`, `place_bracket_order`, `close_all_positions` |

If you only want market data, skip key creation entirely. For account reads, a
**Read Data** key is enough. Create a **Trading** key only if you want the
assistant placing orders.

A key registers the account and trading tools together, so the tool list your
client displays tells you whether credentials arrived, not what they may do:

| What you configured            | Tools registered                         |
| ------------------------------ | ---------------------------------------- |
| Nothing                        | Setup and market data                    |
| A valid key, either permission | Setup, market data, account, and trading |

The trading tools are listed with a Read Data key as well. Delta rejects what
they send with `Unauthorized`, and the server says the key lacks Trading
permission.

`DELTA_MCP_DEBUG` adds one more tool in either case,
`get_debug_status`, which reports where the
[debug log](/docs/troubleshooting#capture-a-debug-log) is being written.

## Create your API key [#create-your-api-key]

<Steps>
  <Step>
    ### Open API key management [#open-api-key-management]

    Go to **delta.exchange → Account → Manage API Keys**.
  </Step>

  <Step>
    ### Choose permissions for your use [#choose-permissions-for-your-use]

    For data only, enable **Read Data** and nothing else. That also limits the blast
    radius if the key ever leaks. To let the assistant place orders, enable
    **Trading**. Grant only what you need.
  </Step>

  <Step>
    ### Whitelist your IP [#whitelist-your-ip]

    Add an IP whitelist so the key only works from your machine. This is
    **required** for a Trading key to work. You can revoke the key anytime from the
    same page; revocation is immediate.
  </Step>

  <Step>
    ### Hand the key to the server [#hand-the-key-to-the-server]

    If you installed the Claude Desktop bundle, type the key and secret into its
    install form. In VS Code, paste them at the masked prompt. Everywhere else, set
    them as environment variables in your client's MCP config. All three routes are
    covered in the [Quickstart](/docs). Or put the key in the shared file below and
    leave your client's config without credentials at all.
  </Step>
</Steps>

## Where the key goes [#where-the-key-goes]

There are two places a key can live, and they are read in a fixed order.

**Your client's own config** is read first: the bundle's install form, VS Code's
masked prompt, or an `env` block in a config file. This is what the install
builder fills in when you type a key into it.

**The shared file** is read second:

```
~/.delta-exchange-mcp/config.env
```

Every MCP client on the machine reads it, so a key set there works in Claude
Desktop, Cursor, Claude Code and the rest at the same time. The server creates
the file the first time it runs, owner-only, with instructions inside it, and
prints the path in its startup line.

A value your client sets always wins. Leaving a field empty in your client means
"not answered" and falls through to the file. Getting this backwards is a real
failure mode with a confusing symptom, so it has [its own troubleshooting
entry](/docs/troubleshooting#the-form-saved-my-key-but-the-assistant-still-cannot-see-my-account).

### Three ways to fill the shared file [#three-ways-to-fill-the-shared-file]

All three write the same file. Pick one.

**In the conversation.** Ask your assistant to connect your account and a form
appears inline:

```text
Connect my Delta Exchange account
```

It asks which site the key came from, what the assistant may do with it, then the
key and the secret. What you type goes straight to the file. It is not part of
the conversation and the assistant cannot read it, because the form runs in its
own frame. This needs a client that renders in-chat forms: Claude Desktop and the
Codex desktop app do today. On any other client nothing appears and you get the
instructions instead. See [`setup_credentials`](/docs/tools/setup).

**At a terminal**, which works on every client:

```bash
uvx delta-exchange-mcp login
```

It prompts with the input hidden and checks the key against Delta before saving
anything.

**By hand.** Open the file and fill in the three lines already waiting in it:

```dotenv
DELTA_API_KEY=your-key-here
DELTA_API_SECRET=your-secret-here
DELTA_MCP_ENV=india_prod
```

<Callout type="warn" title="Never send the key as a chat message">
  The form exists so the key stays out of the conversation. A message is in the
  assistant's context and is stored in the conversation. If an assistant offers to
  take your key that way, decline.
</Callout>

The terminal and by-hand routes normally need your client restarted afterwards.
The in-chat form usually needs neither: a saved key registers the account and
trading tools in the running server and tells the client its tool list changed,
so first-time setup, environment changes and key rotation need no restart of the
server. Some clients, Claude Desktop among them, read the tool list only when they
start the server: if the account tools do not appear, restart the client. The
trading tools follow the key, so saving one that carries Trading permission arms
them too.

## Choosing the key permission [#choosing-the-key-permission]

The permission on the key decides whether the assistant can trade. No setting
here changes that, and
[Security](/docs/security#your-keys-permission-is-the-only-gate) explains why it
is the boundary that holds.

Grant **Read Data** and the assistant reads your account while Delta rejects
every order it sends. Grant **Trading** and it places real orders from the moment
the key is saved, with no rehearsal, no size cap and no confirmation step. Delta
requires an IP whitelist entry on a Trading key.

## Environment variables [#environment-variables]

| Variable               | Required                    | Description                                                                                                                                    |
| ---------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `DELTA_API_KEY`        | For account / trading tools | Your API key. Its own permission decides what the assistant may do.                                                                            |
| `DELTA_API_SECRET`     | For account / trading tools | The matching secret.                                                                                                                           |
| `DELTA_MCP_ENV`        | Yes                         | Target environment: `india_prod` (production) or `india_testnet` (testnet).                                                                    |
| `DELTA_MCP_DEBUG`      | No                          | Set `1` to trace every HTTP request and response to a file, for bug reports. See [Troubleshooting](/docs/troubleshooting#capture-a-debug-log). |
| `DELTA_MCP_DEBUG_FILE` | No                          | Override the debug log path (default `~/.delta-exchange-mcp/logs/`).                                                                           |

<Callout title="Match the key to the environment">
  A production key only works with `india_prod`; a testnet key only with
  `india_testnet`. Mixing them produces signature/auth errors. Test trading on
  testnet first: it is the only way to rehearse an order.
</Callout>

## Where your keys live [#where-your-keys-live]

Your credentials stay on your machine. Which file holds them depends on how you
installed the server:

| Install path                                  | Where the credentials are stored                                                                                                                         |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Claude Desktop bundle                         | Entered in the install form; Claude Desktop keeps them with the server's own settings, not in a file you edit.                                           |
| VS Code one-click                             | Entered at the masked prompt; VS Code stores them in its own secret storage and injects them via `${input:…}`, so they never land in `.vscode/mcp.json`. |
| Cursor one-click, or any hand-written config  | Plain text in your client's config file — `~/.cursor/mcp.json`, `~/.codex/config.toml`, `claude_desktop_config.json`, and so on.                         |
| The in-chat form, `login`, or editing by hand | Plain text in `~/.delta-exchange-mcp/config.env`, created owner-only. One file for every client on the machine, read after whatever your client sets.    |

Whichever path you used, the rest is the same:

* Read into the server subprocess as environment variables at launch.
* Used to sign requests sent **directly from your machine** to Delta's API,
  with HMAC-SHA256.
* **Never** sent to the AI model or any Delta server beyond the trading API.

More on the security model in [Security](/docs/security).

<Callout type="warn" title="Keep secrets out of shared files">
  Do not commit a config file containing real credentials to git. Treat the API
  secret like a password.
</Callout>
