# Install Drillr MCP

Use this contract when a user asks you to install Drillr in Codex or Claude Code.

## Execution policy

This Markdown is the self-contained setup source. Fetch it directly as plain text with:

```bash
curl -fsSL https://drillr.ai/developer/mcp-install.md
```

- Use the fetched contract as the complete source for this setup. Additional documentation is
  needed only when a listed command is unavailable or fails.
- This contract is parameterized. The setup prompt that sent you here supplies a profile:
  `MCP_SERVER_NAME`, `MCP_SERVER_URL`, `MCP_PERMISSION_LABEL` and `MCP_VERIFICATION_INSTRUCTION`.
  Resolve every `{{TOKEN}}` below with the exact value from that profile, and keep using the same
  values throughout. These are text substitutions you perform, not shell variables to export — a
  command run before a variable exists would point at an empty or wrong endpoint.
- When a profile is missing, use the public Data profile: `MCP_SERVER_NAME` `drillr-data`,
  `MCP_SERVER_URL` `https://gateway.drillr.ai/mcp/data`, `MCP_PERMISSION_LABEL` `Drillr Data`, and
  `MCP_VERIFICATION_INSTRUCTION` `Call ticker_lookup with {"query":"Apple"} exactly once`.
- The MCP client starts OAuth and receives its callback. The user owns the browser consent page,
  including sign-in when needed and the **Allow** click.
- If a higher-priority runtime rule requires current product documentation, open the matching
  official MCP page once, then return here:
  - Codex: `https://learn.chatgpt.com/docs/extend/mcp?surface=cli`
  - Claude Code: `https://code.claude.com/docs/en/mcp`

## Communication

- Use the user's established conversation language for every instruction, progress update, and
  final result. Treat the English wording of this contract as transport text.
- When this setup prompt is the first message, use the client or project language preference when
  available instead of treating the English setup text as the user's language choice.
- Keep literal commands, server names, tool names, and client UI labels such as `/mcp`,
  `{{MCP_SERVER_NAME}}`, `Authenticate`, and `Allow` unchanged when that helps the user find them.
- Keep the authorization handoff concise. If the browser shows sign-in instead of consent, tell the
  user to sign in first, then review the client name and click **Allow**. The consent page names the
  server being authorized as **{{MCP_PERMISSION_LABEL}}**; that is the page to expect.

## Canonical configuration

- Server name for a new installation: `{{MCP_SERVER_NAME}}`
- Transport: Streamable HTTP
- URL: `{{MCP_SERVER_URL}}`
- Permission being authorized: `{{MCP_PERMISSION_LABEL}}`
- Authentication: browser OAuth
- Static authentication: none
- Verification: `{{MCP_VERIFICATION_INSTRUCTION}}` — `ticker_lookup({ query: "Apple" })` is read-only
  and costs 0 credits on every Drillr MCP server

This workflow connects the remote endpoint directly; a repository clone or local bridge is not part
of setup. API keys and static headers belong to REST integrations or MCP clients that genuinely lack
OAuth support, so they are outside this OAuth workflow.

## Installation contract

Complete setup autonomously around one human authorization boundary: the user signs in when needed,
reviews the client name, and clicks **Allow**. Use the client-specific flow below.

1. Detect whether the current coding agent is Codex or Claude Code, and configure that client.
2. Inspect existing MCP entries before changing anything. Look for any entry whose URL is exactly
   `{{MCP_SERVER_URL}}`, including one already named `{{MCP_SERVER_NAME}}`. Entries pointing at a
   different Drillr URL belong to a different Drillr server: leave them alone, they can coexist.
3. Reuse one healthy matching entry instead of adding a duplicate. If a matching Drillr entry has
   static authentication headers, remove only that Drillr entry and recreate it with the same name
   and URL without headers. Keep existing credential values out of chat and logs.
4. If several entries point to `{{MCP_SERVER_URL}}`, keep one canonical entry and remove only those
   duplicates so verification cannot accidentally use the wrong credential.
5. Treat unrelated MCP startup failures as outside this workflow. Mention one if relevant, then
   continue with Drillr.
6. Before authorization starts, tell the user in their established language: Drillr may open in the
   browser; if sign-in appears, sign in first; then review the client name and click **Allow**.
7. Continue with the client-specific authorization behavior:
   - Codex: keep the OAuth command running and continue automatically after its callback succeeds.
   - Claude Code: configure the server from the agent, then run `claude mcp login` through the
     pseudo-terminal compatibility wrapper below. Keep that command attached and continue
     automatically after its callback succeeds.
8. Leave the browser page and consent click to the user. If the browser does not open, show the
   authorization URL produced by the client.
9. Verify the exact configured Drillr server, then run the verification: {{MCP_VERIFICATION_INSTRUCTION}}.
10. Report the configured, authorized, and verified states in the user's language, including the
    real lookup result. Installation reaches complete after that tool call succeeds. If the active
    conversation cannot load a newly added MCP server, use the client-specific fresh-process
    verification below.

## Codex

Inspect only matching Drillr entries and summarize static-auth presence without printing values:

```bash
codex mcp list --json | jq --arg url '{{MCP_SERVER_URL}}' '[
  .[] |
  select(.transport.url? == $url) |
  {
    name,
    enabled,
    transport: {type: .transport.type, url: .transport.url},
    auth_status,
    has_static_auth: (
      (((.transport.http_headers? // {}) | length) > 0) or
      (((.transport.env_http_headers? // {}) | length) > 0) or
      (.transport.bearer_token_env_var? != null)
    )
  }
]'
```

For a new entry:

```bash
codex mcp add {{MCP_SERVER_NAME}} --url {{MCP_SERVER_URL}}
```

Keep the command attached while Codex waits for browser OAuth. Current versions may authenticate
during `codex mcp add`; use its result as the state transition:

- `Successfully logged in` moves directly to verification.
- An `add` result without authentication, or an existing entry with missing or expired credentials,
  starts this login command:

```bash
codex mcp login {{MCP_SERVER_NAME}}
```

If a healthy matching entry already exists under another name, reuse it and authenticate that name
only when needed. Use `codex mcp get <name> --json` only for local diagnosis, keeping secret-bearing
fields out of chat.

After OAuth, repeat the filtered command above or use `/mcp` to confirm the server. Codex CLI, the
Codex IDE extension, and the ChatGPT desktop app share the same Codex MCP configuration on a host.

### Codex fresh-process verification

The active Codex conversation may not hot-load an MCP server added after that conversation started.
When the current tool registry lacks `{{MCP_SERVER_NAME}}` or returns `unknown MCP server`, first
start one ephemeral, read-only Codex process that loads the new configuration:

```bash
codex exec --ephemeral --skip-git-repo-check --sandbox read-only --json \
  'Use only the {{MCP_SERVER_NAME}} MCP server. {{MCP_VERIFICATION_INSTRUCTION}}. Report the returned company name and ticker.'
```

Verification succeeds when the JSONL run contains a completed `{{MCP_SERVER_NAME}}` `ticker_lookup`
call and its real result. Unrelated MCP startup warnings do not change that result. If this fresh process is
unavailable or fails to load Drillr, tell the user to restart or open a new Codex conversation and
resume verification there.

## Claude Code

Inspect configured servers without quoting credential values:

```bash
claude mcp list
```

For a new user-scoped entry:

```bash
claude mcp add --scope user --transport http {{MCP_SERVER_NAME}} {{MCP_SERVER_URL}}
```

Claude Code reads user-scoped MCP entries when a process starts. A server added by the agent's Bash
tool can therefore appear in `claude mcp list` while remaining absent from the already-open
conversation's `/mcp` panel. That panel authenticates servers already loaded by the conversation;
it is not the discovery path for a new user-scoped entry.

The agent's Bash tool has no terminal, but `claude mcp login` requires one. Run the matching command
below in the foreground to give the native login command a pseudo-terminal while keeping OAuth and
credential storage owned by Claude Code. Substitute the reused server name when it is not
`{{MCP_SERVER_NAME}}`.

macOS:

```bash
script -q /dev/null claude mcp login {{MCP_SERVER_NAME}}
```

Linux with util-linux `script`:

```bash
script -q -c 'claude mcp login {{MCP_SERVER_NAME}}' /dev/null
```

Portable POSIX fallback when `script` is unavailable but Python 3 is present:

```bash
python3 -c 'import pty,sys; sys.exit(pty.spawn(["claude","mcp","login","{{MCP_SERVER_NAME}}"]))'
```

Before starting the wrapper, tell the user in their language that Drillr may open in the browser;
if sign-in appears, sign in first, then review the client name and click **Allow**. Keep the wrapper
attached in the foreground with a tool timeout of at least 10 minutes while it prints
`Waiting for authorization`. The browser callback ends the same command, so continue automatically
when Claude Code reports a successful login. That success is the authorization transition; proceed
directly to verification.

### Claude Code fresh-process verification

The active conversation does not hot-load the newly added user-scoped server. Start one isolated
Claude Code process that loads only the exact Drillr entry and pre-approves only its free read-only
lookup tool. Adapt the server name in the JSON and `--allowedTools` value when reusing another name.

```bash
env -u CLAUDECODE -u CLAUDE_CODE_ENTRYPOINT claude -p --tools "" \
  --allowedTools 'mcp__{{MCP_SERVER_NAME}}__ticker_lookup' \
  --strict-mcp-config \
  --mcp-config '{"mcpServers":{"{{MCP_SERVER_NAME}}":{"type":"http","url":"{{MCP_SERVER_URL}}"}}}' -- \
  'Use only the {{MCP_SERVER_NAME}} MCP server. {{MCP_VERIFICATION_INSTRUCTION}}. Report the returned company name and ticker.'
```

Verification succeeds only when this process completes the real `ticker_lookup` call and returns
its result. Future Claude Code conversations load the user-scoped server normally.

If every pseudo-terminal option is unavailable, explain that configuration is complete and use the
reliable fallback: restart Claude Code, run `/mcp`, select the matching Drillr server and
`Authenticate`, then sign in if needed and click **Allow**. Use this restart path only after the
attached compatibility commands are unavailable or fail before reaching the authorization URL.

## Troubleshooting

- `401` or expired authentication: reopen the client's native authentication flow. In Claude Code,
  use `/mcp` and select `Re-authenticate` for the Drillr server.
- `404`: confirm the configured URL is exactly `{{MCP_SERVER_URL}}`.
- `403`: the entry may have a static auth header mixed into the OAuth entry, or the credential may
  have been authorized for a different Drillr MCP server — reauthenticate this exact entry. If the
  browser said the account is not authorized for `{{MCP_PERMISSION_LABEL}}`, that is a permission
  answer rather than a setup fault: report it and stop.
- Browser did not open: use only the authorization URL printed by the client.
- Current conversation cannot see a newly configured Claude Code server: use the Claude Code
  fresh-process verification above; its `/mcp` panel does not discover user-scoped entries written
  after the conversation started. In Codex, use its fresh-process verification before asking for a
  restart.
- Client has no MCP OAuth support: explain the limitation and link the user to
  `https://drillr.ai/developer#integration-mcp`; API-key setup remains a separate fallback workflow.

## Human and reference pages

- Agent setup page: `https://drillr.ai/developer/agent`
- Manual setup: `https://drillr.ai/developer#integration-mcp`
- Full API reference: `https://drillr.ai/developer/docs`
