> ## Documentation Index
> Fetch the complete documentation index at: https://docs.get-exo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ChatGPT connector

> Connect ChatGPT to Exo as a custom connector over OAuth. Static keys do not work here, and each ChatGPT surface sees a different toolset.

ChatGPT reaches Exo at `https://api.get-exo.com/mcp/` as a custom connector, using the same OAuth 2.1 server the claude.ai connector uses. The OAuth exchange mints ChatGPT its own Exo API key automatically.

<Warning>
  **A static `exo_` key cannot be pasted into ChatGPT.** ChatGPT supports OAuth or no auth for connectors, and nothing in between. If you are looking for the paste-a-key path, that is [Claude Code](/integrations/claude-code) or [Codex](/integrations/codex).
</Warning>

## Before you start

* An Exo account allowlisted for the private preview.
* A paid ChatGPT plan: Plus, Pro, Business, Enterprise or Edu. Developer mode is not available on Free.
* Content already in your graph. `search` reads your knowledge graph, so an empty organization returns nothing. See [Import your ChatGPT history first](#import-your-chatgpt-history-first).

## Set it up

<Steps>
  <Step title="Turn on Developer mode">
    In ChatGPT, open **Settings**, then **Apps and Connectors**, then **Advanced settings**, and turn on **Developer mode** (beta).
  </Step>

  <Step title="Create the connector">
    Back in **Apps and Connectors**, click **Create** and fill in:

    | Field          | Value                          |
    | -------------- | ------------------------------ |
    | Name           | `Exo`                          |
    | MCP server URL | `https://api.get-exo.com/mcp/` |
    | Authentication | OAuth                          |

    <Warning>
      Keep the trailing slash on `/mcp/`. A bare `/mcp` redirects, and the `Authorization` header does not survive the redirect.
    </Warning>
  </Step>

  <Step title="Sign in and allow">
    ChatGPT discovers Exo's OAuth server and opens the Exo sign-in page at `/connect`. Sign in with your dashboard account and click **Allow**.
  </Step>

  <Step title="Enable it in a chat">
    Open the composer's tools menu and enable the Exo connector. The dashboard's ChatGPT card flips to **Connected** once Exo receives the first request from the connector's key, which appears in your key list labeled **ChatGPT connector**.
  </Step>
</Steps>

## What each surface can do

This is the part that surprises people. ChatGPT does not expose the same toolset everywhere.

| ChatGPT surface                               | Exo tools available                                            |
| --------------------------------------------- | -------------------------------------------------------------- |
| Developer-mode chat                           | The full toolset, plus `search` and `fetch`. Reads and writes. |
| Deep research                                 | `search` and `fetch` only. Read-only retrieval with citations. |
| Company knowledge (Business, Enterprise, Edu) | `search` and `fetch` only.                                     |

Deep research and Company knowledge follow OpenAI's Deep Research contract, which recognises exactly two tools. Exo exposes both, so those surfaces work without Developer mode, but they can only read. Citations link back to the node in your knowledge graph.

The write tools, the ones that let ChatGPT put things into your graph rather than take things out, need Developer mode.

## Import your ChatGPT history first

The connector is far more useful when Exo already knows you, and the obvious source is ChatGPT itself.

<Steps>
  <Step title="Export from ChatGPT">
    **Settings**, then **Data controls**, then **Export data**. OpenAI emails you a zip.
  </Step>

  <Step title="Upload it to Exo">
    Use the dropzone on [the Exo dashboard](https://get-exo.com)'s Import page, or send it to the API:

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
      curl -X POST https://api.get-exo.com/v1/import \
        -H "X-Exo-API-Key: $EXO_KEY" \
        -F "file=@chatgpt-export.zip"
      ```

      ```python Python theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
      import os, requests

      with open("chatgpt-export.zip", "rb") as fh:
          r = requests.post(
              "https://api.get-exo.com/v1/import",
              headers={"X-Exo-API-Key": os.environ["EXO_KEY"]},
              files={"file": fh},
          )
      print(r.json())  # {"jobId": "...", "status": "pending"}
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
      const form = new FormData();
      form.append("file", new Blob([await file.arrayBuffer()]), "chatgpt-export.zip");

      const res = await fetch("https://api.get-exo.com/v1/import", {
        method: "POST",
        headers: { "X-Exo-API-Key": process.env.EXO_KEY! },
        body: form,
      });
      const { jobId } = await res.json();
      ```
    </CodeGroup>
  </Step>

  <Step title="Wait for the job">
    Import is asynchronous. Poll `GET /v1/ingest/{jobId}/status` until `status` is neither `pending` nor `running`. This route reports the worker's own vocabulary, where success is `done`, so a loop that waits for `succeeded` never finishes. Full walkthrough in [File and transcript imports](/integrations/imports).
  </Step>
</Steps>

## When it goes wrong

| Symptom                                          | Cause                                                                                      | Fix                                                                                     |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
| Endless auth prompts, or a silent auth loop      | An auth-mode mismatch, almost always                                                       | Delete the connector and re-create it with **OAuth** selected, not no-auth.             |
| 401 after connecting successfully                | The connector's key was revoked in the dashboard                                           | Reconnect to mint a fresh key. Each connect mints a new one, so revoke old ones freely. |
| The connector is rejected outside Developer mode | Without Developer mode, ChatGPT only accepts servers exposing exactly `search` and `fetch` | Exo exposes both, so those surfaces work. The full toolset still needs Developer mode.  |
| `search` returns nothing                         | Nothing has been imported yet                                                              | [Import your ChatGPT history](#import-your-chatgpt-history-first).                      |

## Next

<Columns cols={2}>
  <Card title="File and transcript imports" icon="file-text" href="/integrations/imports">
    Formats, size behaviour, and how to poll a job to completion.
  </Card>

  <Card title="Retrieving context" icon="search" href="/guides/retrieving">
    What `search` and `fetch` are reading underneath, and the richer call behind them.
  </Card>
</Columns>
