docs

Documentation

Everything you need to go from zero to parsing. One page, no sidebar rabbit holes.

Quick start

Two things. Account, then one install command.

1. Create an account

Sign up at getfrenchie.dev/register. You get 100 free credits on your first signup, once per email — no credit card required.

Once you're in, grab your API key from the dashboard. It looks like this:

fr_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4

Keep it somewhere safe. You'll need it in the next step.

2. Install Frenchie in your agent

From the root of your project:

npx @lab94/frenchie install --api-key fr_your_key_here

The installer auto-detects your agent, copies the skill files, and writes a project-scoped stdio MCP config. Your agent will call ocr_to_markdown / transcribe_to_markdown with local file paths, and results are saved to .frenchie/<name>/result.md automatically.

You can also target a specific agent explicitly:

# Project-scoped (default):
npx @lab94/frenchie install --agent claude --api-key fr_...
npx @lab94/frenchie install --agent cursor --api-key fr_...
npx @lab94/frenchie install --agent codex  --api-key fr_...
npx @lab94/frenchie install --agent vscode --api-key fr_...
npx @lab94/frenchie install --agent gemini --api-key fr_...

# User-level (requires --global):
npx @lab94/frenchie install --agent antigravity   --global --api-key fr_...
npx @lab94/frenchie install --agent windsurf       --global --api-key fr_...
npx @lab94/frenchie install --agent zed            --global --api-key fr_...
npx @lab94/frenchie install --agent claude-desktop --global --api-key fr_...

User-level installs (Antigravity, Claude Desktop) need the --global flag — auto-detect never writes under $HOME.

Then ask your agent in plain English, or use the shortcuts where supported:

"OCR ./report.pdf with Frenchie"
"Transcribe ./meeting.mp3 and pull out action items"
/ocr invoice.pdf
/transcribe meeting.mp3

For hosted / web agents (HTTP)

Lovable, Manus, Claude.ai, ChatGPT.com, Mistral Le Chat — these can't spawn local binaries. Connect them to the public HTTP endpoint instead:

Claude Code (CLI flag, for reference):

claude mcp add --transport http frenchie https://mcp.getfrenchie.dev --header "Authorization: Bearer fr_your_key_here"

Cursor — add to .cursor/mcp.json:

{
  "mcpServers": {
    "frenchie": {
      "url": "https://mcp.getfrenchie.dev",
      "headers": {
        "Authorization": "Bearer fr_your_key_here"
      }
    }
  }
}

Codex — add to ~/.codex/config.toml:

[mcp_servers.frenchie]
url = "https://mcp.getfrenchie.dev"

[mcp_servers.frenchie.headers]
Authorization = "Bearer fr_your_key_here"

In HTTP mode, agents upload the file first via upload_file, then call OCR/transcription with uploaded_file_reference. The skill pack handles this automatically — install it the same way:

npx @lab94/frenchie install --agent claude
npx @lab94/frenchie install --agent cursor
npx @lab94/frenchie install --agent codex

Pick your agent

Every agent handles MCP a little differently. Pick yours for the exact invocation syntax and the gotchas we've hit in dogfood.

AgentInvokeExampleFull guide
Claude CodeSlash command/ocr TOR.pdfclaude-code →
CursorNatural languageUse Frenchie to OCR TOR.pdfcursor →
Codex (Desktop / CLI / IDE)@frenchie, /frenchie, NL/frenchie TOR.pdfcodex →
Antigravity/<server-name>/frenchie TOR.pdfantigravity →
VS Code CopilotSlash command/frenchie TOR.pdfvscode →
Claude DesktopNatural languageUse Frenchie to OCR TOR.pdfclaude-desktop →
WindsurfNatural languageOCR TOR.pdf via Frenchiewindsurf →
Gemini CLINatural languageOCR TOR.pdf with Frenchiegemini-cli →
ZedAssistant panelOCR TOR.pdf via Frenchiezed →

Something not working? See the symptom-first troubleshooting guide.

MCP tools

Frenchie exposes four core tools through MCP: ocr_to_markdown, transcribe_to_markdown, generate_image, and get_job_result. Your agent picks the right one automatically.

ocr_to_markdown

Converts a PDF or image to Markdown using OCR.

Parameters:

ParameterTypeRequiredDescription
file_pathstringYes*Local path to the file
uploaded_file_referencestringYes*Reference to an already-uploaded file
api_keystringNoOverride the env API key for this request

* One of file_path or uploaded_file_reference is required.

Supported file types:

