{
  "name": "pdfwithlove",
  "site": "https://pdfwithlove.netlify.app",
  "description": "PDF and image tools that run entirely in the browser. No API, no upload, no account - the tools are registered in the page itself.",
  "registration": {
    "webmcp": "navigator.modelContext (provideContext, or registerTool)",
    "fallback": "window.__pdfwithlove",
    "fallbackUsage": "await window.__pdfwithlove.call('<tool>', { ...args })"
  },
  "typicalFlow": [
    "list_tools",
    "describe_tool",
    "open_file_picker",
    "run",
    "save_result"
  ],
  "operations": {
    "total": 63,
    "runnable": 60,
    "uiOnly": {
      "edit_pdf": "Placing text, images and shapes is a direct-manipulation canvas - open the tool page and drive it through the DOM.",
      "sign_pdf": "A signature is drawn or placed by hand on the page. Open the tool page to do it through the DOM.",
      "scan_to_pdf": "Needs the device camera. Open the tool page on a phone, or use images_to_pdf with photos you already have."
    },
    "ids": [
      "merge",
      "split",
      "organize_pages",
      "rotate",
      "extract_pages",
      "delete_pages",
      "compress",
      "flatten_pdf",
      "repair_pdf",
      "pdf_to_pdfa",
      "pdf_to_word",
      "pdf_to_excel",
      "pdf_to_ppt",
      "pdf_to_markdown",
      "word_to_pdf",
      "excel_to_pdf",
      "images_to_pdf",
      "html_to_pdf",
      "pdf_to_image",
      "ocr_pdf",
      "edit_pdf",
      "sign_pdf",
      "watermark",
      "page_numbers",
      "pdf_metadata",
      "redact_pdf",
      "pdf_forms",
      "compare_pdf",
      "protect_pdf",
      "unlock_pdf",
      "crop_pdf",
      "pdf_color_convert",
      "pdf_to_text",
      "text_to_pdf",
      "markdown_to_pdf",
      "extract_images",
      "create_pdf",
      "pages_per_sheet",
      "change_page_size",
      "halve_pages",
      "overlay_pdf",
      "viewer_prefs",
      "remove_metadata",
      "pdf_to_html",
      "pdf_to_epub",
      "svg_to_pdf",
      "password_generator",
      "bookmark_pdf",
      "annotate_pdf",
      "scan_to_pdf",
      "compress_image",
      "resize_image",
      "crop_image",
      "convert_to_jpg",
      "convert_from_jpg",
      "photo_editor",
      "upscale_image",
      "remove_background",
      "watermark_image",
      "meme_generator",
      "rotate_image",
      "html_to_image",
      "blur_face"
    ]
  },
  "tools": [
    {
      "name": "pdfwithlove_list_tools",
      "description": "List the PDF and image operations this site can perform, with the id to pass to pdfwithlove_run. Start here. Optionally filter by category or a search term.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string",
            "enum": [
              "Organize",
              "Optimize",
              "Convert",
              "Edit",
              "Security",
              "Image"
            ]
          },
          "query": {
            "type": "string",
            "description": "Free-text filter over titles and descriptions."
          }
        },
        "required": []
      }
    },
    {
      "name": "pdfwithlove_describe_tool",
      "description": "Describe one operation: how many input files it needs, what it accepts, and every option it takes with its default. Call this before pdfwithlove_run rather than guessing option names.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tool": {
            "type": "string",
            "description": "Tool id from pdfwithlove_list_tools, e.g. \"pdf_to_markdown\"."
          }
        },
        "required": [
          "tool"
        ]
      }
    },
    {
      "name": "pdfwithlove_attach_file",
      "description": "Attach a file for the operations to work on, as base64. Suitable for small inputs; for anything over a megabyte or so use pdfwithlove_open_file_picker instead, which takes the file without moving its bytes through this conversation.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Filename including extension - the extension is how engines recognise the format."
          },
          "base64": {
            "type": "string",
            "description": "File contents, base64. A data: URL is also accepted."
          }
        },
        "required": [
          "name",
          "base64"
        ]
      }
    },
    {
      "name": "pdfwithlove_open_file_picker",
      "description": "Open the browser file chooser and attach whatever is selected. This is the efficient way to hand over a real file: call it, then satisfy the file chooser with your browser-automation upload command. Resolves once files are chosen.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "multiple": {
            "type": "boolean",
            "description": "Allow selecting more than one file. Default true."
          }
        },
        "required": []
      }
    },
    {
      "name": "pdfwithlove_list_files",
      "description": "List the files currently attached, with the ids that pdfwithlove_run takes. Pass clear:true to drop them all first.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "clear": {
            "type": "boolean",
            "description": "Remove every attached file. Default false."
          }
        },
        "required": []
      }
    },
    {
      "name": "pdfwithlove_inspect_pdf",
      "description": "Read an attached PDF without changing it: page count, page size, metadata, form fields, and whether it has extractable text or is a scan. Worth calling before choosing page ranges or deciding whether OCR is needed.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "fileId": {
            "type": "string",
            "description": "Which attached file. Defaults to the first one."
          }
        },
        "required": []
      }
    },
    {
      "name": "pdfwithlove_run",
      "description": "Run one operation on the attached files, in this browser. Returns a summary plus any text the operation produced; a resulting file is held in memory for pdfwithlove_get_result or pdfwithlove_save_result. Nothing is uploaded - the work happens locally, so a large document can take a while.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tool": {
            "type": "string",
            "description": "Tool id, e.g. \"merge\", \"compress\", \"pdf_to_markdown\"."
          },
          "options": {
            "type": "object",
            "additionalProperties": true,
            "description": "Operation options. Call pdfwithlove_describe_tool for the exact shape."
          },
          "text": {
            "type": "string",
            "description": "Text input, for the operations that take typed text instead of a file."
          },
          "fileIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Which attached files to use, in order. Defaults to all of them."
          }
        },
        "required": [
          "tool"
        ]
      }
    },
    {
      "name": "pdfwithlove_get_result",
      "description": "Return the last result. Text results come back in full; a file comes back base64, which is expensive - prefer pdfwithlove_save_result unless you genuinely need the bytes in the conversation.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "maxBytes": {
            "type": "number",
            "description": "Refuse a file larger than this rather than flooding the context. Default 750000."
          }
        },
        "required": []
      }
    },
    {
      "name": "pdfwithlove_save_result",
      "description": "Download the last result through the browser, the same way the Download button does. Use this for anything of real size; the file lands wherever the browser saves downloads.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "filename": {
            "type": "string",
            "description": "Override the suggested filename. Optional."
          }
        },
        "required": []
      }
    },
    {
      "name": "pdfwithlove_open_tool",
      "description": "Navigate the visible page to a tool, its directory, or the home page - for when a person is watching, or when you want to finish a job in the on-screen editor. This only changes the view; it runs nothing.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tool": {
            "type": "string",
            "description": "A tool id, or \"all\" for the tool directory, or \"home\"."
          }
        },
        "required": [
          "tool"
        ]
      }
    }
  ]
}