Skip to content

CraftMyPDF MCP by usefulapi

by usefulapi.io · remote · no sign-in to list tools · v1.3.4 · published by io.usefulapi

Generate PDFs and images from CraftMyPDF templates; read templates, versions and usage.

Deletes · 4

11 tools: 4 can delete or cancel things and 7 only read.

Scanned Oct 22, 2026

No check matched anything in the tool definitions. No finding is not a safety guarantee. How the checks work.

claude mcp add --transport http craftmypdf https://craftmypdf.usefulapi.io/mcp

Tools

Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.

11 tools

Deletes or cancels 4Claude Code: deny
  • craftmypdf_create_imageWRITE: uses the CraftMyPDF account's own quota (credits; a successful generation is a billable transaction, typically 1 credit per document, and every call counts even with identic…Reads text others writeNo findings

    Why it is in this group

    • The name "craftmypdf_create_image" says "create": a word for a change.
    • The server marks it destructive (destructiveHint: true).

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    WRITE: uses the CraftMyPDF account's own quota (credits; a successful generation is a billable transaction, typically 1 credit per document, and every call counts even with identical data). Generate ONE image (JPEG or PNG) from a template and your JSON data. Returns a hosted file URL (never file bytes) that expires after `expiration` minutes. POST /create-image with export_type=json.

    Annotations the server declares

    • title: Create image from template
    • readOnlyHint: false
    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: true
  • craftmypdf_create_pdfWRITE: uses the CraftMyPDF account's own quota (credits; a successful generation is a billable transaction, typically 1 credit per document, and every call counts even with identic…Reads text others writeNo findings

    Why it is in this group

    • The name "craftmypdf_create_pdf" says "create": a word for a change.
    • The server marks it destructive (destructiveHint: true).

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    WRITE: uses the CraftMyPDF account's own quota (credits; a successful generation is a billable transaction, typically 1 credit per document, and every call counts even with identical data). Generate ONE PDF from a template and your JSON data. Returns a hosted file URL (never file bytes) that expires after `expiration` minutes, plus the transaction reference and any anchors (page numbers for a table of contents). Look the template up with craftmypdf_list_templates / craftmypdf_get_template first. POST /create with export_type=json.

    Annotations the server declares

    • title: Create PDF from template
    • readOnlyHint: false
    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: true
  • craftmypdf_create_pdf_from_templatesWRITE: uses the CraftMyPDF account's own quota (credits; a successful generation is a billable transaction, typically 1 credit per document, and every call counts even with identic…Reads text others writeNo findings

    Why it is in this group

    • The name "craftmypdf_create_pdf_from_templates" says "create": a word for a change.
    • The server marks it destructive (destructiveHint: true).

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    WRITE: uses the CraftMyPDF account's own quota (credits; a successful generation is a billable transaction, typically 1 credit per document, and every call counts even with identical data). Generate ONE combined PDF from 2-10 templates, each with its own data (or the shared `data`). Costs credits for each template rendered. Returns a hosted file URL that expires after `expiration` minutes. Uses the latest template versions. POST /create-merge with export_type=json.

    Annotations the server declares

    • title: Create one PDF from several templates
    • readOnlyHint: false
    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: true
  • craftmypdf_merge_pdfsWRITE: uses the CraftMyPDF account's own quota (credits; a successful generation is a billable transaction, typically 1 credit per document, and every call counts even with identic…Reads text others writeNo findings

    Why it is in this group

    • The name "craftmypdf_merge_pdfs" says "merge": a word for a change that another call does not undo.
    • The server marks it destructive (destructiveHint: true).

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    WRITE: uses the CraftMyPDF account's own quota (credits; a successful generation is a billable transaction, typically 1 credit per document, and every call counts even with identical data). Merge 2-10 existing PDFs, given as public https URLs, into ONE PDF. CraftMyPDF downloads the files from your URLs. Returns a hosted file URL that expires after `expiration` minutes. POST /merge-pdfs.

    Annotations the server declares

    • title: Merge PDFs by URL
    • readOnlyHint: false
    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: true