application/pdf    image/png    image/jpeg    image/webp

Credits: 1 per page.

Routing:

FileModeBehavior
Single-page PDF or small imageSyncResult returned immediately
Multi-page PDF or large fileAsyncReturns jobId — MCP auto-polls for up to 90s, then returns status

Response (done — stdio mode):

{
  "status": "done",
  "savedTo": ".frenchie/invoice/result.md",
  "wordCount": 312,
  "imageCount": 1,
  "creditsUsed": 4,
  "resultExpiresAt": "2026-04-10T15:30:00Z"
}

Stdio mode returns metadata only. The full markdown is written to savedTo on disk — read that file with your agent's file tool if you need the content. This keeps tool responses from flooding the agent's context window (a 17-page PDF drops from ~25k tokens to ~200 bytes).

Response (done — HTTP mode):

{
  "status": "done",
  "markdown": "# Invoice\n\n| Item | Amount |\n|------|--------|\n| Widget | $42.00 |",
  "creditsUsed": 4,
  "resultExpiresAt": "2026-04-10T15:30:00Z"
}

HTTP mode keeps the markdown inline because remote clients have no local disk — there's no savedTo path they could read back. Images in the markdown are uploaded to server-side storage and referenced as frenchie-result: keys; fetch them with fetch_result_file.

Response (processing, both modes):

{
  "status": "processing",
  "jobId": "fr_job_29xk",
  "estimatedCompletion": "2026-04-10T15:02:30Z"
}

transcribe_to_markdown

Converts audio or video to a Markdown transcript.

Parameters:

ParameterTypeRequiredDescription
file_pathstringYes*Local path to the file
uploaded_file_referencestringYes*Reference to an already-uploaded file
api_keystringNoOverride the env API key for this request

* One of file_path or uploaded_file_reference is required.

Supported file types:

Audio:  audio/mpeg  audio/mp3  audio/m4a  audio/wav  audio/x-wav  audio/wave  audio/mp4  audio/webm
Video:  video/mp4  video/quicktime (MOV)  video/webm

Credits: 2 per minute (rounded up).

Routing: Determined by duration + file size. Short clips may resolve sync. Longer files go async — chunked and reassembled automatically.

Response format: Same as ocr_to_markdown.

generate_image

Generates a single image from a text prompt using gpt-image-2.

Parameters:

ParameterTypeRequiredDescription
promptstringYesPlain-language description of the image to generate
stylestringNoFree-text style direction; merged into the provider prompt by Frenchie
sizeenumNo1024x1024, 1536x1024, 1024x1536, auto
qualityenumNolow, medium, high, auto
formatenumNopng (default), jpeg, webp
backgroundenumNotransparent, opaque, auto (transparent rejected with jpeg)
api_keystringNoOverride the env API key for this request

Credits: 20 per image, refunded automatically on failure.

Limits: 50 images per hour, 250 images per day per user. v1 generates one image per call — call again for additional variants.

Response (done — stdio mode):

{
  "status": "done",
  "jobId": "fr_job_img_29xk",
  "creditsUsed": 20,
  "resultExpiresAt": "2026-04-23T15:30:00Z",
  "result": {
    "kind": "image",
    "format": "png",
    "mimeType": "image/png",
    "size": "1024x1024",
    "savedTo": ".frenchie/ramen-poster/generated.png"
  }
}

Stdio mode auto-downloads the image and writes it to result.savedTo next to your work. Tell the user the relative path; the file is already on disk.

Response metadata:

FieldModeDescription
result.savedTostdioRelative path to the generated image saved in the agent workspace
result.imageUrlHTTPShort-lived URL for the generated image
creditsUsedbothCredits charged for the generation
resultExpiresAtbothWhen the result payload expires

Response (done — HTTP mode):

{
  "status": "done",
  "jobId": "fr_job_img_29xk",
  "creditsUsed": 20,
  "resultExpiresAt": "2026-04-23T15:30:00Z",
  "result": {
    "kind": "image",
    "format": "png",
    "mimeType": "image/png",
    "size": "1024x1024",
    "imageUrl": "https://minio.getfrenchie.dev/...?signed=true"
  }
}

HTTP mode returns a presigned URL that expires in 30 minutes. Download the image to the user's machine (or render it inline) before the URL expires; the underlying object is deleted shortly after.

Missing prompts, insufficient credits, and provider failures use the standard MCP error envelope in the Errors section below.

get_job_result

Retrieves the result of an async job.

