# Gemina MCP Server

One hosted server, 13 tools for business documents. Sign in with OAuth 2.1 or send an API key. The FileTag tools are free up to 1,500 calls/month — no credit card.

- HTML version: https://www.gemina.co/docs/mcp
- Product page and config snippets for every host: https://www.gemina.co/product/agents#install
- MCP manifest: https://www.gemina.co/.well-known/mcp.json
- FileTag REST API (markdown): https://www.gemina.co/docs/filetag.md
- Gemina REST API (markdown): https://www.gemina.co/docs.md

## Overview

The Gemina MCP server speaks Streamable HTTP. Mount it as a tool source in any compatible host — Claude Code, claude.ai, Claude Desktop, Cursor, VS Code, Codex CLI, Gemini CLI, Grok, Windsurf, ChatGPT, n8n, Copilot Studio, Zapier, Cline, OpenClaw, Hermes-Agent — or drive it from a script.

- **MCP endpoint:** `https://api.gemina.co/api/v1/mcp/` (keep the trailing slash — the slashless form is rewritten, but some hosts treat the redirect as a failed connection)
- **Transport:** Streamable HTTP
- **Discovery (no credentials):** `https://api.gemina.co/api/v1/mcp/public/` — answers `tools/list` anonymously
- **Manifest:** https://www.gemina.co/.well-known/mcp.json

## Authentication

Tool execution needs a credential. The anonymous discovery mount answers `tools/list` without one.

### OAuth 2.1 — sign in from your app

Register the server without a header. The host discovers the authorization server, opens a browser, and you sign in to Gemina and approve the connection. Each connected app gets its own key; revoke it any time under **Connected apps** in the console. The token carries the `mcp` scope.

```bash
# Claude Code
claude mcp add --transport http gemina https://api.gemina.co/api/v1/mcp/
# then run /mcp inside Claude Code and sign in
```

claude.ai and Claude Desktop: Customize → Connectors → Add → Add custom connector → Paste the URL → Sign in. URL: `https://api.gemina.co/api/v1/mcp/`

Most hosts need nothing beyond the URL: they register themselves on the first 401 and open your browser. Three need an explicit second step. One can't sign in at all:

| Host | What to run | Why |
|---|---|---|
| Codex CLI | `codex mcp add gemina --url https://api.gemina.co/api/v1/mcp/` then `codex mcp login gemina` | A bare `[mcp_servers.gemina]` block in `config.toml` connects unauthenticated |
| OpenClaw | `openclaw mcp set gemina '{"url":"https://api.gemina.co/api/v1/mcp/","transport":"streamable-http","auth":"oauth"}'` then `openclaw mcp login gemina` | The `auth: "oauth"` key and the `login` command are both required — no 401-triggered sign-in |
| Hermes-Agent | `auth: oauth` in `~/.hermes/config.yaml`, then `hermes mcp login gemina` | OAuth is an explicit opt-in; run the login from a fresh terminal, the in-session reload times out first |
| Cline | API key only | No documented OAuth path for remote servers as of 27 August 2026 |

Discovery documents:

- `https://api.gemina.co/.well-known/oauth-protected-resource/api/v1/mcp` — protected resource metadata (RFC 9728)
- `https://api.gemina.co/.well-known/oauth-authorization-server/api/v1/mcp` — authorization server metadata (RFC 8414)

### API key — headless and scripted

Send a Gemina API key on every request, as `Authorization: Bearer` or `X-API-Key`. Same server, same tools; the key you use for the REST API works here unchanged.

- **Get an API key:** https://console.gemina.co/registration/create-account

## Tools

13 tools in 3 groups. Names and descriptions are read from the published manifest at build time.

### FileTag (3 tools, free tier)

Tag, rename, and enrich any PDF or image. Free tier, no credit card.

- `files_create_upload` — Reserve a pre-signed PUT slot for a file the agent holds locally, then follow the returned next_tool_call recipe — tag_file by default, extract_document when purpose='extract'. One slot type: any slot works with either tool. Bytes go straight from the agent host to storage and never traverse the LLM context.
- `tag_file` — Run the FileTag pipeline against a previously uploaded slot. Returns extracted metadata, a suggested filename, six filename patterns, and a short-lived signed URL to an enriched copy with the metadata embedded in document properties or EXIF.
- `tag_url` — Fetch a public HTTPS URL server-side under strict SSRF guards and run the FileTag pipeline on it. Same result shape as tag_file; the bytes never traverse the LLM context.

### Extraction (7 tools, plan credits)

Typed extraction over invoices, Hebrew documents, line items, raw OCR, and custom templates.