Only reads 7Claude Code: allow, ask for 1 outbound
  • craftmypdf_get_account_infoThe CraftMyPDF account behind the API key: username, quota used (quota_counter) and quota total (quota_max), template count and limit, creation date.Reads text others writeNo findings

    Why it is in this group

    • The name "craftmypdf_get_account_info" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    The CraftMyPDF account behind the API key: username, quota used (quota_counter) and quota total (quota_max), template count and limit, creation date. Check the quota before generating many documents. GET /get-account-info.

    Annotations the server declares

    • title: Get account info
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • craftmypdf_get_pdf_infoMetadata of a PDF that CraftMyPDF downloads from a public https URL: page count, title, author, creator, producer, dates.Reads text others writeCan send data outNo findings

    Why it is in this group

    • The name "craftmypdf_get_pdf_info" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    • untrusted-inputThe description's first sentence says "http": it reads web pages, which anyone can write.
    • untrusted-inputThe input takes a URL (input.url), and the tool reads it: it reads web pages, which anyone can write.
    • outboundThe input takes a URL (input.url): a request to a URL can carry data to whoever runs it.

    Claude Code: ask, because it is tagged outbound.

    Description, as the server wrote it
    Metadata of a PDF that CraftMyPDF downloads from a public https URL: page count, title, author, creator, producer, dates. May count against the account's rate limit. GET /get-pdf-info.

    Annotations the server declares

    • title: Get PDF info
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • craftmypdf_get_templateOne template: its name and the sample JSON data it expects (the placeholders to fill when generating).Reads text others writeNo findings

    Why it is in this group

    • The name "craftmypdf_get_template" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    One template: its name and the sample JSON data it expects (the placeholders to fill when generating). The full layout body is only returned with include_body (it can be very large and is cut). GET /get-template.

    Annotations the server declares

    • title: Get template
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • craftmypdf_list_template_versionsThe saved versions of a template (version number, description, time, whether it is retained).Reads text others writeNo findings

    Why it is in this group

    • The name "craftmypdf_list_template_versions" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    The saved versions of a template (version number, description, time, whether it is retained). Use a version number when generating to pin the layout. GET /list-template-versions.

    Annotations the server declares

    • title: List template versions
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • craftmypdf_list_templatesList the PDF/image templates of the account: template_id, name, status, group, created and updated time.Reads text others writeNo findings

    Why it is in this group

    • The name "craftmypdf_list_templates" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    List the PDF/image templates of the account: template_id, name, status, group, created and updated time. The template_id is what the generation tools need. Read only; templates cannot be edited here. GET /list-templates.

    Annotations the server declares

    • title: List templates
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • craftmypdf_list_transactionsRecent generation transactions of the account, newest first: transaction_ref, type (PDFGEN, PDFPREVIEW, ...), execution time, credits used, time, file size and result status.Reads private dataReads text others writeNo findings

    Why it is in this group

    • The name "craftmypdf_list_transactions" says "list": a word for reading.

    What it can reach

    • private-dataThe description's first sentence says "file": it reads files.
    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    Recent generation transactions of the account, newest first: transaction_ref, type (PDFGEN, PDFPREVIEW, ...), execution time, credits used, time, file size and result status. Use it to see what was billed. GET /list-transactions.

    Annotations the server declares

    • title: List transactions
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • craftmypdf_query_template_usageUsage statistics (how many generations) of up to 20 templates within an optional date range.Reads text others writeNo findings

    Why it is in this group

    • The name "craftmypdf_query_template_usage" says "query": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    Usage statistics (how many generations) of up to 20 templates within an optional date range. Dates are ISO 8601 UTC date-times such as 2026-10-01T00:00:00Z. GET /query-template-usage.

    Annotations the server declares

    • title: Query template usage
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Exfil surface

Which tools read private data, which read text someone else can write, and which can send data out. One of each is a path a prompt injection can use.