Most of the time you don't need to call this directly — the MCP server auto-polls for up to 90 seconds after submitting a job. You only need get_job_result if the auto-poll timed out and returned a "processing" status.

Parameters:

ParameterTypeRequiredDescription
job_idstringYesThe job ID from a previous async response
api_keystringNoOverride the env API key for this request

Response shape is the same as whichever tool submitted the job (see ocr_to_markdown above) — stdio returns metadata with savedTo, HTTP inlines markdown.

Response (done — stdio mode):

{
  "status": "done",
  "savedTo": ".frenchie/meeting/result.md",
  "wordCount": 4821,
  "imageCount": 0,
  "creditsUsed": 96,
  "resultExpiresAt": "2026-04-10T15:30:00Z"
}

Response (done — HTTP mode):

{
  "status": "done",
  "markdown": "...",
  "creditsUsed": 96,
  "resultExpiresAt": "2026-04-10T15:30:00Z"
}

Response (still processing):

{
  "status": "processing",
  "jobId": "fr_job_29xk",
  "estimatedCompletion": "2026-04-10T15:02:30Z"
}

Sync and async routing

You don't pick sync or async — Frenchie does.

Small files (single-page PDFs, short clips) resolve sync — the result comes back in the same request.

Larger files go async:

  1. Frenchie returns a jobId immediately
  2. The MCP server auto-polls every 3 seconds for up to 90 seconds
  3. If the job finishes within that window, you get the result back transparently
  4. If it doesn't, you get { "status": "processing", "jobId": "..." } — call get_job_result later

For most files, the auto-poll handles everything. Your agent doesn't need to know or care about the difference.

Hand-drawn flow diagram: top row shows the sync path (agent → Frenchie → result, fast). Bottom row shows the async path (agent → Frenchie → jobId → auto-poll clock → result, with a dashed branch from auto-poll to a fallback timeout state for the agent to call get_job_result later).

Supported files

OCR (→ Markdown):

TypeMIME
PDFapplication/pdf
PNGimage/png
JPEGimage/jpeg
WebPimage/webp

Transcription (→ Markdown):

TypeMIME
MP3audio/mpeg, audio/mp3
M4Aaudio/m4a
WAVaudio/wav, audio/x-wav, audio/wave
Audio MP4audio/mp4
Audio WebMaudio/webm
MP4 videovideo/mp4
MOVvideo/quicktime
WebM videovideo/webm

Image generation (text prompt → image):

Output formatMIME
PNG (default)image/png
JPEGimage/jpeg
WebPimage/webp

Image generation takes a text prompt instead of a file upload. Sizes: 1024x1024, 1536x1024, 1024x1536, or auto.

Limits:

LimitValue
Max file size2 GB
Max concurrent jobs5 per user

If you send an unsupported type, you'll get a 400 with "Unsupported file type for [filename]".

Credits

Everything runs on credits. No subscriptions, no monthly fees.

ActionCost
OCR1 credit per page ($0.01)
Transcription2 credits per minute, rounded up ($0.02)
Image generation20 credits per image ($0.20)

$1 = 100 credits. That gets you 100 OCR pages, 50 minutes of transcription, or 5 generated images. New accounts start with 100 free credits. Failed jobs are refunded automatically.

Credit packs:

PackPricePer-credit
100 credits$1$0.010
500 credits$5$0.010
2,000 credits$20$0.010
10,000 credits$100$0.010

First-time email signups get 100 free credits, once per email. No card required. Credits don't expire.

If your balance is too low for a job, the request fails with a 402:

{
  "isError": true,
  "content": [{ "type": "text", "text": "Insufficient credits" }]
}

The response also includes your current balance and the required amount, so your agent (or you) knows exactly how many credits to top up.

Rate limits

Generous enough that you probably won't hit them. But here they are.

LimitValue
Requests per minute60
Concurrent jobs per user5
OCR pages per hour500
Transcription minutes per hour120
Image generations per hour50
Image generations per day250
Credits per day5,000

If you exceed a limit, you'll get a 422 with details on what you hit and when it resets.

For most users, these limits are invisible. If you're consistently hitting them, reach out — we want to hear about your use case.

Result expiry

Results are available for 30 minutes after first delivery. After that, Markdown content or generated-image URLs are deleted and the API returns 410 Gone.

{
  "isError": true,
  "content": [{ "type": "text", "text": "Job result has expired and is no longer available" }]
}

The job record stays in the system (for your usage history), but the actual content is gone. If you need the result again, re-submit the file or prompt.