- `extract_document` — Run typed extraction on an uploaded slot from files_create_upload. Choose extraction_types: invoice_headers, invoice_line_items, custom_template, ocr (runs only on the praetorian model), or the legacy document_details_hebrew / document_line_items_hebrew (praetorian only, not recommended). Model choice is a recommendation, not a rule: velox for headers, invictus with thinking for line items. Asynchronous — returns the result directly or a correlationId to poll. Thinking, evaluation, correction, and coordinate toggles mirror the REST API.
- `get_extraction_result` — Poll for the result of an asynchronous extract_document call using its correlationId. Returns the completed extraction, or an in-process status to poll again.
- `list_extractions` — List past extractions, newest first. Filter by external_id, end_user_id, or an ISO date window, and paginate with skip and limit.
- `get_extraction` — Fetch one extraction by id, including the full extracted data.
- `get_document` — Fetch one document by id, including all of its extractions.
- `add_document_extractions` — Run more extraction types on a document Gemina already stores — no re-upload. Pass the document id (from tag_file, extract_document, or get_document) and the extraction_types; paid per extraction like an upload. Two modes: leave wait at its default to hold the call and read the values in the same turn (poll pollCorrelationId with get_extraction_result), or pass wait=false to return at once when you only need the document filed for later search — the extraction still runs to completion and its outcome stays visible in get_document / list_extractions. Both modes cost the same. Every structured type (not plain OCR) is also submitted for indexing, so the document becomes answerable by query_documents and aggregate_documents; indexing is opt-in, plan-gated and best-effort. A pending upload slot (gfile_…) is not a document id.
- `submit_extraction_feedback` — Submit verified or corrected field values for a completed extraction and get back a per-field comparison summary. Each extraction accepts feedback once.

### Document Intelligence (3 tools, plan credits)

Ask questions and run spend analytics across the tenant's indexed documents — search and compute exact totals, no re-upload.

- `query_documents` — Ask across your whole indexed collection, no re-upload. Search in structured mode (exact field filters), semantic mode (natural-language similarity over extracted fields and FileTag metadata, not raw body text), or hybrid mode (keyword and semantic fused with Reciprocal Rank Fusion, the best default). Returns matched documents with their extracted fields; semantic and hybrid modes also return relevance scores.
- `aggregate_documents` — Spend analytics with no export: compute sums, averages, minimums, maximums, and counts over your indexed documents, grouped by vendor, currency, document type, expense type, payment method, end user, month, or year — e.g. total spent per vendor last quarter. Counts are per document (re-uploads collapse on a full identity match). Money metrics are always split per currency unless a currency filter is given, so totals are never mixed.
- `index_document` — Manually (re)index one document into the searchable index — after corrections, or to backfill a document processed before indexing was enabled. Documents are otherwise submitted for indexing automatically for FileTag and structured extractions once the tenant enables it — plain OCR is not indexed, and a document can be skipped (e.g. no extractable fields or no indexing credits).

Chat is deliberately not a tool: a conversation carries state between turns and an MCP call is stateless. Agents compose a conversational answer from `query_documents` and `aggregate_documents` instead.

## Errors

Transport-level failures use HTTP status codes; tool failures come back as the standard Gemina error envelope inside the JSON-RPC result. Branch on `error_code`, not on the message.

| Status | `error_code` | Meaning |
|---|---|---|
| `401` | `UNAUTHORIZED_ERROR` | No credential was sent — an OAuth host reads the `WWW-Authenticate` challenge and starts the sign-in |
| `403` | `ACCESS_DENIED_ERROR` | The key is unknown, revoked or expired — re-sending it will not help |
| `403` | `insufficient_scope` | The OAuth token does not carry the `mcp` scope — reconnect the app |
| `429` | `FILETAG_RATE_LIMIT_EXCEEDED` | Burst limit — wait the `Retry-After` header and retry |
| `429` | `FILETAG_QUOTA_EXHAUSTED` | Monthly free allowance spent — `Retry-After` counts down to the reset |
| `429` | `CREDIT_EXHAUSTED`, `INSUFFICIENT_CREDITS`, `SPEND_LIMIT_EXCEEDED` | Extraction and Document Intelligence run on plan credits — retrying will not help until the reset or a plan change |

Full status-code table: https://www.gemina.co/docs#errors

## Headless session with curl

Open a session with `initialize`, then list the tools. The same headers work for `tools/call`.

```bash
curl -X POST https://api.gemina.co/api/v1/mcp/ \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'
```

```bash
curl -X POST https://api.gemina.co/api/v1/mcp/ \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
```

## Limits

- Files up to 50 MB
- ~10 calls/second burst per key
- 1,500 FileTag calls/month on the free tier; extraction and Document Intelligence run on plan credits (see https://www.gemina.co/pricing)

## Links

- Config snippets for every host: https://www.gemina.co/product/agents#install
- gemina-mcp on GitHub: https://github.com/tommyil/gemina-mcp
- Agent-ready install guide: https://raw.githubusercontent.com/tommyil/gemina-mcp/main/llms-install.md
- FileTag REST API: https://www.gemina.co/docs/filetag
- Gemina REST API: https://www.gemina.co/docs
- Free API key: https://console.gemina.co/registration/create-account
