Skip to main content
Glama
pressa-dev

@pressa/mcp

by pressa-dev

@pressa/mcp

MCP (Model Context Protocol) server for Pressa - LaTeX in, publication-quality PDF out. This server lets AI assistants compile documents through a standardized interface.

No API key required to start. Add the server, ask for a PDF, get one. A key raises the limits later.

Setup

Add this to your MCP client configuration (e.g. Claude Desktop, Cursor):

{
  "mcpServers": {
    "pressa": {
      "command": "npx",
      "args": ["-y", "@pressa/mcp"]
    }
  }
}

That is the whole configuration. The server starts in anonymous mode and exposes the compile tool, which works with no credentials: 3 successful compilations per day, and failed attempts do not count against that, so an assistant can iterate on its LaTeX for free.

To unlock the rest, add a key:

{
  "mcpServers": {
    "pressa": {
      "command": "npx",
      "args": ["-y", "@pressa/mcp"],
      "env": {
        "PRESSA_API_KEY": "pressa_your_key_here"
      }
    }
  }
}

Get a free key at pressa.dev. Takes about 30 seconds, no credit card. It raises the limit to 50 compilations per month and registers the template, asset and render tools.

Related MCP server: latexmk-mcp

Hosted server (no install)

The same tools are also served over Streamable HTTP at https://api.pressa.dev/mcp, so a client that supports remote MCP servers needs no Node.js and no local process:

claude mcp add --transport http pressa https://api.pressa.dev/mcp

Keyless, it exposes compile and the public template gallery (list_public_templates, get_public_template, render_public_template). Send an Authorization: Bearer <key> header to register the template, asset and render tools as well.

Environment Variables

Variable

Required

Default

Description

PRESSA_API_KEY

No

-

Pressa API key (starts with pressa_). Without it the server runs in anonymous mode and exposes only compile.

PRESSA_API_URL

No

https://api.pressa.dev

API base URL

Anonymous mode

With no PRESSA_API_KEY set, the server starts anyway rather than refusing to run, and registers exactly one tool: compile. Tools that need an account are not registered at all, because a tool that cannot succeed is worse than an absent one.

Anonymous limits: pdflatex only, up to 3 pages, 30 KB of source, no image assets, and PDF links that expire after 1 hour.

Error handling

Compilation failures return a structured diagnosis rather than a raw TeX log: the error class, the offending command, and a concrete suggested fix (often a missing \usepackage). An assistant is expected to apply the fix and retry on its own instead of showing the user a compiler log.

Tools

compile

Compile LaTeX source code into a PDF.

Input:

Parameter

Type

Required

Description

latex

string

Yes

Complete LaTeX source code. Must contain \documentclass, \begin{document}, \input{}, or \include{}. Plain text, markdown, or raw notes are rejected with not_latex_source (422). The AI agent should generate LaTeX itself, not bounce back to the user.

compiler

string

No

"pdflatex" (default), "xelatex", or "lualatex" (Pro and Business plans only)

Each plan has limits on pages per document, LaTeX source size, PDF output size, and compile timeout. If a compile exceeds your plan's page limit, the document does not count against your monthly quota and the MCP response includes the limit and an upgrade URL. Non-LaTeX input is rejected with a structured requirements list and an example_template so the LLM can self-correct without user intervention.

Output (success):

{
  "job_id": "ffc2bd62-3b67-45d6-be14-b529c4b9489f",
  "pdf_url": "https://api.pressa.dev/api/v1/pdfs/ffc2bd62...?sig=xxx&exp=xxx",
  "expires_at": "2026-04-09T20:44:55Z",
  "pages": 1,
  "compilation_time_ms": 359,
  "usage": {
    "plan": "free",
    "compilations_this_month": 9,
    "monthly_limit": 50
  }
}

Output (error): Compilation log and error line number.

usage

Get current API usage statistics.

Input: None.

Output:

{
  "user": {
    "email": "user@example.com",
    "username": "user",
    "plan": "free"
  },
  "usage": {
    "compilations_this_month": 9,
    "monthly_limit": 50,
    "remaining": 41,
    "resets_at": "2026-04-30T23:59:59Z"
  },
  "api_key": {
    "prefix": "pressa_a",
    "name": "my-key",
    "total_requests": 15,
    "last_used_at": "2026-04-08T20:44:55Z"
  }
}

save_template

Save or update a LaTeX template by name. Paid plans only. Upserts: a second call with the same name overwrites the first.

Parameter

Type

Required

Description

name

string

Yes

Template name (max 100 chars). Unique per user.

latex_content

