@korala/mcp
You probably do not need to install this. Point your assistant at
https://api.korala.ai/mcp and sign in to Korala. This package is the same
server as a local program, for the few places where nobody can sign in.
Model Context Protocol server for Korala. An AI assistant
(Claude, ChatGPT, Claude Code, Codex, Cursor, Copilot, Gemini CLI, Grok,
Antigravity and other MCP clients) can draft agreements,
create documents for the signers you name, place their fields, send them and
track signing.
The assistant prepares and you stay the sender. It cannot sign for anyone, and
it sends or voids only after you turn that on. Tool results leave out signer
access tokens, the credential a signing link carries.
Connect by signing in (recommended)
Korala hosts this server at https://api.korala.ai/mcp. You sign in to Korala
in your browser and choose what the assistant may do. There is nothing to
install, no secret in a config file, and you disconnect it in Korala under
Settings → AI Assistants.
claude mcp add --transport http korala https://api.korala.ai/mcp
codex mcp add korala --url https://api.korala.ai/mcp
gemini mcp add --transport http korala https://api.korala.ai/mcp
grok mcp add -s user korala https://api.korala.ai/mcp
agy mcp add korala https://api.korala.ai/mcp
Codex drops a server that is still connecting from a turn's tools, and Korala
takes about two seconds to connect. Add required = true under
[mcp_servers.korala] in ~/.codex/config.toml.
Cursor (~/.cursor/mcp.json); VS Code and the rest are in the guides below:
{ "mcpServers": { "korala": { "url": "https://api.korala.ai/mcp" } } }
In Claude and ChatGPT, add a custom connector with the same address. Guides
for each assistant: https://docs.korala.ai/ai-agents.
Try it
Draft a one-page mutual NDA between Acme Inc. and Anna Miller
(anna@example.com), show me what it needs, save it as a template and create
the document. Don't send it yet.
Tools
create_draft_link | "Open in Korala" link for a Markdown draft. Needs no account and no sign-in. The local program started with no API key offers this tool alone |
list_templates, get_template | Find and inspect reusable templates. A long form's fields come back summarized, 60 to a page (fieldPage, fieldCount, nextFieldPage); fieldDetail: "full" gives every column, 20 to a page |
preview_markdown_template | Render a Markdown agreement without saving: pages, variables, signature roles |
create_markdown_template | Save a Markdown agreement as a template |
create_document_from_template | Create a draft for the signers you name, matched to the template's roles, with the data that fills it |
add_template_field, update_template_field, remove_template_field | Build a template's fields: by coordinates, against text the generated document contains, or at a Word bookmark |
request_pdf_upload | For a chat that cannot send a file: an empty draft and a Korala link where the user uploads the PDF |
upload_attached_pdf | A PDF attached in ChatGPT becomes a draft (ChatGPT passes attachments to tools as a download link) |
create_upload_url, confirm_upload | Upload an existing PDF (agents that can make HTTP requests with local files). confirm_upload reports what is in the file and how its fields can be placed |
get_form_fields | Where a fillable PDF's own fields are, so a signature lands on the right line |
import_form_fields | The fields a fillable PDF declares, placed for one signer in one call. Skips what an earlier import placed |
update_field, remove_field | Correct a field that landed in the wrong place, instead of uploading again |
remove_signer | Take a signer, and their fields, off a draft: one added by mistake or left from an earlier attempt |
update_signer | Rename a signer or change when they sign, on a draft |
view_page | A page as an image, with rulers in field coordinates and the placed fields outlined: for scans, and to check a placement |
read_text | What an uploaded PDF says, a run of pages at a time, for a document the assistant has not seen |
find_text | Where a phrase sits in a flat PDF, with the line around it and every page's size |
add_field_at_text | A field placed against that phrase ("right of", "above", "below"); Korala works out the coordinates |
add_signer, add_field | Recipients, and fields at exact coordinates, for uploaded PDFs |
find_blanks | Where the page is waiting to be filled in: ruled lines and labelled blanks, with the label beside each. It does not decide what they are for; the assistant reading it can |
add_fields | Many fields in one call, each reported on its own so one bad entry does not cost the rest |
fill_fields | Writes the answers into the fields, so the person is left with the signature. Works on a draft and on a document already out for signature, but not once the signer it belongs to has signed; a signature or initials field is refused. The answer lists what is still unfilled |
prepare_for_signature | One signer, one free place to sign: it places that. Anything else it hands back rather than guess whose line is whose |
send_document | Send to signers, only if you allowed sending (the "Send and void documents" permission at sign-in, or KORALA_MCP_ALLOW_SEND=true with a key); otherwise returns a review link |
list_documents, get_document, get_audit_trail | Track status, who has signed, and history. get_document pages its fields the same way get_template does |
void_document | Cancel a sent document, under the same permission; otherwise returns a review link |
Fields come in six types (signature, initials, date, text, checkbox and
dropdown), and every tool that builds one takes the full set of properties:
choices for a dropdown, an input mask, a validation pattern, a date format,
the font and colour, checkbox groups, a condition that makes the field
required, and the link to a fillable PDF's own form field. The full list:
https://docs.korala.ai/ai-agents/tools#field-properties
Markdown template syntax: https://docs.korala.ai/guides/markdown-templates
Running it locally with an API key
An API key is needed only where there is no person to approve a sign-in:
- a CI job, a server or a script that creates documents unattended;
- the Claude Desktop extension (
korala.mcpb), which runs this program;
- your own backend, embedding the server (below).
Create a key in Korala under Settings → API Keys, and start with a
test-mode key: its documents are unbilled, send no email and carry a TEST
watermark, with 10 sends and 10 documents from templates per billing period.
A test-mode key can still open and send live documents by id (known gap), so
treat any key as able to reach live documents.
{
"mcpServers": {
"korala-local": {
"command": "npx",
"args": ["-y", "@korala/mcp"],
"env": {
"KORALA_API_KEY_ID": "your-key-id",
"KORALA_API_SECRET": "your-secret"
}
}
}
}
KORALA_API_KEY_ID | required for everything but draft links | Key ID |
KORALA_API_SECRET | required for everything but draft links | Key secret |
KORALA_MCP_ALLOW_SEND | optional, default false | true lets the assistant send documents to signers and void them. When false, it gives you a link to review and act in Korala instead. |
KORALA_API_URL | optional | Defaults to https://api.korala.ai/api/v1 |
KORALA_WEB_URL | optional | Defaults to https://korala.ai; used for review links |
The same setup for Claude Code and Codex, and the draft-only mode:
https://docs.korala.ai/ai-agents/api-key. From a checkout of this
repository, build with pnpm --filter @korala/mcp... build and run
node packages/mcp/dist/bin.js.
Embedding
import { KoralaClient } from '@korala/api-client';
import { createKoralaMcpServer } from '@korala/mcp';
const server = createKoralaMcpServer(new KoralaClient({ apiKeyId, apiSecret }), {
allowSend: false,
});
await server.connect(transport);