11 paths in this server alone from private data, through text someone else wrote, to a way out. Denying 1 outbound tool breaks every one.

Reads private data1
Reads files, mail, messages, databases, secrets, calendars or repositories.
Can send data out1
Can carry data to people or systems: it sends, posts or publishes, or takes a recipient, channel or URL.
deny to break every path
{
  "permissions": {
    "deny": [
      "mcp__craftmypdf__craftmypdf_get_pdf_info"
    ]
  }
}

Other servers in the same agent add their own tools to these paths. Audit your whole setup to see them together.

Remote posture

What anyone on the internet sees at the remote endpoint: an anonymous initialize and tools/list, and the public OAuth metadata.

Looked at Oct 22, 2026, 15:26 UTC, unchanged since Oct 22, 2026. No credentials were sent and no tool was called. What is looked at.

Reachable
yes
HTTP status of an anonymous initialize
200
tools/list served without credentials
yes
Tools that change things, listed without credentials
4
Protocol version
2025-06-18
WWW-Authenticate on 401
not observed
resource_metadata in WWW-Authenticate
none
RFC 9728 protected resource metadata
https://craftmypdf.usefulapi.io/.well-known/oauth-protected-resource/mcp
Authorization servers
https://craftmypdf.usefulapi.io
Legacy HTTP+SSE transport
no
Dynamic client registration
yes
Client ID metadata documents
no
  • HighThe whole server

    The endpoint served tools/list without credentials, and the list has 4 tools that change things (4 destructive). Whether a call also works without credentials was not tested: tools are never called.

    Matched text

    https://craftmypdf.usefulapi.io/mcp: tools/list returned 11 tools to an anonymous client, including craftmypdf_create_pdf (destructive), craftmypdf_create_image (destructive), craftmypdf_create_pdf_from_templates (destructive), craftmypdf_merge_pdfs (destructive)

    What this check looks for

Install

Pinned to version 1.3.4. Values in angle brackets are yours to fill in.

claude mcp add --transport http craftmypdf https://craftmypdf.usefulapi.io/mcp

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change or a way out, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__craftmypdf__craftmypdf_get_account_info",
      "mcp__craftmypdf__craftmypdf_list_transactions",
      "mcp__craftmypdf__craftmypdf_list_templates",
      "mcp__craftmypdf__craftmypdf_get_template",
      "mcp__craftmypdf__craftmypdf_list_template_versions",
      "mcp__craftmypdf__craftmypdf_query_template_usage"
    ],
    "ask": [
      "mcp__craftmypdf__craftmypdf_get_pdf_info"
    ],
    "deny": [
      "mcp__craftmypdf__craftmypdf_create_pdf",
      "mcp__craftmypdf__craftmypdf_create_image",
      "mcp__craftmypdf__craftmypdf_create_pdf_from_templates",
      "mcp__craftmypdf__craftmypdf_merge_pdfs"
    ]
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. A read that can send data out (it takes a URL, say) asks first too. It assumes the server is installed as craftmypdf. Review it before you use it.

Capability tags behind 11 rules
  • mcp__craftmypdf__craftmypdf_get_account_info untrusted-input
  • mcp__craftmypdf__craftmypdf_list_transactions private-data, untrusted-input
  • mcp__craftmypdf__craftmypdf_list_templates untrusted-input
  • mcp__craftmypdf__craftmypdf_get_template untrusted-input
  • mcp__craftmypdf__craftmypdf_list_template_versions untrusted-input
  • mcp__craftmypdf__craftmypdf_query_template_usage untrusted-input
  • mcp__craftmypdf__craftmypdf_get_pdf_info untrusted-input, outbound
  • mcp__craftmypdf__craftmypdf_create_pdf untrusted-input
  • mcp__craftmypdf__craftmypdf_create_image untrusted-input
  • mcp__craftmypdf__craftmypdf_create_pdf_from_templates untrusted-input
  • mcp__craftmypdf__craftmypdf_merge_pdfs untrusted-input