Skip to main content
Glama
README.md
# Zactonz MCP server

A [Model Context Protocol](https://modelcontextprotocol.io) server for the [Zactonz APIs](https://developers.zactonz.com/apis/). It lets an AI assistant capture a screenshot of a web page, read a page as Markdown, preview a link, look up DNS, SSL and WHOIS records, check a domain's email setup, verify addresses, generate QR codes, barcodes and social card images, convert images and translate text.

It runs on your machine over stdio and needs Node.js 18 or newer.

## Install

> **Not on npm yet.** `@zactonz/mcp` has not been published, so the `npx` commands below do not
> work yet. Until it is, install from source — the steps are at the end of this section and take
> about a minute.

### From source

Needs [Node.js](https://nodejs.org) 18 or newer and git.

```bash
git clone https://github.com/zactonz/zactonz-mcp.git
cd zactonz-mcp
npm ci --omit=dev
```

That is the whole install: two runtime dependencies, no build step. Check it starts — it will wait
for input, so press Ctrl+C to leave:

```bash
node bin/zactonz-mcp.js
```

Then point your client at the absolute path, in place of the `npx` form used below:

```json
{
  "mcpServers": {
    "zactonz": {
      "command": "node",
      "args": ["/absolute/path/to/zactonz-mcp/bin/zactonz-mcp.js"],
      "env": {
        "ZACTONZ_API_KEYS": "zk_screen_…,zk_markdown_…"
      }
    }
  }
}
```

Use the real absolute path — `~` and relative paths are not expanded by most clients. On Windows,
write it with forward slashes or escaped backslashes, for example
`C:/Users/you/zactonz-mcp/bin/zactonz-mcp.js`.

For Claude Code:

```bash
claude mcp add zactonz --env ZACTONZ_API_KEYS="zk_screen_…" -- node /absolute/path/to/zactonz-mcp/bin/zactonz-mcp.js
```

If you would rather have `zactonz-mcp` on your `PATH`, run `npm link` in the clone, then use
`"command": "zactonz-mcp"` with no `args`.

To update later: `git pull && npm ci --omit=dev`.

## Setup

1. Create a key for each product you want to use in the [API console](https://developers.zactonz.com/console/). There is a free plan.
2. Install the server — see [Install](#install) above.
3. Add the server to your MCP client, with the keys in `ZACTONZ_API_KEYS` separated by commas.

The examples below use `npx -y @zactonz/mcp`, which will work once the package is published. Until
then substitute the `"command"` and `"args"` shown under [From source](#from-source).

Clients that read an `mcpServers` block, such as Claude Desktop, Cursor and Windsurf:

```json
{
  "mcpServers": {
    "zactonz": {
      "command": "npx",
      "args": ["-y", "@zactonz/mcp"],
      "env": {
        "ZACTONZ_API_KEYS": "zk_screen_…,zk_markdown_…,zk_domain_…"
      }
    }
  }
}
```

VS Code (`.vscode/mcp.json`):

```json
{
  "servers": {
    "zactonz": {
      "command": "npx",
      "args": ["-y", "@zactonz/mcp"],
      "env": { "ZACTONZ_API_KEYS": "zk_screen_…,zk_markdown_…" }
    }
  }
}
```

Claude Code:

```bash
claude mcp add zactonz --env ZACTONZ_API_KEYS="zk_screen_…,zk_markdown_…" -- npx -y @zactonz/mcp
```

On Windows, if the client cannot start `npx` directly, use `"command": "cmd"` with `"args": ["/c", "npx", "-y", "@zactonz/mcp"]`.

## Keys

A Zactonz key works for one product, and the product is part of the key: `zk_screen_…` is a screenshot key, `zk_markdown_…` a Markdown key. Put every key you have in `ZACTONZ_API_KEYS`. The server uses the right one for each call and offers the assistant only the tools those keys can call.

Keys stay in the server process. They are sent to `api.zactonz.com` in the `Authorization` header and nowhere else, and they are never included in anything returned to the assistant.

## Tools

| Tool                       | Purpose                                          | Key          |
| -------------------------- | ------------------------------------------------ | ------------ |
| `capture_screenshot`       | Capture a web page as an image or PDF            | `screen`     |
| `render_html`              | Render HTML to an image or PDF                   | `screen`     |
| `read_webpage`             | Read a web page as Markdown                      | `markdown`   |
| `convert_html_to_markdown` | Convert HTML to Markdown                         | `markdown`   |
| `preview_link`             | Title, description, image and metadata of a URL  | `unfurl`     |
| `lookup_dns`               | DNS records and DNSSEC status                    | `domain`     |
| `inspect_ssl_certificate`  | Certificate, chain, expiry and TLS details       | `domain`     |
| `lookup_whois`             | Registrar, dates and nameservers of a domain     | `domain`     |
| `check_email_domain`       | MX, SPF, DKIM, DMARC and related records, scored | `email`      |
| `verify_emails`            | Whether addresses can receive mail               | `mverifier`  |
| `generate_qr_code`         | Generate a QR code                               | `qr`         |
| `read_qr_code`             | Decode a QR code                                 | `qr`         |
| `generate_barcode`         | Generate a barcode                               | `barcode`    |
| `generate_social_image`    | Generate an Open Graph image                     | `og`         |
| `convert_image`            | Convert, resize or crop an image                 | `image`      |
| `inspect_image`            | Dimensions, format and colours of an image       | `image`      |
| `translate_text`           | Translate between 46 languages                   | `translator` |
| `get_drive_download_link`  | Direct download link for a Google Drive file     | `gdrive`     |
| `check_api_key`            | Plan and remaining quota of a key                | any          |

[docs/tools.md](docs/tools.md) lists the arguments of each tool.

Example requests once it is connected:

- "Take a screenshot of example.com on a 390 pixel wide screen and tell me whether the menu fits."
- "Read https://example.com/pricing and summarise the plans."
- "Does example.com have SPF and DMARC set up correctly?"
- "When does the SSL certificate for example.com expire?"

## Results

A tool returns JSON text. Two things differ from the raw API:

- `read_webpage` and `convert_html_to_markdown` return the Markdown as plain text, followed by the remaining fields as JSON. They request at most 20,000 characters unless the assistant asks for more.
- A tool that produces an image returns the link and, when the file is 750 KB or smaller, the image as well, so the assistant can look at it. `capture_screenshot` and `render_html` use JPEG quality 80 unless told otherwise, to stay under that size. PDFs and larger images are returned as a link only.

A refused call is returned as a tool error carrying the API's message, the status, how long to wait when a limit was reached, and the request id.

## Limits and timing

Calls spend units from your plan's quota, the same as direct API calls. See [rate limits and quotas](https://developers.zactonz.com/apis/rate-limits/).

A tool call is given 55 seconds in total, because MCP clients stop waiting after 60. Within that time the server retries once, and only where a retry cannot repeat work: after a `429` with a short `Retry-After`, after a gateway error on a read, or ten seconds after the API's request burst limit rejects a call. If the client cancels a call, the server stops.

## Configuration

| Variable                         | Purpose                                                         | Default                   |
| -------------------------------- | --------------------------------------------------------------- | ------------------------- |
| `ZACTONZ_API_KEYS`               | API keys, separated by commas                                   | none                      |
| `ZACTONZ_MCP_INLINE_IMAGE_BYTES` | Largest image returned inline, in bytes. `0` returns links only | `750000`                  |
| `ZACTONZ_BASE_URL`               | API base URL                                                    | `https://api.zactonz.com` |

Without keys the server still starts and lists every tool, and each call answers with setup instructions. Values in `ZACTONZ_API_KEYS` that are not Zactonz keys are ignored and reported on stderr.

## Security and privacy

- **Untrusted content.** `read_webpage`, `preview_link` and `read_qr_code` return text written by whoever controls the page or the code. That text can contain instructions aimed at the assistant. The server labels it as third-party data, but the label is advice to the model, not a guarantee. Review what an assistant does after reading pages you do not control.
- **Generated files are public links.** Screenshots, PDFs, QR codes, barcodes and converted images are stored on `api.zactonz.com` at unguessable URLs that anyone holding the link can open, for the period given on each endpoint's reference page. Do not render documents that must stay private.
- **What is sent.** Tool arguments go to `api.zactonz.com` and nowhere else. The server keeps no logs and stores nothing on disk. The API's own handling of data is covered by the [privacy policy](https://zactonz.com/privacy/).
- **Arguments are validated** against each tool's schema before any request is made, and arguments outside the schema are refused.
- **Images are fetched for inline display only from the API's own host**, over HTTPS, without following redirects.
- Tools that fetch a URL do so from Zactonz's servers, which refuse private and internal addresses.

Report a vulnerability as described in [SECURITY.md](SECURITY.md).

## Troubleshooting

- **A tool is missing.** Only tools with a key are listed. Add a key for that product and restart the client.
- **Every call answers with setup instructions.** `ZACTONZ_API_KEYS` is empty or holds no valid key. The server prints the reason on stderr, which most clients show in their MCP log.
- **"Missing or invalid API key."** The key was revoked or mistyped. Ask the assistant to run `check_api_key`, or check the key in the console.
- **A screenshot has no inline image.** The file is over the inline limit. Lower the quality or size, or raise `ZACTONZ_MCP_INLINE_IMAGE_BYTES`.

## Versioning

This package follows [semantic versioning](https://semver.org/). While it is at `0.x`, a minor release may rename a tool or an argument; such changes are listed in the [changelog](CHANGELOG.md).

## Development

See [CONTRIBUTING.md](CONTRIBUTING.md).

## Licence

MIT. See [LICENSE](LICENSE). Maintained by [Zactonz Technologies](https://zactonz.com).

TDQS

A3.7/5.0

Scored across 19 tools

Disambiguation4/5

Each tool targets a clearly distinct operation (QR, DNS, SSL, WHOIS, email, web rendering, image processing, translation). The only mild overlap is among web-content tools (read_webpage, preview_link, capture_screenshot, render_html), but their descriptions clearly differentiate fetching text, metadata, visual capture, and rendering provided HTML.

Naming Consistency5/5

All 19 tools use snake_case with a leading verb (read_, lookup_, inspect_, check_, verify_, generate_, capture_, render_, convert_, preview_, translate_, get_), creating a highly predictable pattern. No mixing of conventions.

Tool Count3/5

19 tools is on the heavy side for a single MCP server; the rubric treats 16–25 as borderline. Each tool is distinct, but the broad utility scope means the set could feel large to an agent.

Completeness4/5

The surface covers many common web utilities well: QR/barcode generation and reading, image conversion/inspection, web rendering/screenshots, DNS/SSL/WHOIS lookups, email checks, translation, and Drive link conversion. Minor gaps include OCR beyond QR, PDF-to-text, URL expansion/shortening, or text summarization, but core utilities are present.

Maintenance

ActivityMaintained
ResponsivenessNo issues