@formfeed/mcp 0.3.9 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/bin/formfeed-mcp.mjs +30 -29
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @formfeed/mcp
|
|
2
2
|
|
|
3
|
+
[](https://glama.ai/mcp/servers/formfeed-dev/formfeed)
|
|
4
|
+
|
|
3
5
|
Model Context Protocol server for [Formfeed](https://formfeed.dev/?utm_source=npm&utm_content=mcp).
|
|
4
6
|
Gives Claude, Cursor and other agents six tools: `list_templates`, `get_template_schema`,
|
|
5
7
|
`validate_template` (free: the data against the template's schema, ad-hoc HTML offline), `render`, `convert_to_pdf` (Word, Excel,
|
package/bin/formfeed-mcp.mjs
CHANGED
|
@@ -81449,7 +81449,7 @@ var encoder2 = new TextEncoder();
|
|
|
81449
81449
|
// packages/mcp/src/lib/server.ts
|
|
81450
81450
|
import { z as z2 } from "zod";
|
|
81451
81451
|
var CONVERT_LIMIT_BYTES = 20 * 1024 * 1024;
|
|
81452
|
-
var SERVER_INFO = { name: "formfeed", version: "0.3.
|
|
81452
|
+
var SERVER_INFO = { name: "formfeed", version: "0.3.10" };
|
|
81453
81453
|
var READS = { readOnlyHint: true, destructiveHint: false, openWorldHint: false };
|
|
81454
81454
|
var CREATES = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
|
|
81455
81455
|
var engineSchema = z2.enum(["jinja2", "liquid", "handlebars"]);
|
|
@@ -81499,12 +81499,12 @@ function createFormfeedServer(options) {
|
|
|
81499
81499
|
"list_templates",
|
|
81500
81500
|
{
|
|
81501
81501
|
title: "List templates",
|
|
81502
|
-
description: "
|
|
81502
|
+
description: "Lists the templates of the workspace the API key belongs to, most recently changed first: id, slug, name, kind (pdf, image, docx for Word, pptx for PowerPoint), engine, tags and published_version. Call it first to find the slug that get_template_schema, validate_template and render take; skip it when the user already named the template. Returns every match in one answer, without archived templates, and an empty list when nothing matches. A template whose published_version is null has never been published, so render cannot use it yet. Read-only and free.",
|
|
81503
81503
|
inputSchema: {
|
|
81504
|
-
kind: kindSchema.optional(),
|
|
81505
|
-
engine: engineSchema.optional(),
|
|
81506
|
-
tag: z2.string().optional(),
|
|
81507
|
-
q: z2.string().optional().describe("
|
|
81504
|
+
kind: kindSchema.optional().describe("Only templates that produce this kind of document"),
|
|
81505
|
+
engine: engineSchema.optional().describe("Only templates written in this template language"),
|
|
81506
|
+
tag: z2.string().optional().describe("Only templates with this tag; exact match, tags are lowercase with dashes (e.g. billing)"),
|
|
81507
|
+
q: z2.string().optional().describe("Text to find in the name or slug, case-insensitive (e.g. invoice)")
|
|
81508
81508
|
},
|
|
81509
81509
|
annotations: READS
|
|
81510
81510
|
},
|
|
@@ -81521,8 +81521,8 @@ function createFormfeedServer(options) {
|
|
|
81521
81521
|
"get_template_schema",
|
|
81522
81522
|
{
|
|
81523
81523
|
title: "Get the data schema of a template",
|
|
81524
|
-
description: "JSON Schema of the `data` object a template expects
|
|
81525
|
-
inputSchema: { template: z2.string().describe("
|
|
81524
|
+
description: "Returns the JSON Schema of the `data` object a template expects and the sample data it was designed with, from its published version, else its latest draft. Call it after list_templates and before render or validate_template, to build data that fits; ad-hoc html has no stored schema to read. When the template stores no schema, one is inferred from the sample data: treat that as a guide, not a contract. Read-only and free; an unknown slug returns an error.",
|
|
81525
|
+
inputSchema: { template: z2.string().describe("Slug (e.g. invoice) or tpl_ id, as list_templates returns them") },
|
|
81526
81526
|
annotations: READS
|
|
81527
81527
|
},
|
|
81528
81528
|
async ({ template }) => {
|
|
@@ -81542,12 +81542,12 @@ function createFormfeedServer(options) {
|
|
|
81542
81542
|
"validate_template",
|
|
81543
81543
|
{
|
|
81544
81544
|
title: "Validate a template with data",
|
|
81545
|
-
description: "Checks a template
|
|
81545
|
+
description: "Checks a template and its data without rendering: free, no units, nothing stored, no document produced. Call it before render when you assembled the data yourself, or after writing ad-hoc html. With template, the API checks the published version (else the latest) as a render would: syntax, header and footer, errors only this data triggers, and the data against the stored JSON Schema (a wrong type or a missing required field is an error). With html and engine it compiles offline and reports syntax errors, unknown filters and variables missing from data. Returns ok and diagnostics (severity, code, message, plus path, line and column, or part and paragraph for Word and PowerPoint). Warnings leave ok true: settle each before rendering.",
|
|
81546
81546
|
inputSchema: {
|
|
81547
|
-
template: z2.string().optional().describe("
|
|
81548
|
-
html: z2.string().optional().describe("Template source when no
|
|
81549
|
-
engine: engineSchema.optional().describe("
|
|
81550
|
-
data: z2.record(z2.string(), z2.unknown()).optional()
|
|
81547
|
+
template: z2.string().optional().describe("Slug or tpl_ id of a stored template; pass this or html"),
|
|
81548
|
+
html: z2.string().optional().describe("Template source to check offline, when there is no stored template; pass this or template"),
|
|
81549
|
+
engine: engineSchema.optional().describe("Template language of html; required with html"),
|
|
81550
|
+
data: z2.record(z2.string(), z2.unknown()).optional().describe("The data the document will be rendered with, shaped as get_template_schema describes. Left out, a stored template is checked with its sample data")
|
|
81551
81551
|
},
|
|
81552
81552
|
annotations: READS
|
|
81553
81553
|
},
|
|
@@ -81594,18 +81594,18 @@ function createFormfeedServer(options) {
|
|
|
81594
81594
|
"render",
|
|
81595
81595
|
{
|
|
81596
81596
|
title: "Render a document",
|
|
81597
|
-
description: "
|
|
81597
|
+
description: "Creates a document by filling a stored template, or ad-hoc html, with data: a PDF or image, or DOCX, PPTX or PDF from Word and PowerPoint templates. Returns the render with status and download_url. Use it to make a document from data; to turn an existing office file into a PDF, use convert_to_pdf. Stored templates render their published version, so one whose published_version is null fails with template_not_found. Every call is a new render: a live key consumes units, a test key is free (watermarked on the Free plan). A render that fails returns status failed and an error with code and message; validate_template finds most causes beforehand. The link expires at expires_at; get_render issues a fresh one.",
|
|
81598
81598
|
inputSchema: {
|
|
81599
|
-
template: z2.string().optional().describe("
|
|
81600
|
-
html: z2.string().optional().describe("
|
|
81601
|
-
engine: engineSchema.optional().describe("
|
|
81602
|
-
data: z2.record(z2.string(), z2.unknown()).optional(),
|
|
81599
|
+
template: z2.string().optional().describe("Slug or tpl_ id of a stored template; pass this or html"),
|
|
81600
|
+
html: z2.string().optional().describe("A complete HTML document to render instead of a stored template, up to 5 MB"),
|
|
81601
|
+
engine: engineSchema.optional().describe("Template language of html, when it contains expressions to fill from data"),
|
|
81602
|
+
data: z2.record(z2.string(), z2.unknown()).optional().describe("Values for the template, shaped as get_template_schema describes; leave out when it needs none"),
|
|
81603
81603
|
output: outputSchema.optional().describe(
|
|
81604
81604
|
"Left out, the template decides: PDF for PDF templates and html, its image format for image templates, its default output for Word and PowerPoint templates. Word templates render docx or pdf, PowerPoint templates pptx or pdf"
|
|
81605
81605
|
),
|
|
81606
|
-
filename: z2.string().optional(),
|
|
81606
|
+
filename: z2.string().optional().describe("Name of the file behind download_url, e.g. invoice-2026-0042.pdf"),
|
|
81607
81607
|
locale: z2.string().optional().describe("BCP 47 tag for helpers and translations, e.g. de-DE"),
|
|
81608
|
-
wait: z2.boolean().default(true).describe("
|
|
81608
|
+
wait: z2.boolean().default(true).describe("Most renders are finished when the call returns; true also waits for one that continues in the background, false returns it as it is (queued or rendering) to check later with get_render")
|
|
81609
81609
|
},
|
|
81610
81610
|
annotations: CREATES
|
|
81611
81611
|
},
|
|
@@ -81634,20 +81634,21 @@ function createFormfeedServer(options) {
|
|
|
81634
81634
|
{
|
|
81635
81635
|
title: "Convert an office document to PDF",
|
|
81636
81636
|
description: [
|
|
81637
|
-
"Converts
|
|
81637
|
+
"Converts an existing Word, Excel, PowerPoint, OpenDocument, RTF or HTML document (up to 20 MB) to a PDF as it is, without filling in data, and returns the render with status and download_url.",
|
|
81638
|
+
"To make a document from a template and data, use render instead.",
|
|
81638
81639
|
"Pass exactly one source: render_id, the render of a Word or PowerPoint template (output docx or pptx);",
|
|
81639
81640
|
options.localFiles ? "path, a file on this machine; or file_base64 with file_name." : "or file_base64 with file_name, the document itself.",
|
|
81640
|
-
"The document is converted and not kept."
|
|
81641
|
+
"Every call is a new render that counts units like a PDF; the Free plan cannot convert (Starter and above). The document is converted and not kept."
|
|
81641
81642
|
].join(" "),
|
|
81642
81643
|
inputSchema: {
|
|
81643
|
-
render_id: z2.string().optional().describe("rnd_ id of a render whose output is docx or pptx"),
|
|
81644
|
-
...options.localFiles ? { path: z2.string().optional().describe("Absolute path of
|
|
81645
|
-
file_base64: z2.string().optional().describe("The document, base64 encoded"),
|
|
81644
|
+
render_id: z2.string().optional().describe("rnd_ id of a render whose output is docx or pptx, to get that document as a PDF"),
|
|
81645
|
+
...options.localFiles ? { path: z2.string().optional().describe("Absolute path of the document on this machine") } : {},
|
|
81646
|
+
file_base64: z2.string().optional().describe("The document to convert, base64 encoded; needs file_name"),
|
|
81646
81647
|
file_name: z2.string().optional().describe("Name of the document, e.g. report.xlsx; the type is read from the content"),
|
|
81647
|
-
page_ranges: z2.string().regex(/^\d+(-\d+)?(,\d+(-\d+)?)*$/).optional().describe("Pages to convert, e.g. 1-3,5"),
|
|
81648
|
+
page_ranges: z2.string().regex(/^\d+(-\d+)?(,\d+(-\d+)?)*$/).optional().describe("Pages to convert, e.g. 1-3,5; all pages when left out"),
|
|
81648
81649
|
landscape: z2.boolean().optional().describe("Landscape for spreadsheets and documents without their own page setup"),
|
|
81649
81650
|
single_page_sheets: z2.boolean().optional().describe("Each spreadsheet sheet on one page"),
|
|
81650
|
-
filename: z2.string().optional().describe("Name of the PDF")
|
|
81651
|
+
filename: z2.string().optional().describe("Name of the PDF behind download_url, e.g. report.pdf")
|
|
81651
81652
|
},
|
|
81652
81653
|
annotations: CREATES
|
|
81653
81654
|
},
|
|
@@ -81696,8 +81697,8 @@ function createFormfeedServer(options) {
|
|
|
81696
81697
|
"get_render",
|
|
81697
81698
|
{
|
|
81698
81699
|
title: "Get a render",
|
|
81699
|
-
description: "
|
|
81700
|
-
inputSchema: { id: z2.string() },
|
|
81700
|
+
description: "Returns the current state of a render: status (queued, rendering, succeeded or failed), download_url with expires_at, page_count, units and error. Use it to follow a render started with wait false, or to get a fresh link once the old one has expired; render and convert_to_pdf already return this for the render they just made. Read-only and free; an unknown id returns an error.",
|
|
81701
|
+
inputSchema: { id: z2.string().describe("rnd_ id of the render, as render or convert_to_pdf returned it") },
|
|
81701
81702
|
annotations: READS
|
|
81702
81703
|
},
|
|
81703
81704
|
async ({ id }) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formfeed/mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.10",
|
|
4
4
|
"mcpName": "io.github.formfeed-dev/formfeed",
|
|
5
5
|
"description": "Model Context Protocol server for Formfeed: list templates, read data schemas, validate and render documents from AI agents.",
|
|
6
6
|
"license": "MIT",
|