Skip to content

poma-mcp — PrimeCut MCP Server

poma-mcp is POMA AI's Model Context Protocol server for the PrimeCut document-ingestion product. It exposes four tools: submit a file and wait, resume a job, check status, or fetch a completed result. Drop it into Claude Code, Claude Desktop, Cursor, or any other MCP-aware agent and you can ingest documents through natural language and get back hierarchical chunks plus chunksets.

This server does not expose Grill tools. The Grill context engine lives in a separate MCP server — poma-grill-mcp. If you need both products, install both binaries.

When to use this server

Pick poma-mcp when you want:

  • The raw PrimeCut output — chunks (hierarchical content tree), chunksets (pre-grouped embedding windows), or the full .poma archive bytes — directly from an agent.
  • A simple stdio/HTTP server to feed your own embedding + retrieval stack downstream.
  • Direct-ingest mode from the shell (poma-mcp -input /path/to.pdf) for scripts and one-off jobs.

If you need Grill ingestion + hybrid search instead, use poma-grill-mcp. The two servers can run side-by-side in the same MCP client config — just give them distinct names (e.g. poma-primecut and poma-grill).

1. Get an API key

Sign up at console.poma-ai.com and copy your account API key (prefix poma_acc_…).

2. Install

bash
brew install poma-ai/poma-mcp/poma-mcp
which poma-mcp     # capture the absolute path for the next step
bash
go install github.com/poma-ai/poma-mcp@latest
which poma-mcp
bash
git clone https://github.com/poma-ai/poma-mcp
cd poma-mcp
go build -o bin/poma-mcp .
realpath bin/poma-mcp

3. Wire it into your MCP client

Use the absolute path from the previous step.

json
{
  "mcpServers": {
    "poma-primecut": {
      "command": "/full/path/to/poma-mcp",
      "args": ["-input", "-"],
      "env": { "POMA_API_KEY": "your-api-key" }
    }
  }
}
json
{
  "mcpServers": {
    "poma-primecut": {
      "command": "/full/path/to/poma-mcp",
      "args": ["-input", "-"],
      "env": { "POMA_API_KEY": "your-api-key" }
    }
  }
}
json
{
  "mcpServers": {
    "poma-primecut": {
      "command": "/full/path/to/poma-mcp",
      "args": ["-input", "-"],
      "env": { "POMA_API_KEY": "your-api-key" }
    }
  }
}

Restart the client. You should now be able to ask things like:

"Ingest ~/Documents/contract.pdf with POMA PrimeCut and show me the chunkset for page 3."

Tools

poma-mcp exposes four tools, all primecut_*:

ToolWhat it does
primecut_ingestUpload a file, wait for processing, return parsed chunks + chunksets. Set archiveOutput: true to also receive the raw .poma archive (base64).
primecut_statusFetch the current status of a job (non-streaming). Returns status and any error.
primecut_resumeRe-attach to a running ingest job by job_id. Useful when an MCP connection drops mid-ingest.
primecut_get_resultFetch the result of an already-completed job without re-streaming events.

primecut_ingest

ArgumentTypeRequiredDescription
file_base64stringyesStandard base64 of the file bytes.
filenamestringnoOriginal filename (report.pdf). Server infers from bytes when omitted.
tokenstringnoAPI key — overrides POMA_API_KEY for this call.
ecobooleannoUse eco / cost-optimised ingest mode.
archiveOutputbooleannoAlso include the .poma archive bytes (base64) in the data field.

The response shape mirrors what the SDK and CLI return: result.chunks, result.chunksets, plus a job_id and a list of status events. See the PrimeCut SDK results page for the full structure.

primecut_status

ArgumentTypeRequiredDescription
job_idstringyesJob ID to check.
tokenstringnoAPI key.

Returns the current status (one of pending, processing, done, failed) and an error field when applicable. Does not stream — call it on a polling interval if you want progress updates.

primecut_resume

ArgumentTypeRequiredDescription
job_idstringyesJob ID from a prior ingest.
tokenstringnoAPI key.
timeout_secondsintegernoMax wait time. Default 600.
archiveOutputbooleannoReturn .poma archive bytes in the data field.

