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

# mcps

> MCP server entries upserted into agent config files.

```yaml theme={"theme":"nord"}
mcps:
  - name: <string>
    agents: <[string] | ["*"]>
    global: <bool>           # optional, default false (set true for current agents)
    source: <url>            # mutually exclusive with inline
    inline:                  # mutually exclusive with source
      type: <stdio|http|sse> # optional
      command: <string>
      args: <[string]>
      env: <map[string,string]>
      url: <string>
      headers: <map>
    merge: <bool>            # optional, default true
    target: <path>           # deprecated — use agents instead
```

## Type

`array[McpEntry]`

## Required

No. Omit `mcps:` if you don't manage any.

## Entry fields

### `name`

| Field  | Type   | Required |
| ------ | ------ | -------- |
| `name` | string | yes      |

The identifier the entry is upserted under inside the target's `mcpServers` object.

### `agents`

| Field    | Type             | Required                       |
| -------- | ---------------- | ------------------------------ |
| `agents` | array of strings | yes (when `target` is not set) |

Either a list of registry names (`[claude-code, cursor, codex]`) or the wildcard `["*"]`.

`["*"]` resolves at sync time to every registered agent that has a non-empty MCP config for the requested scope. Agents whose registry entry has no MCP config for that scope are skipped silently.

The destination JSON file is then looked up in the [agent registry](/agents/overview) — `global_mcp_config_file` for `global: true`, `project_mcp_config_file` for `global: false`.

### `global`

| Field    | Type | Required | Default |
| -------- | ---- | -------- | ------- |
| `global` | bool | no       | `false` |

| Value   | Resolved path                                                                                            |
| ------- | -------------------------------------------------------------------------------------------------------- |
| `true`  | `global_mcp_config_file` from the registry — the agent's user-global MCP config (e.g. `~/.claude.json`). |
| `false` | `project_mcp_config_file` from the registry — the agent's workspace-scoped MCP config.                   |

In the current registry every built-in agent only ships a `global_mcp_config_file`. Set `global: true` on every entry until per-project MCP configs land. With `global: false` (the YAML default) gaal silently skips the entry for every agent that has no project-scoped MCP path.

### `source`

| Field    | Type | Required      |
| -------- | ---- | ------------- |
| `source` | URL  | conditionally |

A URL returning a JSON document with an `mcpServers` object. gaal downloads the file and merges the entry whose key matches `name` into each resolved target.

Mutually exclusive with `inline`.

### `inline`

| Field    | Type   | Required      |
| -------- | ------ | ------------- |
| `inline` | object | conditionally |

The MCP server spec, written directly in `gaal.yaml`. Inline entries can describe stdio servers or native HTTP/SSE endpoints, depending on what the target agent supports.

| Subfield  | Type                      | Required      |
| --------- | ------------------------- | ------------- |
| `type`    | string                    | no            |
| `command` | string                    | conditionally |
| `args`    | array of strings          | no            |
| `env`     | map\[string]string        | no            |
| `url`     | string                    | conditionally |
| `headers` | map\[string, HeaderValue] | no            |

Use `command` for stdio servers. Use `url` for HTTP or SSE servers. `type` defaults to stdio when `command` is set, and HTTP when `url` is set.

Header values may be plain scalars or objects:

```yaml theme={"theme":"nord"}
headers:
  X-Team: platform
  Authorization:
    env: LINEAR_API_KEY
```

Prefer `env:` for secrets. gaal writes the environment variable name into formats that support env-backed headers.

Mutually exclusive with `source`. Exactly one of `source` or `inline` must be set per entry.

### `merge`

| Field   | Type | Required | Default |
| ------- | ---- | -------- | ------- |
| `merge` | bool | no       | `true`  |

Whether to merge the entry into the existing `mcpServers` object (preserving siblings) or overwrite it. The default keeps every server gaal didn't author.

### `target` (deprecated)

| Field    | Type   | Required |
| -------- | ------ | -------- |
| `target` | string | no       |

Explicit path to the JSON file. Deprecated — set `agents:` and `global:` instead so the path comes from the registry. When both `target` and `agents` are set, `target` wins and gaal logs a deprecation warning.

## Example

```yaml theme={"theme":"nord"}
mcps:
  # Inline stdio server, fanned out to two agents.
  - name: filesystem
    agents: [claude-code, cursor]
    global: true
    inline:
      command: uvx
      args: [mcp-server-filesystem, ~/projects]

  # Native HTTP server with an env-backed header.
  - name: linear
    agents: [claude-code]
    global: true
    inline:
      type: http
      url: https://mcp.linear.app/mcp
      headers:
        Authorization:
          env: LINEAR_API_KEY

  # SSE server.
  - name: sentry
    agents: [claude-code]
    global: true
    inline:
      type: sse
      url: https://mcp.sentry.dev/sse

  # Remote source, every detected agent.
  - name: github
    source: https://raw.githubusercontent.com/github/mcp-servers/main/config.json
    agents: ["*"]
    global: true
```

## Behaviour

* gaal upserts under the `mcpServers` object of every resolved target file.
* Other top-level keys in the target are preserved.
* Other entries inside `mcpServers` that gaal didn't author are preserved.
* Removing an entry from `gaal.yaml` does **not** remove it from the target unless you pass `--prune`.
* gaal does **not** expand `${VAR}` references in `args:` or `env:`. The agent process resolves them when launching the server.
* Header `env:` values name environment variables; they do not contain the secret itself.
* When the resolved target's parent directory is missing, gaal silently skips the entry — it never creates an agent's config directory as a side effect.

## Related

<CardGroup cols={2}>
  <Card title="Concepts: MCP servers" icon="plug" href="/concepts/mcp-servers" />

  <Card title="Configure MCP servers" icon="gear" href="/configure/mcp-servers" />

  <Card title="Environment & secrets" icon="key" href="/configure/environment-and-secrets" />
</CardGroup>
