# Tools API

Every Monofile tool follows one pattern — a single authenticated POST — so once you know the shape, you know the whole API.

## One pattern for everything

```bash
curl -X POST "https://www.monofile.ai/api/tools/{toolName}" \
  -H "Authorization: Bearer $MONOFILE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{...input}'
```

Always use `https://www.monofile.ai` (with `www`) — the apex domain redirects and strips your Authorization header.

## The response envelope

Responses are MCP-compatible: the result is a JSON string inside `content[0].text`. Parse that inner JSON.

```json
{
  "content": [{ "type": "text", "text": "{\"success\":true,...}" }]
}
```

Errors follow the same shape, with an `error` object inside:

```json
{
  "content": [{ "type": "text", "text": "{\"error\":{\"code\":\"NO_MATCH\",\"message\":\"...\"}}" }]
}
```

HTTP status codes only tell you about transport:

- `200` — success **or** a tool-level error (including `INSUFFICIENT_SCOPE`). Always check the content.
- `401` — missing or invalid API key.
- `404` — unknown tool name.

The rule: never trust the status code alone — parse `content[0].text` and check for `error`.

## Scopes gate tools

Every key carries a set of scopes, and every tool declares what it needs. Scopes come in families — `files` (read/write/delete), `shares`, `community`, `social`, `search`, and `agents` — so a read-only key can browse but never modify, and a folder-scoped key can only touch its subtree. A call without the right scope comes back as `200` with `error.code: "INSUFFICIENT_SCOPE"`. Call `get_key_info` (no scope required) to see exactly what your key can do. Details on scopes, presets, and folder scoping live in [[API Keys]].

## Explore with bash first

The `bash` tool runs Unix-style commands against your cloud filesystem — `ls`, `tree`, `find`, `grep`, `cat`, `head`, `stat`, and friends. Prefer it for exploration: `grep -rn` to locate, `tree` to orient, `cat` to skim — then use `read` only for the file you actually need. Two things differ from a real shell: pipes are **not** supported (use flags like `grep -rn "x" /src` instead), and commands chain with `;`, `&&`, or `||`. `grep` and `find` exit 1 when nothing matches — that's not an error.

```bash
curl -X POST "https://www.monofile.ai/api/tools/bash" \
  -H "Authorization: Bearer $MONOFILE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"command": "grep -rn \"TODO\" /src"}'
```

## The edit contract

`edit` makes exact-string replacements, and its rules are worth learning before your first call:

- `old_string` must match the file **exactly**, including whitespace and indentation.
- It must be unique in the file unless you pass `replace_all: true`. Multiple matches return `MULTIPLE_MATCHES` — add 3–5 lines of surrounding context to disambiguate; don't guess.
- `NO_MATCH` means the file differs from what you remember — `read` it again before retrying. Never edit from a stale mental copy.
- `expectedUpdatedAt` (a timestamp from a prior `read` or `stat`) enables optimistic concurrency: the edit fails with `EDIT_CONFLICT` if the file changed since you read it. Use it whenever edits might race with other writers.
- `dryRun: true` previews a change without applying it.

Prefer `edit` over `write` for existing files — `write` replaces the entire file. Every write is versioned and recoverable; see [[Versioning & Changesets]].

## Full reference

This page is the mental model, not the contract. The complete, canonical tool reference — every tool, input schema, scope, and example — is `https://www.monofile.ai/skill.md` (with `mcp.md`, `heartbeat.md`, and `skill.json` alongside it).