Re-attaches to a running job's status stream and returns its terminal result. Useful if primecut_ingest returned but the MCP connection dropped before the job finished.

primecut_get_result

ArgumentTypeRequiredDescription
job_idstringyesJob ID of a completed job.
tokenstringnoAPI key.

Fetch the cached result of a job that already reached done. Does not poll, does not re-stream — fails fast with an error if the job is not yet terminal.

Output shape

primecut_ingest returns:

json
{
  "job_id": "100c65a03a304aa343a1518aa79e8300-20260414T083549Z",
  "result": {
    "chunks": [
      {
        "chunk_index": 0,
        "content": "WGV Rechtsschutzversicherung – Umfassender Schutz",
        "depth": 0,
        "parent_chunk_index": null,
        "poma_page": 1,
        "to_embed": "WGV Rechtsschutzversicherung – Umfassender Schutz"
      }
    ],
    "chunksets": [
      {
        "chunkset_index": 0,
        "chunk_indices": [0, 1, 2],
        "poma_page": 1,
        "text": "…concatenated to_embed text for all member chunks…"
      }
    ]
  },
  "events": [
    { "status": "queued" },
    { "status": "processing" },
    { "status": "done" }
  ]
}
Chunk fieldDescription
chunk_indexPosition in the flat chunk list.
contentExtracted text (or HTML for tables).
depthNesting depth in the document hierarchy.
parent_chunk_indexIndex of the parent chunk (null for root).
poma_pageSource page number.
to_embedPlain-text version used for embedding.
image_nameSet when the chunk describes an image.
tableSet when the chunk is a table (content is HTML).
Chunkset fieldDescription
chunkset_indexPosition in the chunkset list.
chunk_indicesIndices of the chunks that form this chunkset.
textConcatenated to_embed text for all member chunks.
poma_pagePage of the first chunk in the set.

On error, the MCP response sets isError: true and error describes the failure: { "error": "job failed: unsupported file type" }.

Direct file ingest (no MCP client)

For scripts and one-off jobs you can skip the MCP handshake entirely. Pass any non-MCP file path as -input:

bash
POMA_API_KEY=your-key poma-mcp -input /path/to/document.pdf

The server runs primecut_ingest immediately and prints the JSON result to stdout. Add -eco for eco mode or -archiveOutput to also emit the .poma archive (base64).

HTTP mode

Run as a long-lived HTTP server for custom integrations:

bash
POMA_API_KEY=your-key poma-mcp -http :8080
  • MCP endpoint: POST http://localhost:8080/v1 (standard streamable HTTP MCP — initialize → capture Mcp-Session-Idnotifications/initializedtools/call).
  • Health check: GET http://localhost:8080/health.

The repo's test.sh is a working stdio example you can adapt.

Docker

bash
# HTTP mode
docker run -e POMA_API_KEY=your-key -p 8080:8080 \
  ghcr.io/poma-ai/poma-mcp -http :8080

# Stdio (default entrypoint)
docker run -i -e POMA_API_KEY=your-key ghcr.io/poma-ai/poma-mcp

All flags

FlagDefaultDescription
-input <path|->Stdio mode: MCP on stdin (-) or a non-MCP file path for direct ingest.
-http <addr>HTTP mode (e.g. :8080). Mutually exclusive with -input.
-token <key>API key (alternative to POMA_API_KEY).
-ecofalseUse eco / cost-optimised ingest.
-archiveOutputfalseAlways return the .poma archive (server-wide).
-roots /a,/bRestrict file access to these directory prefixes — useful for direct-ingest mode.

Troubleshooting

SymptomLikely causeFix
Tool calls return isError: true with unauthorizedMissing or wrong API keySet POMA_API_KEY or pass token per call.
Large PDFs fail with payload-too-large errorsBase64 inflates JSON body past MCP frame limitsUse poma-mcp -input <path> for direct ingest, or POST the raw bytes to the REST API.
Agent looks for grill_* tools and finds nothingpoma-mcp only ships primecut_* toolsInstall poma-grill-mcp alongside this server (give them distinct names in your client config).
Claude Desktop doesn't see the serverConfig edited but client not restartedQuit and relaunch Claude Desktop.

See also