Koskamo

Zovo Page Numbers MCP

Adds page numbers, Bates numbers, or text watermarks to PDF documents. It supports various formats, positions, and styles, including upright text on rotated pages and CSV logging for Bates numbers.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Zovo Page Numbers MCP logo, by ZovoCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-08Published by Zovo
MCP endpoint (Streamable HTTP)
https://page-numbers.zovo.one/mcp
Vendor documentation

What its tools do

3 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

3 of 3 have a description · 3 of 3 declare behavior hints · 3 of 3 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Add page numbers like Page 1 of 12 at bottom center
  • Add Bates numbers starting at ACME000101 with prefix
  • Put a light DRAFT watermark across all pages

Source and maintenance

Community listingRegistry 1.0.0

Protocol and capabilities

Server
page-numbers 1.0.0
MCP protocol negotiated in check
2025-11-25
Tools
3 advertised
Resources
1 advertised
Resource templates
1 advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "resources": {
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Zovo Page Numbers stamps page numbers (stamp_page_numbers), Bates numbers with a CSV log (stamp_bates_numbers), or a text watermark such as DRAFT (stamp_watermark) on an attached PDF and returns a new PDF. Rotated and cropped pages are handled: the text is placed upright inside the visible area. Each output is read again: the stamp text and place are checked on each stamped page, and a second PDF reader (pdf.js) checks all pages up to 300 or a 300-page sample of larger files. Files are processed in memory; the new PDF is kept for 1 hour for download, then deleted.

Tools

3 advertised

stamp_page_numbers — Number PDF pages
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when the user wants to add page numbers to a PDF, number the pages of a PDF, put "Page 1 of 10" in a footer or header, or skip numbering the cover page. Takes one attached PDF, a format with {n} (this page's number) and optional {total} (the last number), one of six positions, start number, pages to skip at the start, font size and margin, and returns a new PDF. Each stamp is checked again in the new file before the link is given. Does not open password-protected PDFs, does not draw non-Latin scripts or emoji, and does not change the page content under the number. Do not use for Bates numbers (use stamp_bates_numbers).

stamp_page_numbers input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "file"
  ],
  "properties": {
    "file": {
      "type": "object",
      "required": [
        "download_url",
        "file_id"
      ],
      "properties": {
        "file_id": {
          "type": "string",
          "description": "ChatGPT file id, e.g. file_abc123."
        },
        "file_name": {
          "type": "string",
          "description": "Original file name if known, e.g. statement.pdf."
        },
        "mime_type": {
          "type": "string",
          "description": "Media type if known, e.g. application/pdf."
        },
        "download_url": {
          "type": "string",
          "description": "Temporary download link for the file, supplied by ChatGPT."
        }
      },
      "description": "The PDF to number, e.g. report.pdf."
    },
    "format": {
      "type": "string",
      "maxLength": 80,
      "description": "Text with {n} and optional {total}, e.g. \"Page {n} of {total}\" (default), \"{n}\", \"{n}/{total}\" or \"- {n} -\"."
    },
    "position": {
      "enum": [
        "top-left",
        "top-center",
        "top-right",
        "bottom-left",
        "bottom-center",
        "bottom-right"
      ],
      "type": "string",
      "description": "Where the text goes on each page as viewed: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right. Default bottom-center."
    },
    "font_size": {
      "type": "number",
      "description": "Font size in points from 6 to 36, e.g. 10 (default)."
    },
    "margin_pt": {
      "type": "number",
      "description": "Distance from the page edge in points from 6 to 144, e.g. 36 (half an inch, default)."
    },
    "skip_first": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991,
      "description": "How many pages at the start get no number, e.g. 1 for a cover page. Default 0."
    },
    "start_number": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991,
      "description": "Number for the first numbered page, e.g. 1 (default)."
    }
  }
}
stamp_page_numbers output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "file",
    "pages",
    "stamped_pages",
    "first_stamp",
    "last_stamp",
    "position",
    "font_size",
    "check",
    "notes",
    "output_name",
    "output_size_kb",
    "expires_in_hours",
    "format",
    "skipped_pages",
    "downloads"
  ],
  "properties": {
    "file": {
      "type": "string"
    },
    "check": {
      "type": "object",
      "required": [
        "passed",
        "what",
        "pages_checked",
        "pages_read_by_pdfjs"
      ],
      "properties": {
        "what": {
          "type": "string"
        },
        "passed": {
          "type": "boolean"
        },
        "pages_checked": {
          "type": "number"
        },
        "pages_read_by_pdfjs": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "pages": {
      "type": "number"
    },
    "format": {
      "type": "string"
    },
    "position": {
      "type": "string"
    },
    "downloads": {
      "type": "object",
      "required": [
        "pdf"
      ],
      "properties": {
        "pdf": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "font_size": {
      "type": "number"
    },
    "last_stamp": {
      "type": "object",
      "required": [
        "page",
        "text"
      ],
      "properties": {
        "page": {
          "type": "number"
        },
        "text": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "first_stamp": {
      "type": "object",
      "required": [
        "page",
        "text"
      ],
      "properties": {
        "page": {
          "type": "number"
        },
        "text": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "output_name": {
      "type": "string"
    },
    "skipped_pages": {
      "type": "string"
    },
    "stamped_pages": {
      "type": "number"
    },
    "output_size_kb": {
      "type": "number"
    },
    "expires_in_hours": {
      "type": "number"
    }
  },
  "additionalProperties": false
}
stamp_page_numbers annotations
{
  "title": "Number PDF pages",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
stamp_bates_numbers — Bates number a PDF
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when the user wants to Bates number a PDF, Bates stamp documents for a legal production, or add sequential document control numbers such as ACME000101 to each page. Takes one attached PDF, a prefix, start number, zero-padding digits (1-10), optional suffix and one of six positions, and returns a new PDF plus a CSV log of page number to Bates number, with the first and last Bates number. Each stamp is checked again in the new file before the link is given. Does not open password-protected PDFs, does not number across several files in one call (pass the next start number yourself), and does not draw non-Latin scripts. Do not use for simple page numbers (use stamp_page_numbers).

stamp_bates_numbers input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "file"
  ],
  "properties": {
    "file": {
      "type": "object",
      "required": [
        "download_url",
        "file_id"
      ],
      "properties": {
        "file_id": {
          "type": "string",
          "description": "ChatGPT file id, e.g. file_abc123."
        },
        "file_name": {
          "type": "string",
          "description": "Original file name if known, e.g. statement.pdf."
        },
        "mime_type": {
          "type": "string",
          "description": "Media type if known, e.g. application/pdf."
        },
        "download_url": {
          "type": "string",
          "description": "Temporary download link for the file, supplied by ChatGPT."
        }
      },
      "description": "The PDF to Bates number, e.g. production-vol1.pdf."
    },
    "start": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991,
      "description": "First Bates number, e.g. 101. Default 1."
    },
    "digits": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991,
      "description": "Zero-pad the number to this many digits, 1 to 10, e.g. 6 gives 000101. Default 6."
    },
    "prefix": {
      "type": "string",
      "maxLength": 40,
      "description": "Text before the number, e.g. \"ACME\" or \"SMITH-\". Default none."
    },
    "suffix": {
      "type": "string",
      "maxLength": 40,
      "description": "Text after the number, e.g. \"-CONF\". Default none."
    },
    "position": {
      "enum": [
        "top-left",
        "top-center",
        "top-right",
        "bottom-left",
        "bottom-center",
        "bottom-right"
      ],
      "type": "string",
      "description": "Where the text goes on each page as viewed: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right. Default bottom-right."
    },
    "font_size": {
      "type": "number",
      "description": "Font size in points from 6 to 36, e.g. 10 (default)."
    },
    "margin_pt": {
      "type": "number",
      "description": "Distance from the page edge in points from 6 to 144, e.g. 24 (default)."
    }
  }
}
stamp_bates_numbers output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "file",
    "pages",
    "stamped_pages",
    "first_stamp",
    "last_stamp",
    "position",
    "font_size",
    "check",
    "notes",
    "output_name",
    "output_size_kb",
    "expires_in_hours",
    "first_bates",
    "last_bates",
    "downloads"
  ],
  "properties": {
    "file": {
      "type": "string"
    },
    "check": {
      "type": "object",
      "required": [
        "passed",
        "what",
        "pages_checked",
        "pages_read_by_pdfjs"
      ],
      "properties": {
        "what": {
          "type": "string"
        },
        "passed": {
          "type": "boolean"
        },
        "pages_checked": {
          "type": "number"
        },
        "pages_read_by_pdfjs": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "pages": {
      "type": "number"
    },
    "position": {
      "type": "string"
    },
    "downloads": {
      "type": "object",
      "required": [
        "pdf",
        "csv"
      ],
      "properties": {
        "csv": {
          "type": "string"
        },
        "pdf": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "font_size": {
      "type": "number"
    },
    "last_bates": {
      "type": "string"
    },
    "last_stamp": {
      "type": "object",
      "required": [
        "page",
        "text"
      ],
      "properties": {
        "page": {
          "type": "number"
        },
        "text": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "first_bates": {
      "type": "string"
    },
    "first_stamp": {
      "type": "object",
      "required": [
        "page",
        "text"
      ],
      "properties": {
        "page": {
          "type": "number"
        },
        "text": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "output_name": {
      "type": "string"
    },
    "stamped_pages": {
      "type": "number"
    },
    "output_size_kb": {
      "type": "number"
    },
    "expires_in_hours": {
      "type": "number"
    }
  },
  "additionalProperties": false
}
stamp_bates_numbers annotations
{
  "title": "Bates number a PDF",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
stamp_watermark — Watermark a PDF
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when the user wants to add a watermark to a PDF, stamp DRAFT, CONFIDENTIAL, COPY or SAMPLE across the pages, or mark only some pages. Takes one attached PDF, the watermark text (up to 40 characters), opacity from 0.05 to 0.5, angle from -90 to 90 degrees, optional pages such as "1-3, 8" and optional font size, and returns a new PDF with the text centered on each chosen page. Each stamp is checked again in the new file before the link is given. Does not add image or logo watermarks, does not open password-protected PDFs, and the text can be removed with PDF editing software. Do not use for page numbers.

stamp_watermark input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "file",
    "text"
  ],
  "properties": {
    "file": {
      "type": "object",
      "required": [
        "download_url",
        "file_id"
      ],
      "properties": {
        "file_id": {
          "type": "string",
          "description": "ChatGPT file id, e.g. file_abc123."
        },
        "file_name": {
          "type": "string",
          "description": "Original file name if known, e.g. statement.pdf."
        },
        "mime_type": {
          "type": "string",
          "description": "Media type if known, e.g. application/pdf."
        },
        "download_url": {
          "type": "string",
          "description": "Temporary download link for the file, supplied by ChatGPT."
        }
      },
      "description": "The PDF to watermark, e.g. proposal.pdf."
    },
    "text": {
      "type": "string",
      "maxLength": 80,
      "description": "Watermark text, e.g. \"DRAFT\" or \"CONFIDENTIAL\"."
    },
    "angle": {
      "type": "number",
      "description": "Angle in degrees counter-clockwise, -90 to 90, e.g. 45 (default) or 0 for flat."
    },
    "pages": {
      "type": "string",
      "maxLength": 400,
      "description": "Pages to mark, e.g. \"all\" (default) or \"1-3, 8, 10-end\"."
    },
    "opacity": {
      "type": "number",
      "description": "How strong the text is, 0.05 (faint) to 0.5, e.g. 0.15 (default)."
    },
    "font_size": {
      "type": "number",
      "description": "Font size in points, 8 to 300, e.g. 72. Default: fit the page."
    }
  }
}
stamp_watermark output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "file",
    "pages",
    "stamped_pages",
    "first_stamp",
    "last_stamp",
    "position",
    "font_size",
    "check",
    "notes",
    "output_name",
    "output_size_kb",
    "expires_in_hours",
    "text",
    "opacity",
    "angle",
    "page_list",
    "downloads"
  ],
  "properties": {
    "file": {
      "type": "string"
    },
    "text": {
      "type": "string"
    },
    "angle": {
      "type": "number"
    },
    "check": {
      "type": "object",
      "required": [
        "passed",
        "what",
        "pages_checked",
        "pages_read_by_pdfjs"
      ],
      "properties": {
        "what": {
          "type": "string"
        },
        "passed": {
          "type": "boolean"
        },
        "pages_checked": {
          "type": "number"
        },
        "pages_read_by_pdfjs": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "pages": {
      "type": "number"
    },
    "opacity": {
      "type": "number"
    },
    "position": {
      "type": "string"
    },
    "downloads": {
      "type": "object",
      "required": [
        "pdf"
      ],
      "properties": {
        "pdf": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "font_size": {
      "type": "number"
    },
    "page_list": {
      "type": "string"
    },
    "last_stamp": {
      "type": "object",
      "required": [
        "page",
        "text"
      ],
      "properties": {
        "page": {
          "type": "number"
        },
        "text": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "first_stamp": {
      "type": "object",
      "required": [
        "page",
        "text"
      ],
      "properties": {
        "page": {
          "type": "number"
        },
        "text": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "output_name": {
      "type": "string"
    },
    "stamped_pages": {
      "type": "number"
    },
    "output_size_kb": {
      "type": "number"
    },
    "expires_in_hours": {
      "type": "number"
    }
  },
  "additionalProperties": false
}
stamp_watermark annotations
{
  "title": "Watermark a PDF",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

1 advertised

page-numbers-widget — Zovo Page Numbers view

Advertised by the server during the last successful anonymous check.

Interactive view for Zovo Page Numbers.

page-numbers-widget URI
ui://widget/page-numbers-v1-1.0.0-3225d04d9864453ae11bfe3391c019f4198cb5908be382aa44b0e11d8c8aa394.html

MIME type: text/html;profile=mcp-app

page-numbers-widget-legacy — Zovo Page Numbers view (previous versions)

Advertised by the server during the last successful anonymous check.

page-numbers-widget-legacy URI template
ui://widget/page-numbers-{version}.html

MIME type: text/html;profile=mcp-app

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
1218 ms
95th percentile latency
1218 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 1218 ms · metadata changed · 3 tool(s), 1 resource(s), 1 resource template(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http zovo-page-numbers-mcp https://page-numbers.zovo.one/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add zovo-page-numbers-mcp --url https://page-numbers.zovo.one/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable zovo-page-numbers-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "zovo-page-numbers-mcp": {
      "url": "https://page-numbers.zovo.one/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "zovo-page-numbers-mcp": {
      "type": "streamableHttp",
      "url": "https://page-numbers.zovo.one/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start zovo-page-numbers-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "zovo-page-numbers-mcp": {
      "type": "http",
      "url": "https://page-numbers.zovo.one/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http zovo-page-numbers-mcp https://page-numbers.zovo.one/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://page-numbers.zovo.one/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "zovo-page-numbers-mcp": {
      "serverUrl": "https://page-numbers.zovo.one/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Zovo Page Numbers MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.