Metadata-Version: 2.5
Name: verbumia-mcp
Version: 0.15.0
Summary: Model Context Protocol server for Verbumia — list projects, missing keys, propose translations from Claude Desktop and other MCP clients.
Project-URL: Homepage, https://verbumia.ca
Project-URL: Documentation, https://verbumia.ca/docs/mcp/setup
Project-URL: Source, https://github.com/verbumia/verbumia-tools
Project-URL: Issues, https://github.com/verbumia/verbumia-tools/issues
Author: Verbumia
License: MIT
License-File: LICENSE
Keywords: claude,i18n,mcp,translations,verbumia
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Internationalization
Requires-Python: <3.14,>=3.12
Requires-Dist: httpx>=0.28
Requires-Dist: mcp>=1.0
Requires-Dist: pydantic>=2.9
Description-Content-Type: text/markdown

# Verbumia MCP server

Model Context Protocol server for [Verbumia](https://verbumia.ca) — exposes
your translation project to Claude Desktop and other MCP clients.

## Status

Tools wired: `list_projects`, `get_project_info`, `list_keys`,
`list_untranslated_keys`, `list_missing_keys`, `missing_keys_stats`,
`acknowledge_missing_keys`, `create_namespace`, `create_key`,
`create_keys_bulk`, `update_key`, `update_keys_bulk`, `propose_translation`,
`propose_translations_bulk`, `publish_cdn`, `validate_translations`,
`project_context_get`, `project_context_set`, `glossary_list`, `glossary_create`,
`glossary_update`, `glossary_delete`, `health_report`, `coverage_report`,
`delete_keys_bulk`, `restore_keys_bulk`, `list_trash`.

### Project context document (V1.2)

`project_context_get` / `project_context_set` read and write a free-form
markdown blob attached to the project — terminology, brand voice, domain
notes (religious, legal, medical, gaming, etc.). The content is intended
as ambient context for human translators **and** for AI agents producing
translations: prepend it to your translation prompts so every output stays
consistent with the project's vocabulary and tone. Hard cap 100 KiB.

Scopes:
- `project_context_get` requires `project:read` (existing scope).
- `project_context_set` requires `project:settings:write` (new scope, narrower
  than `project:write` since settings changes propagate to every translator's
  prompt context).

Note: the blanket `mcp:*` scope is **not** sufficient for these tools — grant
the precise scope on the key.

### Glossary (V1.3)

CRUD over the project glossary — the terminology rules the backend applies when
translating. The single public `rule_type` vocabulary is `translation` |
`do_not_translate` | `forbidden` (the internal storage type is never exposed).

- `glossary_list` — filters `rule_type`, `q` (substring on term), `limit`
  (1..500, default 200) → `{ items, total }`.
- `glossary_create` — `{ rule_type?, term, translations?, case_sensitive?, note? }`;
  `rule_type` defaults to `translation`; `translations` is honored only for
  `translation`. 409 on a duplicate `(rule_type, term)`.
- `glossary_update` — by `entry_id`; send only the fields to change (`term`,
  `translations`, `case_sensitive`, `note`). `rule_type` is immutable.
- `glossary_delete` — by `entry_id`.

These use the dedicated MCP surface `/v1/mcp/projects/{id}/glossary` and need the
`mcp:*` scope (the dashboard glossary endpoints are project-role only).

**Per-string glossary hints.** `list_untranslated_keys` and `list_keys` accept
`include_glossary_hints: true` (default false). When set, each returned key
carries a `glossary_hints[]` array — `{ term, rule_type, target_translation,
matched_text }` — for the rules the backend matched against the key's source
string. All matching is backend-side; the MCP forwards the flag and surfaces the
hints verbatim.

### Quality reports + trash (V1.4)

Read-only inspection (surfaced verbatim):
- `health_report` — project source-health report (source-string issues, with
  `by_issue` / `by_severity` rollups). Optional `version_id`.
- `coverage_report` — translation-coverage report (global completeness +
  per-language). Optional `version_id`.

Trash — soft-delete, restorable; **no purge over MCP** (hard-delete is
human-only via the dashboard):
- `delete_keys_bulk` — move up to 500 keys to the trash by `key_uuid` (idempotent).
- `restore_keys_bulk` — restore trashed keys by `key_uuid`.
- `list_trash` — list trashed keys (`{key_uuid, namespace, name, deleted_at}`,
  cursor-paginated).

The trash tools are **uuid-addressed**: get `key_uuid` from `list_keys` (active)
or `list_trash` (trashed), then pass it to delete/restore. A trashed key
disappears from `list_keys`, `list_untranslated_keys`, the CDN, and the reports
until it is restored.

### Edit a key's source value (V1.5)

`update_key` / `update_keys_bulk` edit a key's **source-language value in place**
(`PATCH`), preserving the key and its history (version bump + history revision +
audit). Address the key by **exactly one** of `key_uuid` (preferred — from
`list_keys`) **or** `namespace` + `name`; an optional `description` can be updated
in the same call.

- When the `source_value` **actually changes**, the key's `reviewed` / `approved`
  target translations are demoted to needs-review (`translated`, the "à revoir"
  state); `missing` / `draft` / `translated` targets are left untouched.
  `stale_flagged` reports how many were demoted.
- Submitting the current value is a **no-op** (`result: "unchanged"`, not billed);
  a real source change — or a `description`-only change — bills 1 unit per key.
- `update_keys_bulk` takes up to 500 items and returns a per-item `results` array
  (`status`: `ok` | `unchanged` | `error`) plus a `summary` roll-up; valid items
  commit even if siblings fail.

## Install

```bash
# Recommended (zero-install, used by Claude Desktop's mcp.json):
npx -y @verbumia/mcp

# Or from PyPI:
pipx install verbumia-mcp
```

A Homebrew tap (`brew install verbumia/tap/verbumia-mcp`) is coming once we
publish to npm.

## Configure (Claude Desktop)

Open **Settings → Developer → Edit Config**, then:

Single-project setup:

```json
{
  "mcpServers": {
    "verbumia": {
      "command": "npx",
      "args": ["-y", "@verbumia/mcp"],
      "env": {
        "VERBUMIA_API_KEY": "vrb_live_<prefix>.<secret>",
        "VERBUMIA_PROJECTS": "<project_uuid>",
        "VERBUMIA_BASE_URL": "https://api.verbumia.dev"
      }
    }
  }
}
```

Multi-project setup (v0.11+) — comma-separate the UUIDs and Claude will pass
`project_uuid` on each tool call:

```json
"env": {
  "VERBUMIA_API_KEY": "vrb_live_<prefix>.<secret>",
  "VERBUMIA_PROJECTS": "01993a..,01993b..,01993c.."
}
```

Restart Claude Desktop. Tools show up in the prompt UI.

## Environment

| Variable             | Required | Default                        | Description                                                                                |
|----------------------|----------|--------------------------------|--------------------------------------------------------------------------------------------|
| `VERBUMIA_API_KEY`   | yes      |                                | API key from Org Settings → API Keys (`VERBUMIA_TOKEN` also accepted, back-compat)         |
| `VERBUMIA_PROJECTS`  | no       | (LLM passes per call)          | CSV of project UUIDs. When >1, the LLM MUST pass `project_uuid` on each tool call.         |
| `VERBUMIA_PROJECT`   | no       | (legacy)                       | Singular fallback for v0.10.x users. Ignored when `VERBUMIA_PROJECTS` is set (warns).      |
| `VERBUMIA_BASE_URL`  | no       | `https://api.verbumia.dev`      | Override for self-host or staging (`VERBUMIA_API_BASE` also accepted, back-compat)         |

The token format is `vrb_live_<prefix>.<secret>` and must carry the `mcp:*`
scope. For the `project_context_*` tools, also grant `project:read` and/or
`project:settings:write` — see the **Project context document** section
above. Treat the token like any other secret — keychain or `.env`, never
commit.

If your API key is pinned to a single project (its `project_uuid` is set
server-side), listing additional UUIDs in `VERBUMIA_PROJECTS` will surface
as a `403 API key is scoped to a different project` from the backend on
any call targeting one of the others.

## Local development

```bash
cd mcp
uv sync
uv run verbumia-mcp        # stdio transport — pipe MCP frames over stdin/stdout
```

## License

MIT.
