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.
- Repo: github.com/poma-ai/poma-mcp
- Transports: stdio (default), streamable HTTP (
-http :8080), Docker - License: MPL-2.0
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.pomaarchive 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
brew install poma-ai/poma-mcp/poma-mcp
which poma-mcp # capture the absolute path for the next stepgo install github.com/poma-ai/poma-mcp@latest
which poma-mcpgit clone https://github.com/poma-ai/poma-mcp
cd poma-mcp
go build -o bin/poma-mcp .
realpath bin/poma-mcp3. Wire it into your MCP client
Use the absolute path from the previous step.
{
"mcpServers": {
"poma-primecut": {
"command": "/full/path/to/poma-mcp",
"args": ["-input", "-"],
"env": { "POMA_API_KEY": "your-api-key" }
}
}
}{
"mcpServers": {
"poma-primecut": {
"command": "/full/path/to/poma-mcp",
"args": ["-input", "-"],
"env": { "POMA_API_KEY": "your-api-key" }
}
}
}{
"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.pdfwith POMA PrimeCut and show me the chunkset for page 3."
Tools
poma-mcp exposes four tools, all primecut_*:
| Tool | What it does |
|---|---|
primecut_ingest | Upload a file, wait for processing, return parsed chunks + chunksets. Set archiveOutput: true to also receive the raw .poma archive (base64). |
primecut_status | Fetch the current status of a job (non-streaming). Returns status and any error. |
primecut_resume | Re-attach to a running ingest job by job_id. Useful when an MCP connection drops mid-ingest. |
primecut_get_result | Fetch the result of an already-completed job without re-streaming events. |
primecut_ingest
| Argument | Type | Required | Description |
|---|---|---|---|
file_base64 | string | yes | Standard base64 of the file bytes. |
filename | string | no | Original filename (report.pdf). Server infers from bytes when omitted. |
token | string | no | API key — overrides POMA_API_KEY for this call. |
eco | boolean | no | Use eco / cost-optimised ingest mode. |
archiveOutput | boolean | no | Also 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
| Argument | Type | Required | Description |
|---|---|---|---|
job_id | string | yes | Job ID to check. |
token | string | no | API 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
| Argument | Type | Required | Description |
|---|---|---|---|
job_id | string | yes | Job ID from a prior ingest. |
token | string | no | API key. |
timeout_seconds | integer | no | Max wait time. Default 600. |
archiveOutput | boolean | no | Return .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
| Argument | Type | Required | Description |
|---|---|---|---|
job_id | string | yes | Job ID of a completed job. |
token | string | no | API 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:
{
"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 field | Description |
|---|---|
chunk_index | Position in the flat chunk list. |
content | Extracted text (or HTML for tables). |
depth | Nesting depth in the document hierarchy. |
parent_chunk_index | Index of the parent chunk (null for root). |
poma_page | Source page number. |
to_embed | Plain-text version used for embedding. |
image_name | Set when the chunk describes an image. |
table | Set when the chunk is a table (content is HTML). |
| Chunkset field | Description |
|---|---|
chunkset_index | Position in the chunkset list. |
chunk_indices | Indices of the chunks that form this chunkset. |
text | Concatenated to_embed text for all member chunks. |
poma_page | Page 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:
POMA_API_KEY=your-key poma-mcp -input /path/to/document.pdfThe 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:
POMA_API_KEY=your-key poma-mcp -http :8080- MCP endpoint:
POST http://localhost:8080/v1(standard streamable HTTP MCP —initialize→ captureMcp-Session-Id→notifications/initialized→tools/call). - Health check:
GET http://localhost:8080/health.
The repo's test.sh is a working stdio example you can adapt.
Docker
# 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-mcpAll flags
| Flag | Default | Description |
|---|---|---|
-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). |
-eco | false | Use eco / cost-optimised ingest. |
-archiveOutput | false | Always return the .poma archive (server-wide). |
-roots /a,/b | — | Restrict file access to these directory prefixes — useful for direct-ingest mode. |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
Tool calls return isError: true with unauthorized | Missing or wrong API key | Set POMA_API_KEY or pass token per call. |
| Large PDFs fail with payload-too-large errors | Base64 inflates JSON body past MCP frame limits | Use poma-mcp -input <path> for direct ingest, or POST the raw bytes to the REST API. |
Agent looks for grill_* tools and finds nothing | poma-mcp only ships primecut_* tools | Install poma-grill-mcp alongside this server (give them distinct names in your client config). |
| Claude Desktop doesn't see the server | Config edited but client not restarted | Quit and relaunch Claude Desktop. |
See also
poma-grill-mcp— Grill context-engine MCP server (grill_*tools).- PrimeCut SDK — same ingestion flow, programmatic.
- POMA CLI — same workflow from the shell.