Home / Blog / Generate documents with Claude: MCP and Claude Code

Generate documents with Claude: MCP and Claude Code

Two ways to have Claude produce real documents from your templates: a connector you approve once, and an API key that the proxy attaches without it ever reaching the sandbox.

You have a template, and you would like to say “make this month’s invoice for Acme” and get a file back. There are two ways to let Claude do that with iReceipt PRO. They differ in who holds the credential and who runs the loop.

How they differConnector (MCP)Claude Code with a network secret
WhereA chat in Claude, or Claude CodeClaude Code in the cloud
What Claude callsMCP tools at mcp.ireceipt.proThe REST API, directly or through the SDK, at api.ireceipt.pro
CredentialOAuth: you sign in and approve once. There is no key to pasteAn API key stored on the environment. Claude never sees it
One call makesOne document, returned in the conversationWhatever your code loops over
Reach for it whenYou want one document, or want a template written or fixedIt is a batch, a schedule, or anything that belongs in a script

Both spend the same monthly request allowance as a call you make yourself.

Route 1: the connector

iReceipt PRO runs a remote MCP server at https://mcp.ireceipt.pro/mcp. It uses OAuth 2.1 with dynamic client registration, so the client registers itself and sends your browser to the dashboard. You sign in, see who is asking and for what, and press Allow or Deny. The scopes are:

A client that asks for no scope gets templates:read and templates:render. Administrators have one more, for the public gallery.

Connect it

In claude.ai (custom connectors are on the Free, Pro, Max, Ultra, Team and Enterprise plans): Customize, then Connectors, then + Add, then Add custom connector. Give it a name, paste https://mcp.ireceipt.pro/mcp, and sign in when asked. If the dialog asks which OAuth client to use, choose Register automatically: dynamic client registration is the mode this server implements. On Team and Enterprise an Owner adds it first, under Organization settings, Connectors, Add, Custom, Web. The steps are Anthropic’s, in their help article.

In Claude Code:

claude mcp add --transport http ireceipt https://mcp.ireceipt.pro/mcp
claude mcp login ireceipt

claude mcp login runs the OAuth flow from your shell. The /mcp panel inside a session does the same.

To take access back, open the dashboard’s Agents tab. Each connected agent is listed with its scopes and when it was last used, and Forget revokes the grant and every token issued under it. The agent’s next call is refused and it has to ask for your consent again.

What Claude can do with it

list_templates, get_template, create_template, update_template, delete_template, validate_template, get_template_guide, preview_template and generate_document. The first group is for authoring: Claude can write a template, render a draft of it and look at the picture, and save it only when it is right. generate_document is the one that makes the document itself.

It looks like preview_template, and it is deliberately stricter:

The data is missing 1 value that "invoice" draws, so those places would be
blank in the document:
- customer.name

Add them to variables and call again. If you have checked the document yourself, or a
blank is intended, pass allowMissing: true. Nothing was rendered and nothing was counted against the quota.

A request in plain words is enough: “Generate the invoice template for Acme Trading, INV-2026-0187, three lines.” Claude reads the template with get_template to see which fields it expects, asks you for what is missing, and then calls generate_document.

One call makes one document. For a hundred of them, use the second route and let code do the looping. Know the difference before you do: the REST API and the SDK have no missing-data check. A value your data lacks is rendered as an empty string, so a script that loops should check its data first.

Renders through the connector are also rate-limited, to 60 in a minute by default, so a looping agent cannot spend a month’s allowance in one go.

Route 2: Claude Code in the cloud, with a network secret

A Claude Code session in the cloud runs in an environment. You can store an API key on it as a network secret. Anthropic’s agent proxy adds the key to requests for the hosts you list, after each request has left the session’s VM, so the key is not in an environment variable and not in a file. Claude can call the API without ever seeing it.

Set it up

  1. In the dashboard, create an API token. Make it a dedicated one for this environment, so you can revoke it on its own.
  2. At claude.ai/code, open the environment for editing and select its Network secrets row, then Add secret.
  3. Keep the secret type Bearer. Allowed websites: api.ireceipt.pro. Custom headers: one row. The header name is already Authorization and the prefix Bearer, and the value is the token.
  4. Select Add. The value cannot be viewed again; to change it, delete the secret and add it again.

