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

# Connect to your AI agent

> Add the Visor MCP server to Claude, ChatGPT, Codex, or any AI agent. Most apps connect in under a minute.

Connect Visor to your AI app and it can pull live vehicle inventory, prices, and dealer data for you — just by asking. Most apps connect in under a minute, and you never copy or paste a key: you sign in to Visor and pick your account.

<Note>
  Your API account starts with one-time starter API Credit based on your Visor plan: Free \$1, Plus weekly \$1, Plus monthly \$10, Plus annual \$50, or Plus lifetime \$100. The first \$1 never expires; any unused amount above it expires 12 months after it's granted. Looking up what's available is free — you're only charged when the agent pulls actual data, and that costs a fraction of a cent per request.
</Note>

## Pick your app

<CardGroup cols={2}>
  <Card title="Claude" icon="https://mintcdn.com/visor/crfLIIhmOg8saucl/images/clients/claude.svg?fit=max&auto=format&n=crfLIIhmOg8saucl&q=85&s=90460cf8b7c626057f66ed6c1eab3d46" href="#claude-desktop-and-web" width="24" height="24" data-path="images/clients/claude.svg">
    Claude desktop app or claude.ai
  </Card>

  <Card title="ChatGPT" icon="https://mintcdn.com/visor/crfLIIhmOg8saucl/images/clients/openai.svg?fit=max&auto=format&n=crfLIIhmOg8saucl&q=85&s=e78aa822734444457629be44ecd861f4" href="#chatgpt" width="24" height="24" data-path="images/clients/openai.svg">
    ChatGPT with developer mode
  </Card>

  <Card title="Claude Code" icon="https://mintcdn.com/visor/crfLIIhmOg8saucl/images/clients/claudecode.svg?fit=max&auto=format&n=crfLIIhmOg8saucl&q=85&s=899ffbb3ead262156719693508af4f86" href="#claude-code" width="24" height="24" data-path="images/clients/claudecode.svg">
    Anthropic's coding agent
  </Card>

  <Card title="Codex" icon="https://mintcdn.com/visor/crfLIIhmOg8saucl/images/clients/codex.svg?fit=max&auto=format&n=crfLIIhmOg8saucl&q=85&s=397a61dcb1d7819c1570a9423ac0d4ae" href="#codex" width="24" height="24" data-path="images/clients/codex.svg">
    OpenAI's coding agent
  </Card>

  <Card title="OpenClaw" icon="https://mintcdn.com/visor/crfLIIhmOg8saucl/images/clients/openclaw.svg?fit=max&auto=format&n=crfLIIhmOg8saucl&q=85&s=9e88e46e07380def47522846508dfc8d" href="#openclaw" width="64" height="64" data-path="images/clients/openclaw.svg">
    OpenClaw AI agent
  </Card>

  <Card title="Hermes" icon="https://mintcdn.com/visor/crfLIIhmOg8saucl/images/clients/hermes.svg?fit=max&auto=format&n=crfLIIhmOg8saucl&q=85&s=8ce7a4e840be161b7f9cf53938be5bb5" href="#hermes" width="24" height="24" data-path="images/clients/hermes.svg">
    Nous Research's agent
  </Card>

  <Card title="Another MCP client" icon="https://mintcdn.com/visor/crfLIIhmOg8saucl/images/clients/mcp.svg?fit=max&auto=format&n=crfLIIhmOg8saucl&q=85&s=51ef41b9a1121ebaf9a70b75cf9ff21c" href="#other-mcp-clients" width="24" height="24" data-path="images/clients/mcp.svg">
    OpenCode and generic clients
  </Card>

  <Card title="Your own code" icon="https://mintcdn.com/visor/crfLIIhmOg8saucl/images/clients/code.svg?fit=max&auto=format&n=crfLIIhmOg8saucl&q=85&s=6efc9a5ef07da81c907e2eb20ca54fdc" href="#use-it-from-your-own-code" width="24" height="24" data-path="images/clients/code.svg">
    OpenAI and Claude APIs
  </Card>
</CardGroup>

Whatever app you use, it connects to one address:

```txt theme={null}
https://mcp.visor.vin/mcp
```

The server is **read-only** — your agent can read Visor data, but it can never change anything in your account.

