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

# MCP Server Overview

> The Vrin MCP server exposes the knowledge base to any MCP-compatible AI agent. Install, configure, and call the two tools.

The Vrin MCP server is a thin wrapper around the Vrin API that speaks [Model Context Protocol](https://modelcontextprotocol.io). Any MCP client — Claude Desktop, Claude Code, Cursor, Windsurf, ChatGPT Developer Mode, the OpenAI Agents SDK, custom clients — can drive Vrin through it.

<Note>
  If you're setting up Vrin for an AI coding agent, start at [Vrin for AI Agents](/agents) — it has the copy-paste prompt that orchestrates install + config + ingestion end-to-end.
</Note>

## What the server exposes

| Tool                                              | Purpose                                                                |
| ------------------------------------------------- | ---------------------------------------------------------------------- |
| [`vrin_query_async`](/mcp/tools#vrin_query_async) | Start a query. Returns a `job_id` immediately.                         |
| [`vrin_check_job`](/mcp/tools#vrin_check_job)     | Long-poll a running query. Returns `completed` / `working` / `failed`. |

| Resource        | Purpose                                                                   |
| --------------- | ------------------------------------------------------------------------- |
| `vrin://stats`  | Entity count, fact count, document count for the authenticated user.      |
| `vrin://config` | Server version, API key type (standard vs enterprise), connection status. |

### Why two tools for one query?

Vrin's deep reasoning takes 30–120 seconds. A synchronous tool would force the client to hold an open connection that long, which hits most MCP client timeouts. So Vrin splits the call:

1. `vrin_query_async(query=...)` → returns a `job_id` in milliseconds. The real work runs in a worker Lambda.
2. `vrin_check_job(job_id=...)` → long-polls for up to 55 seconds and returns either the final result, `working` (keep calling), or `failed`.

Most queries finish inside the first `vrin_check_job` call. Complex `research`-depth queries may need 2–3. **Do not stop calling `vrin_check_job` until you see `completed` or `failed`.** The `working` response is a signal to call again, not to give up.

***

## Install

```bash theme={null}
pip install vrin-mcp-server
```

Requires Python 3.9+. Installs two entry points:

* `vrin-mcp` — STDIO transport (for Claude Desktop, Claude Code, Cursor).
* `vrin-mcp-http` — HTTP transport (for remote deployment, Docker, ChatGPT Developer Mode).

### Set your API key

```bash theme={null}
export VRIN_API_KEY=vrin_live_your_api_key
```

Get one at [vrin.cloud](https://vrin.cloud) → Dashboard → API Keys, or sign up via the CLI:

```bash theme={null}
pip install vrin
vrin auth register you@example.com
vrin auth create-key --name "mcp-client"
```

***

## Configure your MCP client

<Tabs>
  <Tab title="Claude Desktop">
    File: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows).

    ```json theme={null}
    {
      "mcpServers": {
        "vrin": {
          "command": "python",
          "args": ["-m", "vrin_mcp.server"],
          "env": {
            "VRIN_API_KEY": "vrin_live_your_api_key"
          }
        }
      }
    }
    ```

    Restart Claude Desktop. Click the connectors icon — `vrin` should be listed as connected.

    Troubleshooting: if `vrin_mcp` isn't on `$PATH`, use the absolute Python path, e.g. `/opt/homebrew/bin/python3`.
  </Tab>

  <Tab title="Claude Code">
    From a project root:

    ```bash theme={null}
    claude mcp add vrin python -m vrin_mcp.server \
      --env VRIN_API_KEY=vrin_live_your_api_key
    ```

    Or edit `.mcp.json` directly (project-scoped) or `~/.claude/settings.json` (user-scoped):

    ```json theme={null}
    {
      "mcpServers": {
        "vrin": {
          "command": "python",
          "args": ["-m", "vrin_mcp.server"],
          "env": {"VRIN_API_KEY": "vrin_live_your_api_key"}
        }
      }
    }
    ```

    Reload the project or restart Claude Code. Run `/mcp` inside Claude Code to confirm `vrin` is connected.
  </Tab>

  <Tab title="Cursor">
    File: `~/.cursor/mcp.json`.

    ```json theme={null}
    {
      "mcpServers": {
        "vrin": {
          "command": "python",
          "args": ["-m", "vrin_mcp.server"],
          "env": {"VRIN_API_KEY": "vrin_live_your_api_key"}
        }
      }
    }
    ```

    Settings → Tools & MCP → reload. The `vrin` tools will appear in any Composer chat.
  </Tab>

  <Tab title="Windsurf / others">
    Any MCP client that supports STDIO child processes works the same way. The command is always `python -m vrin_mcp.server` with `VRIN_API_KEY` in the env.

    For clients that want an HTTP endpoint, run `vrin-mcp-http` locally (defaults to port 8000) and point the client at `http://localhost:8000/mcp`.
  </Tab>
</Tabs>

***

## Call the tools from code

If you want to drive the MCP server programmatically (for testing, for custom clients, or for CI), use any MCP client library. Here's a minimal example with the Python MCP SDK:

```python theme={null}
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def main():
    params = StdioServerParameters(
        command="python",
        args=["-m", "vrin_mcp.server"],
        env={"VRIN_API_KEY": "vrin_live_..."},
    )
    async with stdio_client(params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # Start a query
            start = await session.call_tool(
                "vrin_query_async",
                {"query": "What is ACME's Q4 revenue?", "mode": "context"},
            )
            job_id = start.content[0].text  # parse per your framing
            # In practice: parse the returned JSON, pull job_id

            # Poll until done
            while True:
                status = await session.call_tool("vrin_check_job", {"job_id": job_id})
                # parse status — if status=="completed" break; else continue

asyncio.run(main())
```

***

## Remote deployment

Run the HTTP server for cases where the MCP client isn't on the same machine:

<Tabs>
  <Tab title="Docker">
    ```bash theme={null}
    docker run -d \
      -p 8000:8000 \
      -e VRIN_API_KEY=vrin_live_... \
      --name vrin-mcp \
      ghcr.io/vrin-cloud/vrin-mcp-server:latest
    ```
  </Tab>

  <Tab title="Docker Compose">
    ```yaml theme={null}
    services:
      vrin-mcp:
        image: ghcr.io/vrin-cloud/vrin-mcp-server:latest
        ports: ["8000:8000"]
        environment:
          VRIN_API_KEY: ${VRIN_API_KEY}
        restart: unless-stopped
    ```
  </Tab>

  <Tab title="bare metal">
    ```bash theme={null}
    pip install "vrin-mcp-server[remote]"
    VRIN_API_KEY=vrin_live_... vrin-mcp-http
    ```

    The server listens on `0.0.0.0:8000` by default. Override with `VRIN_HTTP_HOST` / `VRIN_HTTP_PORT`.
  </Tab>
</Tabs>

Then point an MCP-over-HTTP client at it. For Claude Desktop:

```json theme={null}
{
  "mcpServers": {
    "vrin": {
      "url": "https://mcp.your-domain.com/mcp",
      "auth": {"type": "bearer", "token": "vrin_live_your_api_key"}
    }
  }
}
```

Put TLS and auth in front of the server. The HTTP server accepts either a `VRIN_API_KEY` env var baked into the container **or** a per-request `Authorization: Bearer vrin_...` header (header wins when both are present).

***

## Environment variables

| Variable             | Required                           | Default               | Description                                        |
| -------------------- | ---------------------------------- | --------------------- | -------------------------------------------------- |
| `VRIN_API_KEY`       | Yes, unless using per-request auth | —                     | API key starting with `vrin_live_` or `vrin_ent_`. |
| `VRIN_HTTP_HOST`     | No                                 | `0.0.0.0`             | HTTP server bind host.                             |
| `VRIN_HTTP_PORT`     | No                                 | `8000`                | HTTP server port.                                  |
| `VRIN_QUERY_TIMEOUT` | No                                 | `120`                 | Per-query timeout in seconds.                      |
| `VRIN_WORKER_LAMBDA` | No                                 | `vrin-mcp-job-worker` | Override the worker Lambda name (internal).        |

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="vrin does not appear in my MCP client">
    1. Confirm `python -m vrin_mcp.server` runs without errors in a terminal with `VRIN_API_KEY` set.
    2. Make sure the `command` in your config is an absolute path or on `$PATH` for the GUI client (Claude Desktop does not always inherit shell `$PATH` — use `/opt/homebrew/bin/python3` or similar).
    3. Restart the client fully (quit, not reload).
    4. Check the client's MCP logs. Claude Desktop: `~/Library/Logs/Claude/mcp*.log`.
  </Accordion>

  <Accordion title="vrin_check_job keeps returning status=working forever">
    Normal for complex `depth=research` queries. Keep calling. The server-side timeout is 120s per job — if the job still hasn't completed after that, `vrin_check_job` will return `failed` with an error message. If you see `working` for more than 3 consecutive calls (\~165s), something upstream is wedged: check [status.vrin.cloud](https://status.vrin.cloud).
  </Accordion>

  <Accordion title="Job not found / expired">
    Jobs expire after 1 hour. If you call `vrin_check_job` with a stale `job_id`, you'll get `status: "not_found"`. Start a new query with `vrin_query_async`.
  </Accordion>

  <Accordion title="Enterprise keys aren't routing correctly">
    `vrin_ent_*` keys require an `infrastructure_config` record to exist in the enterprise config table. If you get "enterprise configuration not found", contact [support@vrin.cloud](mailto:support@vrin.cloud) — the setup is one-time and usually done during onboarding.
  </Accordion>
</AccordionGroup>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Tool reference" icon="plug" href="/mcp/tools">
    Full input/output schemas for `vrin_query_async` and `vrin_check_job`.
  </Card>

  <Card title="Vrin for AI Agents" icon="robot" href="/agents">
    The agent-onboarding page. Start here if you're setting Vrin up via a coding agent.
  </Card>
</CardGroup>