string

For a new template

Full LaTeX source for the template body. May be omitted when converting the saved source with placeholder_engine: "liquid".

description

string

No

Short human-readable summary (max 500 chars). Shown in list_templates.

instructions

string

No

Agent playbook (prose markdown, max 50000 chars). Describes how to fill the template - defaults, workflow rules, edge cases, conditional logic. Optional but recommended for templates with dynamic parts. See note below.

placeholder_engine

string

No

"liquid": the source contains Liquid placeholders ({{ amount }}) filled by render; on an existing raw LaTeX template this converts it in place (same id, name and instructions). "none": raw LaTeX whose braces only look like placeholders. Omit to keep the template's current kind.

description vs instructions: description is the one-line UI summary ("Standard Toptal monthly invoice"). instructions is the longer playbook your AI agent reads alongside the LaTeX when filling the template ("Ask the user only for total amount; date is today; invoice number format YYYYMMDD-N where N is sequential count for the calendar year; for EU clients add VAT line"). They are different fields.

Raw LaTeX vs placeholder templates: a raw LaTeX template is compiled exactly as saved. A placeholder template is filled with JSON data by render, so the layout never changes. A source containing Liquid placeholders sent without placeholder_engine is refused with liquid_placeholders_in_v1_template, because raw LaTeX would print the braces literally in the PDF. If a placeholder save returns liquid_syntax_error, wrap the literal LaTeX that Liquid misreads (usually a comment right after a brace, \foo{%) in {% raw %}...{% endraw %}.

list_templates

List the user's saved templates. Does not include latex_content or instructions to keep the response small.

Input: None.

Each item in the returned array carries id, name, description, updated_at, latex_size_bytes, and has_instructions (boolean). Use the has_instructions flag to decide whether a follow-up get_template call will return a useful playbook.

get_template

Fetch a single template by ID or name. Returns the full latex_content plus instructions (if any) in one round trip - your agent gets the layout and the playbook together.

Parameter

Type

Required

Description

id_or_name

string

Yes

Numeric ID or URL-safe template name.

delete_template

Delete a template by ID or name.

Parameter

Type

Required

Description

id_or_name

string

Yes

Numeric ID or URL-safe template name.

Development

npm install
npm run build
npm start

License

MIT

Available Tools

1 tool
compileAInspect

Compile LaTeX source into a PDF. Returns a PDF URL, page count and compile time. USE THIS WHEN: you have LaTeX source (or a \documentclass) and no local pdflatex / TeX Live installation to run it with. This is that missing compiler, available over HTTP. Also use it whenever the user asks for a document where typesetting matters - an invoice, contract, report, letter, CV, certificate, or academic paper - since you can write the LaTeX yourself and compile it here. DO NOT USE THIS TO: convert HTML to PDF, merge, split or compress existing PDF files, or extract text from a PDF. This compiles LaTeX source and nothing else. NO API KEY IS CONFIGURED, so this runs on the anonymous tier: pdflatex only, up to 3 pages, no image assets, and a small number of compilations per day. It works right now - use it. If the server reports the daily allowance is used up, tell the user they can get a free key at https://pressa.dev/users/sign_up in about 30 seconds with no credit card, then set PRESSA_API_KEY and restart this server. If a document is over the plan's page or size limit, the response still contains a PDF: preview: true, the first pages the plan allows, total_pages, and plan_required naming the plan that covers the whole document. Show the user the preview and relay warning; never drop pages silently. IMPORTANT: This tool compiles LaTeX, NOT plain text. You (the AI agent) must generate complete, valid LaTeX source yourself before calling this tool. Do not pass user-provided plain text, markdown, JSON, or raw file contents directly - convert them to LaTeX first. Do not ask the user to write LaTeX; that is your job.

A minimal valid document is: \documentclass{article}\begin{document}\end{document}. Always include a documentclass declaration. Always wrap content in \begin{document}...\end{document}. Always escape these characters in body text: % becomes %, & becomes &, $ becomes $, # becomes #, _ becomes _, { becomes {, } becomes }, backslash becomes \textbackslash{}.

IMAGES & BINARY ASSETS: To include images, logos, signatures, or embedded PDFs, pass them in the assets parameter as a map of filename => base64-encoded binary. In your LaTeX source, reference them by the same filename via \includegraphics{filename.png} (remember \usepackage{graphicx}). Example workflow: user uploads a PDF with a company logo; you extract the logo as PNG, base64-encode it, and pass { "logo.png": "iVBORw0KGgo..." } as assets while referencing \includegraphics{logo.png} in the LaTeX.

STORED ASSETS (for reusable brand files): For files the user will reuse across many documents (company logo, signature, letterhead), prefer save_asset once and then use_stored_assets: ["name"] on every future compile, instead of re-encoding the same bytes into assets every time. Ephemeral assets stays the right choice for one-off files extracted from user-provided documents.

If the input is not valid LaTeX, the API returns a not_latex_source error with the exact requirements and an example template. Read that response, fix your LaTeX, and retry. Do not bounce back to the user.

ParametersJSON Schema
NameRequiredDescriptionDefault
latexYesComplete LaTeX source code. Must include \documentclass and a \begin{document}...\end{document} body. Plain text, markdown, raw notes, JSON, or fragments without these markers will be rejected with not_latex_source. If the user gave you non-LaTeX input, convert it to LaTeX yourself before calling.
assetsNoOptional map of filename => base64-encoded binary. Supported formats: PNG, JPG, JPEG, PDF, SVG. Filenames must be plain (no paths, no leading dot, alphanumeric + _-). Each asset is written into the compile workspace so LaTeX can reference it by that exact filename (e.g. \includegraphics{logo.png}). Per-plan limits: Free 2 assets/1MB, Starter 5/5MB, Pro 20/25MB, Business 50/75MB (decoded bytes). Invalid filenames return invalid_asset_filename; mismatched magic bytes return invalid_asset_format; overflowing decoded size returns assets_too_large (413); too many entries returns too_many_assets.
compilerNoLaTeX compiler to use (default: pdflatex). pdflatex and xelatex are available on every plan. lualatex requires Pro or Business; on Free or Starter it returns compiler_not_available.
use_stored_assetsNoNames of assets in the user's persistent library to inject into this compile. Use this instead of re-sending the same bytes in `assets` every time when a file (logo, signature, letterhead) will be reused across many compiles. Save the file once via save_asset, then reference it by name here. Cannot collide with names in the ephemeral `assets` map - asset_name_collision (422) if a name appears in both.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses behaviors: anonymous tier limits (pdflatex only, up to 3 pages, no image assets, daily caps), how over-limit responses behave (preview with total_pages and plan_required), error handling (not_latex_source with retry guidance), and the requirement to convert non-LaTeX input. It also details asset handling and stored-asset workflows, leaving no behavioral ambiguity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very long, spanning multiple paragraphs and sections. While it is structured with headers and front-loaded with the core purpose, it could be condensed without losing critical information. Every sentence adds value, but the overall length is excessive for a tool description, making it less concise than ideal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite lacking an output schema, the description fully covers return values (URL, page count, compile time), error scenarios, limits, and asset handling. It provides complete guidance for invoking the tool correctly, including minimal LaTeX structure, escaping rules, and how to handle image assets. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% (all parameters described in schema), but the description adds substantial meaning beyond the schema. It explains the asset workflow with a concrete example (base64 encoding, filename matching), clarifies when to use stored assets vs ephemeral assets, and elaborates on compiler availability and error conditions. This enriches the agent's understanding of how to use parameters correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool compiles LaTeX source into a PDF and returns a URL, page count, and compile time. It also explicitly lists exclusions (HTML conversion, PDF merging, etc.), reinforcing what it is not for, and differentiates it from any potential alternatives by stating it is a remote compiler for users without local TeX installations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit 'USE THIS WHEN' and 'DO NOT USE THIS TO' sections, specifying when to use the tool (e.g., when the user lacks pdflatex, or when typesetting matters for invoices, contracts, etc.) and when not to use it (HTML-to-PDF, PDF manipulation). It also clarifies that the AI agent should generate LaTeX itself, giving clear usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.7.2
    • First observedcompile

TDQS

A4.7/5.0

Scored across 1 tool

Disambiguation5/5

With only one tool, there is no possibility of confusing it with another. The tool's purpose—compiling LaTeX to PDF—is clearly defined and bounded by explicit do-not-use instructions.

Naming Consistency4/5

The single tool name 'compile' is a clear, conventional verb that matches its action. However, with only one tool there is no larger naming pattern to evaluate, so a small deduction applies for lack of evidence.

Tool Count4/5

One tool is minimal, but the server's scope is intentionally narrow: LaTeX-to-PDF compilation. The single tool earns its place by handling assets, page limits, previews, and error recovery through parameters and response metadata.

Completeness5/5

For the stated domain of compiling LaTeX source into PDFs, the tool covers the full workflow: source input, asset embedding, plan limitations, preview generation, and error remediation. No obvious operations are missing within that scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers