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

# Connect synthetic tools

> Route your agent's API and MCP calls to simulated services such as Gmail, Slack and Stripe during a drill.

During a drill, your agent calls simulated versions of the services it depends on. Each drill gets its own local address for each simulated service. Your agent never receives a Firedrill token. The address is the only thing it needs.

## How it fits together

1. **Descriptor:** declare each dependency with an alias, the service that calls it, `http` or `mcp`, and the operations it uses.
2. **World:** map the same alias to a synthetic tool version. See [Worlds](https://docs.firedrill.run/build/worlds.md).
3. **Local plan:** tell the CLI which environment variable receives the address.
4. **Your agent:** reads the address from that variable instead of the real service's URL.

## Declare the dependency

```json Descriptor theme={null}
"dependencies": [
  {
    "alias": "mail",
    "service_alias": "agent",
    "protocol": "mcp",
    "mode": "synthetic",
    "operations": ["messages.list", "messages.send"]
  }
]
```

Also add the variable name to the service's `configuration` in the descriptor, for example `{"name": "MAIL_MCP_URL", "phase": "runtime", "secret": false, "required": true}`.

## Route it in the local plan

Add `dependency_env` to the service that makes the calls:

```json Local plan service theme={null}
"dependency_env": [
  { "alias": "mail", "name": "MAIL_MCP_URL", "url": "mcp" }
]
```

| `url` | Your agent receives | Use for |
| - | - | - |
| `invoke` | `http://127.0.0.1:<port>/<key>/<alias>/v1/invoke` | `http` dependencies |
| `mcp` | `http://127.0.0.1:<port>/<key>/<alias>/mcp` | `mcp` dependencies |

The service must be launched fresh for each drill (`mode: launch`, `per_drill: true`), or be the process the `jsonl-process.v1` driver starts. Every synthetic dependency must be routed.

### Use an MCP configuration file

If your agent loads MCP servers from a config file, set `mcp_config_env` on the service instead:

```json Local plan service theme={null}
"mcp_config_env": "MCP_CONFIG_PATH"
```

The variable receives the path of a private file like this:

```json theme={null}
{
  "mcpServers": {
    "mail": { "type": "http", "url": "http://127.0.0.1:<port>/<key>/mail/mcp", "headers": {} }
  }
}
```

## Point your agent at the address

Prefer a setting your agent already has, in this order:

1. The SDK's base URL option.
2. The MCP server configuration.
3. Your framework's routing for tools.

Do not use proxies, custom certificate authorities or DNS overrides. The plan refuses them.

## Call an HTTP dependency

For a dependency with `protocol: http`, route it with `"url": "invoke"`, for example to `MAIL_INVOKE_URL`. Then send a POST:

```bash theme={null}
curl -s -X POST "$MAIL_INVOKE_URL" \
  -H 'content-type: application/json' \
  -d '{"operation": "messages.list", "arguments": {"userId": "me", "q": "is:unread"}}'
```

| Field | Description |
| - | - |
| `operation` | One of the operations in the descriptor. Others return 403 `operation_not_declared`. |
| `arguments` | The operation's input. |
| `idempotency_key` | Optional. Send the same key when you retry. |

The simulated service's status and body come back unchanged.

## Call an MCP dependency

The `mcp` address is a Streamable HTTP MCP server. `tools/list` returns the simulated service's tools and `tools/call` runs them. Connect with any MCP client library.

## Errors your agent may see

| Status | Code | What to do |
| - | - | - |
| 503 | `dependency_not_ready` | Wait for `retry-after`, then try again. |
| 503 | `dependency_unavailable` | The scenario made the service unavailable on purpose. Handle it as an outage. |
| 409 or 502 | varies | Retry with the same `idempotency_key`. Never create a new one. |
| 403 | `operation_not_declared` | Add the operation to the descriptor and the world. |
| 413 | `request_too_large` | Send a smaller request. |

## Pick a synthetic tool

```bash theme={null}
firedrill tools catalog
firedrill tools save <release-id>
firedrill tools runnable
```

`tools save` adds a catalog tool to your workspace. `tools runnable` lists the saved versions you can use in a world. `tools definitions show <version-id>` prints the contract digest the world needs. See [Synthetic tools](https://docs.firedrill.run/tools/overview.md).

> [card] [Build a world](https://docs.firedrill.run/build/worlds.md)
>
> Map each dependency to a tool version.

> [card] [Synthetic tools](https://docs.firedrill.run/tools/overview.md)
>
> See which services are available.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.