We don't store your files or results longer than necessary. That's the point.

Errors

When something goes wrong, Frenchie returns a standard MCP error:

{
  "isError": true,
  "content": [{ "type": "text", "text": "<error message>" }]
}

Here's what you might see:

HTTPConditionMessage
400Unsupported file type or bad payload"Unsupported file type for [filename]"
402Not enough credits"Insufficient credits" + required/current balance
408More than 5 concurrent jobs"Concurrent job limit exceeded"
410Result expired (>30 min)"Job result has expired and is no longer available"
422Rate limit exceededError + quota details
500Processing failed"Frenchie job failed" + error details

Most errors are self-explanatory. If you hit a 500, it's on us — retry once, and if it persists, let us know at support@getfrenchie.dev.

API key

Your API key is created when you sign up. Find it on your dashboard.

Format: fr_ followed by 32 hex characters.

fr_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4

Two ways to authenticate:

  1. Environment variable (recommended): Set FRENCHIE_API_KEY in your MCP config. The server reads it on startup.
  2. Per-request parameter: Pass api_key in any tool call. This overrides the env key for that specific request — useful if you're managing multiple accounts.

Your key is hashed (SHA-256) before storage. We never store it in plaintext.

If your key is compromised, revoke it from the dashboard and generate a new one. Active jobs will finish, but new requests with the old key will be rejected.

Upgrading from an older Frenchie

Frenchie 0.3.0 ships three changes that affect existing installs: stdio tool responses are now metadata-only (markdown stays on disk), MCP configs use absolute npx paths so GUI agents work, and mcp --help / --version / --selftest now short-circuit instead of hanging.

If you're on 0.2.x

Re-run install. That's it.

cd <your project>
npx @lab94/frenchie@latest install --api-key fr_your_key_here

Restart your agent fully (not a soft reload) — MCP subprocesses persist across reloads on some agents.

If you're on 0.1.x (HTTP-primary)

0.2.0 switched the primary integration path from HTTP to stdio. The old HTTP entry at user or local scope will shadow the new project stdio entry — you have to remove it first:

Claude Code:

claude mcp list                      # check scope
claude mcp remove frenchie -s local  # or -s user / -s project as needed

Cursor:

Edit ~/.cursor/mcp.json and remove the frenchie block that has a url field.

Codex:

Edit ~/.codex/config.toml and remove any [mcp_servers.frenchie] block with url = "...".

Then re-run install and restart your agent. Verify with claude mcp list (or equivalent) that the entry now shows a command: "/.../npx" rather than a URL.

For the full upgrade guide with every version gap (including 0.3.0 → 0.3.1 critical pin fix and 0.3.1 → 0.3.2 API key reuse), see the migration guide.

FAQ

My agent says "Frenchie tool not found" — what's wrong?

Your MCP server probably isn't connected yet. If you used npx @lab94/frenchie install, restart your agent — that picks up the new config. If you set up HTTP manually, check that the snippet is in the right file for your tool, the API key is correct, and the agent has been restarted.

Can I use Frenchie without MCP? Like a REST API?

Frenchie is designed MCP-first. Local coding agents run the server over stdio via npx @lab94/frenchie install. Hosted/web agents connect to https://mcp.getfrenchie.dev over HTTP. The skill pack helps Tier-A agents (Claude Code, Cursor, Codex, Antigravity, Claude Desktop) use both paths cleanly. We do not position Frenchie as a general-purpose REST wrapper.

How do I check my credit balance?

Log into your dashboard at getfrenchie.dev/dashboard. Your balance and usage history are on the main page. Or use the /frenchie-status slash command directly in your agent.

I sent a large PDF and got a "processing" status. Now what?

Wait a bit and call get_job_result with the jobId. The MCP server auto-polls for 90 seconds, so if you got processing back, the job is taking longer than usual. Most large files finish within 5 minutes.

Can I parse a password-protected PDF?

No. Remove the password first, then send it through. We can't unlock files on your behalf.

My OCR result has weird formatting. What gives?

OCR quality depends on the source. Clean digital PDFs produce near-perfect Markdown. Scanned documents, handwriting, and low-res images are best-effort — usually good, occasionally imperfect. If something looks consistently wrong, let us know.

Do you support [language X] for transcription?

Transcription handles most major languages automatically. We don't require you to specify a language — it's detected from the audio.

I'm hitting rate limits. Can you increase them?

Reach out at support@getfrenchie.dev with your use case. We're happy to discuss higher limits for legitimate workloads.