## Chat apps

### Claude Desktop and web

<Steps>
  <Step title="Open Connectors">
    In Claude — the desktop app or [claude.ai](https://claude.ai) — open **Customize → Connectors**.
  </Step>

  <Step title="Add a custom connector">
    Click **+**, choose **Add custom connector**, and paste the Visor server URL: `https://mcp.visor.vin/mcp`. Click **Add**.
  </Step>

  <Step title="Sign in to Visor">
    Click **Connect**. Visor opens in your browser — sign in, choose your API account, and approve. That's it: no key to copy.
  </Step>
</Steps>

<Check>
  Ask Claude: *"Use the Visor tools to find the median price of a Toyota RAV4 in California."* If it comes back with numbers, you're connected.
</Check>

<Note>
  On Team or Enterprise, an owner adds the connector once under organization connector settings. Members then connect it from their own **Customize → Connectors** and complete the Visor sign-in.
</Note>

### ChatGPT

Custom connectors need **developer mode**, available on ChatGPT Plus, Pro, Team, Enterprise, and Edu plans.

<Steps>
  <Step title="Turn on developer mode">
    Open **Settings → Connectors → Advanced** and turn on **Developer mode**.
  </Step>

  <Step title="Create the connector">
    Go back to **Settings → Connectors** and click **Create**. Name it `Visor` and paste the server URL: `https://mcp.visor.vin/mcp`.
  </Step>

  <Step title="Sign in to Visor">
    Save, then complete the Visor sign-in when prompted. Toggle Visor on in the chat's tools menu to use it.
  </Step>
</Steps>

<Check>
  Ask ChatGPT: *"Use the Visor tools to find median Toyota RAV4 prices in California."*
</Check>

To call Visor from the OpenAI API instead of the ChatGPT app, see [Use it from your own code](#use-it-from-your-own-code).

## Coding agents

### Claude Code

The fastest path is sign-in (OAuth):

```bash theme={null}
claude mcp add --transport http visor https://mcp.visor.vin/mcp
```

Then run `/mcp` in Claude Code and complete the browser sign-in.

Prefer a token — for example, in a headless or CI environment?

```bash theme={null}
export VISOR_API_KEY="vis_live_..."
claude mcp add-json visor '{"type":"http","url":"https://mcp.visor.vin/mcp","headers":{"Authorization":"Bearer ${VISOR_API_KEY}"}}'
```

Verify either way:

```bash theme={null}
claude mcp list
```

### Codex

Sign-in (OAuth):

```bash theme={null}
codex mcp add visor --url https://mcp.visor.vin/mcp
codex mcp login visor
```

Token:

```bash theme={null}
export VISOR_API_KEY="vis_live_..."
codex mcp add visor --url https://mcp.visor.vin/mcp --bearer-token-env-var VISOR_API_KEY
```

Equivalent `~/.codex/config.toml`:

```toml theme={null}
[mcp_servers.visor]
url = "https://mcp.visor.vin/mcp"
bearer_token_env_var = "VISOR_API_KEY"
enabled = true
```

Verify:

```bash theme={null}
codex mcp list
```

### OpenClaw

Sign-in (OAuth) is the cleanest path — OpenClaw stores the credential for you:

```bash theme={null}
openclaw mcp add visor \
  --url https://mcp.visor.vin/mcp \
  --transport streamable-http \
  --auth oauth
openclaw mcp login visor
```

Prefer to edit `openclaw.json` directly? Add Visor under `mcp.servers`:

```json theme={null}
{
  "mcp": {
    "servers": {
      "visor": {
        "url": "https://mcp.visor.vin/mcp",
        "transport": "streamable-http",
        "auth": "oauth"
      }
    }
  }
}
```

For token auth instead, drop `auth` and add a header (keep this file private):

```json theme={null}
"headers": {
  "Authorization": "Bearer vis_live_..."
}
```

### Hermes

Add Visor under `mcp_servers` in `~/.hermes/config.yaml`. Hermes runs the full OAuth flow for you:

```yaml theme={null}
mcp_servers:
  visor:
    url: "https://mcp.visor.vin/mcp"
    auth: oauth
```

Prefer a token? Use `headers` instead of `auth` (keep this file private):

```yaml theme={null}
mcp_servers:
  visor:
    url: "https://mcp.visor.vin/mcp"
    headers:
      Authorization: "Bearer vis_live_..."
```

After editing the config, run `/reload-mcp` in Hermes to load the server.

### Other MCP clients

Most clients accept either an OAuth server URL or a JSON config with a bearer header.

**OpenCode** — add the remote server under `mcp` in your local config. Keep this in user-local config or another ignored file if you use a literal token.

```json theme={null}
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "visor": {
      "type": "remote",
      "url": "https://mcp.visor.vin/mcp",
      "enabled": true,
      "headers": {
        "Authorization": "Bearer vis_live_..."
      }
    }
  }
}
```

**Generic MCP JSON** — many clients accept a shape like this:

```json theme={null}
{
  "mcpServers": {
    "visor": {
      "type": "http",
      "url": "https://mcp.visor.vin/mcp",
      "headers": {
        "Authorization": "Bearer ${VISOR_API_KEY}"
      }
    }
  }
}
```

If your client supports OAuth, omit `headers` and let it discover auth from the server.

## Use it from your own code

These paths use a dashboard API token. See [Authentication and scopes](#authentication-and-scopes) to create one.

### OpenAI Responses API

Pass the token as the MCP tool authorization value:

```js theme={null}
import OpenAI from "openai";

const client = new OpenAI();

const response = await client.responses.create({
  model: "gpt-5",
  tools: [
    {
      type: "mcp",
      server_label: "visor",
      server_url: "https://mcp.visor.vin/mcp",
      authorization: process.env.VISOR_API_KEY,
      require_approval: "never"
    }
  ],
  input: "Find median Toyota RAV4 prices in California."
});

console.log(response.output_text);
```

### Claude Messages API

Pass the token as the MCP server authorization token:

```python theme={null}
import os
import anthropic

client = anthropic.Anthropic()

response = client.beta.messages.create(
    model="claude-opus-4-8",
    max_tokens=1000,
    betas=["mcp-client-2025-11-20"],
    messages=[{"role": "user", "content": "Find median Toyota RAV4 prices in California."}],
    mcp_servers=[
        {
            "type": "url",
            "url": "https://mcp.visor.vin/mcp",
            "name": "visor",
            "authorization_token": os.environ["VISOR_API_KEY"],
        }
    ],
    tools=[{"type": "mcp_toolset", "mcp_server_name": "visor"}],
)
```

## What your agent can do

You don't need to learn any commands. Once connected, just ask in plain language:

* *"What's the median price of a used Honda Civic near 98101?"*
* *"Show me the 10 newest Toyota RAV4 listings in California with prices and dealers."*
* *"Which Ford F-150 trims have the biggest discounts from MSRP right now?"*

The agent figures out the right Visor query, runs it, and answers.

### How the tools work (for developers)

The server exposes two tools that map to the public `/v1` API contract:

| Tool      | Use it for                                                                         |
| --------- | ---------------------------------------------------------------------------------- |
| `search`  | Find the right SDK method, endpoint, filters, and examples before calling the API. |
| `execute` | Run sandboxed JavaScript against the SDK-shaped `visor` interface.                 |

A good system prompt makes the agent search first, then execute:

```txt theme={null}
Use the Visor MCP server. First call search to find the right SDK method and filters. Then call execute with an async arrow function. Do not build raw HTTP URLs or include API keys in code.
```

Example `search` query:

```txt theme={null}
facet metrics for Toyota inventory in California
```

Example `execute` code:

```js theme={null}
async () => {
  const response = await visor.facets.count({
    facets: ["model"],
    make: ["Toyota"],
    state: ["CA"],
    metric: "price.median",
    sort: "-metric",
    facet_value_limit: 10
  });

  return response.data.facets.model;
}
```

Example listing workflow:

```js theme={null}
async () => {
  const listings = await visor.listings.search({
    make: ["Toyota"],
    model: ["RAV4"],
    state: ["CA"],
    fields: ["default", "price", "miles", "dealer_name", "vdp_url"],
    limit: 10
  });

  return listings.data.map((listing) => ({
    vin: listing.vin,
    price: listing.price,
    miles: listing.miles,
    dealer: listing.dealer_name,
    url: listing.vdp_url
  }));
}
```

Response shapes match the public `/v1` API. Listing and dealer collections return rows in `response.data` and totals in `response.pagination.total`. Facet totals are in `response.data.total`, categorical buckets are in `response.data.facets.<facet>`, numeric buckets are in `response.data.range_facets.<facet>`, and numeric stats are in `response.data.stats.<facet>`. Detail endpoints return one record at `response.data`.

## Authentication and scopes

There are two ways to authenticate, and most apps use the first.

* **Sign in (OAuth)** — the default for Claude, ChatGPT, and any client that supports remote MCP OAuth. Add the server URL, sign in to Visor, pick your API account, and approve. Visor creates a revocable credential for that client. Nothing to copy.
* **Bearer token** — for clients and agent harnesses where you set HTTP headers or a token environment variable.

To create a bearer token:

<Steps>
  <Step title="Open your API account credentials">
    In the Visor dashboard, go to the API account credentials area.
  </Step>

  <Step title="Create a token with the scopes you need">
    Use all three scopes for the full MCP surface.
  </Step>

  <Step title="Store and send it">
    Save it locally as `VISOR_API_KEY` and configure your client to send `Authorization: Bearer <VISOR_API_KEY>`.
  </Step>
</Steps>

Scopes map to what the agent can read:

| Scope            | Unlocks                                                  |
| ---------------- | -------------------------------------------------------- |
| `inventory.read` | Listing search, facets, and VIN lookup                   |
| `dealers.read`   | Dealer search and detail                                 |
| `usage.read`     | Your account's usage summary (`/v1/usage`, not billable) |

<Warning>
  Never put API keys in query strings, prompts, shared project config, or command-line arguments that can be logged. Query-string API keys are rejected.
</Warning>

<Accordion title="OAuth metadata endpoints (for client implementers)">
  The server supports remote MCP OAuth discovery, dynamic client registration, and revocation:

  ```txt theme={null}
  Protected resource metadata: https://mcp.visor.vin/.well-known/oauth-protected-resource/mcp
  Authorization server metadata: https://mcp.visor.vin/.well-known/oauth-authorization-server
  Dynamic client registration: https://mcp.visor.vin/register
  Authorization endpoint: https://mcp.visor.vin/authorize
  Token endpoint: https://mcp.visor.vin/token
  Revocation endpoint: https://mcp.visor.vin/revoke
  ```
</Accordion>

## Limits and billing

* One `execute` workflow can make up to 50 underlying public API requests.
* Underlying requests count against your account Usage Tier rate limits and normal metering, the same as the `/v1` endpoints they map to.
* The server serializes requests, paces them from observed rate-limit headers, and retries bounded `429` responses when `Retry-After` fits inside the execute budget. Concurrent `Promise.all` calls inside one `execute` workflow do not increase Public API throughput. If more waiting is required, `execute` returns structured pause guidance with `retry_after_seconds` instead of sleeping indefinitely.
* The sandbox cannot call arbitrary `fetch()`.
* Large responses and tool outputs are capped. Narrow the query, lower `limit`, or return fewer fields when output is truncated.
* Each billable request made through MCP is metered the same way as the underlying `/v1` endpoint. The `/v1/usage` operation is never billable and requires `usage.read`.

## Troubleshooting

Most connection problems come down to sign-in or scopes.

| Symptom                              | Fix                                                                                                               |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| The agent says it has no Visor tools | Refresh the MCP app or connector in the host, or remove and re-add the server.                                    |
| `mcp_oauth_required`                 | Use the client's sign-in flow, or configure an `Authorization: Bearer ...` header.                                |
| `missing_api_key`                    | The client connected without OAuth and without a bearer token. Add a dashboard token or run the OAuth login flow. |
| `invalid_mcp_oauth_token`            | Reconnect the client or run its MCP logout/login flow. The credential may be expired or revoked.                  |
| `missing_scope`                      | Create or approve a credential with the required scope: `inventory.read`, `dealers.read`, or `usage.read`.        |
| `insufficient_credits`               | Add prepaid API credits, or use an account in good standing.                                                      |
| `query_string_api_key_rejected`      | Remove `api_key`, `apiKey`, `key`, or `access_token` from tool code and use host auth configuration.              |
