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

# Code map: CLI and MCP

> What apps/cli and the crates that serve the syntheo CLI and its MCP server contain, and the doc pages that depend on them.

This page links the code of the `syntheo` CLI and its MCP server to the documentation pages to update when it changes. For the monorepo overview, see [Architecture](https://docs.syntheo.studio/en/architecture.md).

## Contracts checked by tests

Two tests in `apps/cli` read the public documentation directly. A command or MCP tool change breaks CI until these pages follow:

| Test | File | What it checks |
| - | - | - |
| `public_docs_and_skill_cover_the_command_contract` | `apps/cli/src/cli.rs` | Each leaf subcommand and each `--long` option appears in `docs/reference/cli.mdx`, and each subcommand in `skills/syntheo/references/cli.md` or `setup.md`. |
| `cli_contract_matches_snapshot` | `apps/cli/src/cli.rs` | The JSON contract generated by `cli_docs::generate_json` matches the `insta` snapshot in `apps/cli/src/snapshots/`. |
| `client_server_handshake_lists_tools_and_resources` | `apps/cli/src/mcp/tests.rs` | Each tool, its parameters and each resource template (`syntheo://…`) appear in `docs/reference/mcp.mdx`; tools and resources also appear in `skills/syntheo/references/mcp.md`. The contract is frozen in the `mcp_contract` snapshot. |

> [!NOTE]
>
> `docs/AGENTS.md` names `apps/cli/src/cli.rs` as the command contract and `apps/cli/src/mcp/` as the MCP tools and resources contract.

## `apps/cli`: the `syntheo` binary

* **Path**: `apps/cli` (Cargo package `syntheo-cli`, binary `syntheo`, `src/main.rs`).
* **Role**: command-line access to the local `app.db` database and stdio MCP server.
* **Internal dependencies**: `crates/agent-access`, `crates/db-app`, `crates/db-core`. In development only: `crates/cli-docs`.
* **Affected doc pages**: [/en/reference/cli](https://docs.syntheo.studio/en/reference/cli.md), [/en/reference/mcp](https://docs.syntheo.studio/en/reference/mcp.md), [/en/reference/errors](https://docs.syntheo.studio/en/reference/errors.md), [/en/agents/cli](https://docs.syntheo.studio/en/agents/cli.md), [/en/agents/mcp](https://docs.syntheo.studio/en/agents/mcp.md), [/en/agents/overview](https://docs.syntheo.studio/en/agents/overview.md), [/en/installation](https://docs.syntheo.studio/en/installation.md), [/en/import-recordings](https://docs.syntheo.studio/en/import-recordings.md).

### Modules

| File | Role |
| - | - |
| `src/main.rs` | Parses arguments with clap. With `--json`, an argument error is output as JSON (`code: "invalid_arguments"`). |
| `src/lib.rs` | `run(args)`: dispatches each command and returns the exit code. `doctor` runs before any database opening. Exposes `VERSION` (the `APP_VERSION` variable at build time, otherwise the Cargo version). |
| `src/cli.rs` | clap definition of all commands and options (public contract). |
| `src/db.rs` | Resolves the database path and opens it read-only (`open`) or for writing (`open_write`). |
| `src/output.rs` | JSON envelope `{schema_version, command, data, pagination}` (`JSON_SCHEMA_VERSION = "1"`), writing exports without overwriting an existing file unless `--force`. |
| `src/error.rs` | Stable error codes and exit codes. |
| `src/mcp/` | MCP server (`rmcp`, stdio transport): tools in `mod.rs`, `ServerHandler` and resources in `handler.rs`, contract tests in `tests.rs`. |
| `src/commands/*` | Subcommand implementations. |

### Commands

| Command | Implementation | Database access |
| - | - | - |
| `doctor` | `commands/doctor.rs` | Checks the CLI and the database without changing data; code 1 if the database isn't ready. |
| `meetings list`, `folders`, `get`, `note`, `transcript`, `history`, `export` | `commands/meetings.rs` | Read-only. |
| `meetings import`, `import-status` | `commands/recording_import.rs` | Write; requires `--source local`. |
| `meetings hold-list`, `hold-export` | `commands/meeting_hold.rs` | Inventory and NDJSON stream of the local history for archiving. |
| `meetings pilot-usage` | `commands/meeting_pilot.rs` | Capture intervals, without content; requires `--source local`. |
| `meetings capabilities` | `lib.rs` | Doesn't open the database; describes the managed capture capabilities. |
| `meetings initialize-managed`, `delete` | `commands/meeting_delete.rs` | Database preparation according to a managed policy; permanent deletion of a completed meeting (requires `--source local` and `--require-transcription-complete`). |
| `proposals create`, `list`, `show`, `decline` | `commands/proposals.rs` | Write to the proposals table, never to the note. |
| `mcp` | `mcp.rs` | Write (proposals, imports). |

Global options: `--base` (`SYNTHEO_BASE`), `--db-path` (`SYNTHEO_DB_PATH`), `--json`. `meetings` accepts `--source` (`SYNTHEO_SOURCE`, `local` by default; `auto` is an alias of `local`).

### Database access

`db.rs` looks for the database in this order: `--db-path`, then `--base`/`app.db`, then the system's data folder. Under that folder, the CLI tries `syntheo/app.db`, then `fr.willisback.syntheo/app.db`. A binary named `syntheo-dev` reads `fr.willisback.syntheo.dev/app.db`. A missing database gives the `database_not_found` error: the CLI never creates or migrates the database.

### Error codes

| Code | Exit | Origin |
| - | - | - |
| `operation_failed` | 1 | Generic error, including the `Invalid`, `Conflict` and `Database` errors from `agent-access`. |
| `not_found` | 2 | Meeting, proposal or import not found. |
| `database_not_found` | 3 | `app.db` file missing. |
| `output_exists` | 4 | The export file already exists and `--force` is missing. |
| `invalid_arguments` | clap code | Invalid arguments with `--json`. |

An import started with `--wait` that exceeds `--timeout` also returns code 2, keeping the job queued for `import-status`.

### MCP server

`mcp.rs` declares a `syntheo` server (tools and resources enabled) with instructions that point the agent to `list_meetings` first and forbid direct access to SQLite.

| Tools | `agent-access` function |
| - | - |
| `import_recording`, `get_recording_import` | `import_recording`, `get_recording_import` |
| `list_meetings`, `list_folders`, `get_meeting` | `list_meetings`, `list_folders`, `get_meeting` |
| `get_meeting_transcript`, `get_recurring_meeting_history` | `get_meeting_transcript`, `get_recurring_meeting_history` |
| `export_meeting` | `get_meeting_export` |
| `propose_summary_edit`, `propose_memo_edit`, `list_proposals`, `get_proposal`, `decline_proposal` | `create_proposal`, `list_proposals`, `get_proposal`, `decline_proposal` |

Resources: `syntheo://meetings/{meeting_id}` (Markdown), `syntheo://meetings/{meeting_id}/transcript{?offset,limit}` (text, bounded limit) and `syntheo://series/{series_id}` (Markdown list of the series).

## Crates serving the CLI

### `crates/agent-access`

* **Path**: `crates/agent-access` (package `agent-access`, workspace alias `syntheo-agent-access`).
* **Role**: shared meeting operations, called by the CLI, the MCP server and the app.
* **Main API**:
  * read: `list_meetings`, `list_folders`, `get_meeting`, `get_meeting_transcript`, `get_recurring_meeting_history`, `get_meeting_export`, `get_local_meeting_export`, `paginate_transcripts`;
  * proposals (`proposals.rs`): `create_proposal`, `list_proposals`, `get_proposal`, `decline_proposal`, `proposal_unified_diff`;
  * import (`recording_import.rs`): `import_recording`, `get_recording_import`. The import is only queued if the app reports an active worker: it renews a heartbeat in the `local_recording_import_worker` table (see `apps/desktop/src/stt/recording-import.tsx`);
  * rendering: `to_markdown`, `to_export_markdown`, `ExportLocale`, `format_export_date`, `localize_speaker_label` (`export_markdown.rs`, `transcript_render.rs`);
  * limits: `DEFAULT_LIST_LIMIT` 20, `MAX_LIST_LIMIT` 200, `DEFAULT_TRANSCRIPT_LIMIT` 200, `MAX_TRANSCRIPT_LIMIT` 500, `DEFAULT_FOLDER_LIST_LIMIT` 100.
* **Internal dependencies**: `crates/db-app`, `crates/tiptap`, `crates/transcript`.
* **Used by**: `apps/cli`, `plugins/db` (meeting export), `plugins/local-api`, `crates/session-ingest`.
* **Affected doc pages**: [/en/reference/cli](https://docs.syntheo.studio/en/reference/cli.md), [/en/reference/mcp](https://docs.syntheo.studio/en/reference/mcp.md), [/en/agents/cli](https://docs.syntheo.studio/en/agents/cli.md), [/en/agents/mcp](https://docs.syntheo.studio/en/agents/mcp.md), [/en/import-recordings](https://docs.syntheo.studio/en/import-recordings.md), [/en/notes](https://docs.syntheo.studio/en/notes.md) (Markdown export).

> [!WARNING]
>
> The transcript limits (200 words by default, 500 at most) come from these constants. `docs/AGENTS.md` requires the same values in the documentation examples.

### `crates/cli-docs`

* **Path**: `crates/cli-docs` (`publish = false`).
* **Role**: generates a description of the clap tree, in Markdown (`generate`) or in JSON (`generate_json`, types `CommandDoc`, `OptionDoc`, `ArgumentDoc`).
* **Internal dependencies**: none.
* **Used by**: only the `apps/cli` tests (`dev-dependencies`), for the contract snapshot.
* **Affected doc pages**: none directly; protects [/en/reference/cli](https://docs.syntheo.studio/en/reference/cli.md) against unnoticed drift.

### `crates/agent-core`

* **Path**: `crates/agent-core` (alias `syntheo-agent-core`).
* **Role**: diagnosis and installation of a hook-based integration for three third-party agent CLIs: Codex, Claude Code and OpenCode (`ProviderKind`).
* **Main API**: `health_check`, `install_cli`, `uninstall_cli`, `upgrade_hooks`; types `ProviderHealth`, `ProviderHealthStatus`, `ProviderAuthStatus`.
* **Internal dependencies**: `crates/claude`, `crates/codex`, `crates/opencode`.
* **Used by**: `plugins/agent`, registered by `apps/desktop/src-tauri` outside App Store builds.
* **Status**: inherited from Anarlog. The installed hooks call the `char` command (for example `char claude notify`), not `syntheo`, and no code in `apps/desktop/src` imports `@syntheo/plugin-agent`. Nothing here serves the `syntheo` CLI.
* **Affected doc pages**: none. The agent skills installation documented in [/en/agents/skills](https://docs.syntheo.studio/en/agents/skills.md) goes through `apps/desktop/src-tauri/src/agent_skills.rs`, not through this crate.

### `crates/cli-process`

* **Path**: `crates/cli-process` (alias `syntheo-cli-process`).
* **Role**: launching child processes with tokio: `spawn_with_retry`, `run_to_string`, `spawn_streaming_lines` (stream of typed lines), bounded reading of stdout and stderr (`MAX_PROCESS_STDOUT_BYTES` 64 MB, `MAX_PROCESS_STDERR_BYTES` 1 MB).
* **Internal dependencies**: none.
* **Used by**: `crates/claude`, `crates/codex`, `crates/opencode`. Neither `apps/cli` nor the MCP server uses it.
* **Affected doc pages**: none.

## App side

The app installs and documents the CLI, but this code lives in `apps/desktop`:

* `apps/desktop/src-tauri/src/embedded_cli.rs`: installs the `syntheo` binary shipped with the app (see [Code map: desktop app](https://docs.syntheo.studio/en/code/desktop.md)).
* `apps/desktop/src-tauri/src/agents-content.md`: `AGENTS.md` file written to the data folder at startup, which points to the MCP tools and the CLI.
* `plugins/local-api` and `plugins/mcp`: app-side commands and types, see [/en/code/plugins](https://docs.syntheo.studio/en/code/plugins.md).

## Code and pages mapping

| If you change | Check |
| - | - |
| `apps/cli/src/cli.rs` | [/en/reference/cli](https://docs.syntheo.studio/en/reference/cli.md), [/en/agents/cli](https://docs.syntheo.studio/en/agents/cli.md), `skills/syntheo/references/cli.md`, snapshot `apps/cli/src/snapshots/` |
| `apps/cli/src/mcp/` | [/en/reference/mcp](https://docs.syntheo.studio/en/reference/mcp.md), [/en/agents/mcp](https://docs.syntheo.studio/en/agents/mcp.md), `skills/syntheo/references/mcp.md`, `apps/desktop/src-tauri/src/agents-content.md` |
| `apps/cli/src/error.rs` | [/en/reference/errors](https://docs.syntheo.studio/en/reference/errors.md), `skills/syntheo/references/errors.md` |
| `apps/cli/src/db.rs` | [/en/installation](https://docs.syntheo.studio/en/installation.md), [/en/troubleshooting](https://docs.syntheo.studio/en/troubleshooting.md) |
| `apps/cli/src/output.rs` | [/en/reference/cli](https://docs.syntheo.studio/en/reference/cli.md) (JSON format) |
| `crates/agent-access/src/recording_import.rs` | [/en/import-recordings](https://docs.syntheo.studio/en/import-recordings.md), [/en/reference/mcp](https://docs.syntheo.studio/en/reference/mcp.md) |
| `crates/agent-access/src/proposals.rs` | [/en/agents/overview](https://docs.syntheo.studio/en/agents/overview.md), [/en/reference/mcp](https://docs.syntheo.studio/en/reference/mcp.md) |
| `crates/agent-access/src/lib.rs` (limits) | [/en/reference/cli](https://docs.syntheo.studio/en/reference/cli.md), [/en/reference/mcp](https://docs.syntheo.studio/en/reference/mcp.md) |


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