Network secrets are available on Pro, Max, Ultra, Team and Enterprise plans. On Team and Enterprise without an organization admin role the form is shorter: one host and a token field. Two things in Anthropic’s documentation are worth acting on. The secret applies in every session that runs in the environment, whoever started it, so do not put it on a shared environment unless everyone who uses that environment may generate documents on your allowance. Once saved it cannot be read back, so keep the token in the dashboard, where you can revoke it. Two smaller points from the same page: a host that has a secret stays reachable even when the environment’s network access is restricted, and requests the environment’s setup script makes never get the secret, because the proxy is only attached after the script has run.

Check that it works

Start a session in that environment and ask Claude to call the API with curl. Anthropic’s documentation says the API will answer as if the key were in the request. Note that the command below carries no Authorization header at all. Replace YOUR_TEMPLATE_ID with the id of one of your own private templates; this makes one real request, and with a single field filled in the PDF will be mostly blank:

curl -sS -X POST https://api.ireceipt.pro/v1/pdf/private/YOUR_TEMPLATE_ID \
  -H 'Content-Type: application/json' \
  -d '{"variables":{"invoice":{"number":"INV-2026-0187"}},"size":{"width":796,"height":1126}}' \
  -o invoice.pdf -w '%{http_code}\n'

The success status is 201, not 200, and the body is the PDF. With this curl, a 401 means no key reached the server and a 403 means one did and was not accepted. A 400 “Invalid template name” means the id does not exist among your private templates. The authentication guide and errors and retries go through each status.

From the SDK

npm i @ireceipt.pro/js

The SDK will not run without a key: an empty one throws, and it sends whatever it is given as Authorization: Bearer …. The real key is not in the sandbox, so give it a placeholder and let the proxy set the header on the way out:

Save it as render.mjs (it uses ES modules and top-level await) and run node render.mjs:

import { IReceiptPRO } from '@ireceipt.pro/js';
import { writeFile } from 'node:fs/promises';

// Not a real key. The proxy attaches the one stored on the environment.
const irp = new IReceiptPRO('placeholder');

const pdf = await irp.createPdfFromPrivateTemplate(
  'invoice',
  { invoice: { number: 'INV-2026-0187' } },
  { width: 796, height: 1126 }
);
await writeFile('invoice.pdf', pdf);

The SDK always sends the placeholder, so through it a missing or misconfigured secret does not look like the curl case: the API sees a key it does not know and answers 403 “Token invalid”. A 403 can also mean the monthly allowance is used up or the plan needs an upgrade, so check the dashboard before you debug the secret.

Wrap that in a loop and one session can render a month of invoices. The SDK retries only what a retry could fix (transport errors, 5xx, 408 and 429); a bad template id or a used-up allowance fails on the first attempt.

The page size differs between the two routes. generate_document renders at the template’s own page box. The REST API and the SDK render at A4 portrait, 796 × 1126, unless you pass a size (the REST API also takes a named format; the SDK does not). A landscape certificate saved at 1126 × 796 comes out right in chat and wrong from a script until the script sends its size.

Allowed domains on your account are a browser check (CORS), and a script or curl ignores them, so they do not stand in the way of a cloud session. They are also not a reason to put a key in frontend code; the authentication guide explains why.

Choosing, and taking it back

Use the connector when a person is in the loop: a document now, or a template to write, look at and fix. Use the network secret when code is. Splitting the job is ordinary: author the template in chat with preview_template, then let a cloud session render the month’s documents from a script.

Neither route hands Claude your key. To take the connector back, press Forget on the Agents tab. To take the cloud route back, delete the network secret from the environment and the token in the dashboard.

generate_document and preview_template each count as one request. A document that is refused before rendering — missing data, a template that does not parse, an id that does not exist — costs nothing. A render that fails after it started is refunded.

What we have not verified. We have not clicked through the claude.ai connector dialog for this server from start to finish; the steps above are Anthropic’s. The server implements dynamic client registration (RFC 7591), and we read the dialog’s Register automatically option as that, but we have not tried every option in it. For the SDK placeholder, Anthropic’s public documentation says the proxy “adds the key to requests” for your hosts. We saw a placeholder Authorization header replaced on another host that had a secret, with both curl and the HTTP client the SDK uses, but not on api.ireceipt.pro itself. Run the curl check once before building on it.

Next

Nixie · [email protected]
Updated Nov 8, 2026. AI tools were used in preparing this article.