# OpenCode
> Setting up, authenticating, and running MCP servers in OpenCode with Ivar.
Source: https://ivar.run/docs/guide/mcp/providers/opencode

import { Callout } from 'fumadocs-ui/components/callout';

OpenCode connects to MCP servers declared in `ivar.json` by consuming a generated `opencode.json` configuration file at the hall root. Authentication strategies differ between standard services (like Linear) and restricted services (like Figma).

## Configuration & naming

`ivar` transforms canonical server names from `ivar.json` (`figma`, `linear`) into hall-qualified identifiers (`<hall>-<server>`) in `opencode.json`.

- **Provider config path:** `opencode.json` (hall root)
- **Canonical vs. qualified names:** Declared as `figma` and `linear` in `ivar.json`; mapped to `acme-figma` and `acme-linear` in `opencode.json` (for a hall named `acme`).
- **Configuration schema:** Remote servers are written with `"type": "remote"`. When OAuth metadata is generated, client credentials and redirect URIs appear in the `oauth` block.

### Generated `opencode.json`

```json title="opencode.json"
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "acme-linear": {
      "type": "remote",
      "url": "https://mcp.linear.app/mcp"
    },
    "acme-figma": {
      "type": "remote",
      "url": "https://mcp.figma.com/mcp",
      "oauth": {
        "clientId": "<generated_client_id>",
        "clientSecret": "{env:IVAR_MCP_ACME_FIGMA_SECRET}",
        "redirectUri": "http://127.0.0.1:19876/callback"
      }
    }
  }
}
```

## Authentication

### Linear

Linear implements standard Dynamic Client Registration (DCR) for public clients. OpenCode manages the OAuth handshake natively:

```sh
# Via Ivar (canonical name)
ivar mcp auth linear --provider opencode

# Direct OpenCode command (hall-qualified name)
opencode mcp auth acme-linear
```

### Figma

Figma rejects OpenCode's native dynamic client registration because OpenCode's client identifier is not on Figma's allowlist. 

To bridge this, Ivar pre-registers an allowlisted client (`Codex`), stores the confidential client secret in `.ivar/secrets/mcp.env`, executes the PKCE OAuth exchange internally, and installs the resulting access and refresh tokens directly into OpenCode's credential store (`mcp-auth.json`).

Because OpenCode cannot authenticate with Figma natively, do not run direct `opencode mcp auth` for Figma; use `ivar mcp auth`:

```sh
# Via Ivar (canonical name)
ivar mcp auth figma --provider opencode
```

### Authenticate all providers

To authenticate all configured providers for a server at once:

```sh
ivar mcp auth figma --all-providers

### Status inspection

`ivar mcp status` reads OpenCode's stored tokens from `mcp-auth.json`. With `--live`, it validates connection state via `opencode mcp list`:

```bash
ivar mcp status figma --provider opencode --live
```

## OAuth ownership & credentials

| Aspect | Linear | Figma |
| --- | --- | --- |
| **OAuth ownership** | OpenCode (`opencode mcp auth`) | Ivar (internal OAuth PKCE engine) |
| **Preregistration by Ivar** | None (public client) | Yes (`client_name: "Codex"`) |
| **Credential storage** | OpenCode credential store (`mcp-auth.json`) | OpenCode credential store (`mcp-auth.json`) |
| **Secret location** | None | `.ivar/secrets/mcp.env` (`IVAR_MCP_ACME_FIGMA_SECRET`) |

## Related

- [Linear integration guide](/docs/guide/mcp/integrations/linear)
- [Figma integration guide](/docs/guide/mcp/integrations/figma)
- [MCP OAuth overview](/docs/guide/mcp/oauth)
- [MCP reference & schema](/docs/reference/mcp)
