Skip to main content
Glama

lenses-mcp

MCP server for the Lens suite.

by svx · MIT Licensed

CI license

A Model Context Protocol server that exposes the five Lens-suite CLI tools to any MCP client (Claude Desktop, Cursor, etc.).

The Lens CLIs audit files entirely offline and return stable JSON. This server spawns the CLI, appends --json, captures stdout/stderr, and returns the parsed JSON as MCP text content. It never throws raw: non-zero exits come back as isError: true with the CLI's stderr and, when present, the parsed JSON.

Tools

Tool

Inputs

CLI

booklens_audit

path (string), fail_on? (error|warning|info|none)

booklens audit <file> --json

booklens_fix

path (string), out? (string), dry_run? (boolean)

booklens fix <file> --json [-o <out>] [--dry-run]

officelens_audit

path, fail_on?

officelens <file> --json

odflens_audit

path, fail_on?

odflens <file> --json

iconlens_audit

path, fail_on?

iconlens <file> --json

waxseal_seal

archive, key, out?, created_at?

waxseal seal <archive> --key <pem> --json [--out <seal>] [--created-at <iso>]

waxseal_verify

archive, seal, public_key?, root?

waxseal verify <archive> -s <seal> --json [--public-key <pem>] [--root <hex>]

waxseal_inspect

archive

waxseal inspect <archive> --json

Exit codes from the CLIs: 0 ok, 1 findings, 2 bad input, 3 I/O. Any non-zero code is surfaced as an MCP error result.

iconlens can read SVG from stdin in a terminal (iconlens -), but stdin is reserved by the MCP stdio transport, so over MCP always pass a file path.

Related MCP server: judg3d

Install

Nothing to install — run it straight from GitHub with Bun:

bunx github:srivtx/lenses-mcp#main

Or clone it and run from source:

git clone https://github.com/srivtx/lenses-mcp
cd lenses-mcp
bun install

Use with an MCP client

Claude Desktop

Add to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "lenses": {
      "command": "bunx",
      "args": ["github:srivtx/lenses-mcp#main"]
    }
  }
}

Cursor

Add to ~/.cursor/mcp.json (or .cursor/mcp.json in a project):

{
  "mcpServers": {
    "lenses": {
      "command": "bunx",
      "args": ["github:srivtx/lenses-mcp#main"]
    }
  }
}

To run from a local clone instead, use "command": "bun" with "args": ["run", "/absolute/path/to/lenses-mcp/src/index.ts"].

Any MCP client

Run bunx github:srivtx/lenses-mcp#main as a stdio server. It speaks newline-delimited JSON-RPC on stdin/stdout; all logs go to stderr.

Command resolution and env overrides

By default each tool runs:

bunx github:srivtx/<tool>#main

The #main ref is required — a bare github: spec resolves whatever commit bunx has cached, which goes stale. The first call fetches the package over the network.

Set a LENSES_*_BIN variable to point at a binary you installed yourself (e.g. with the tool's install.sh) and skip the network entirely:

Variable

Tool

LENSES_BOOKLENS_BIN

booklens

LENSES_OFFICELENS_BIN

officelens

LENSES_ODFLENS_BIN

odflens

LENSES_ICONLENS_BIN

iconlens

LENSES_WAXSEAL_BIN

waxseal

When set, the override replaces the whole bunx … invocation:

{
  "mcpServers": {
    "lenses": {
      "command": "lenses-mcp",
      "args": [],
      "env": {
        "LENSES_BOOKLENS_BIN": "/usr/local/bin/booklens",
        "LENSES_WAXSEAL_BIN": "/usr/local/bin/waxseal"
      }
    }
  }
}

An override that is an executable script (e.g. a local .ts CLI with a #!/usr/bin/env bun shebang) works too. A blank/whitespace value falls back to the bunx default.

Development

bun test                      # unit tests for the command builders + validation
bun run typecheck             # tsc --noEmit
bun run start                 # run the stdio server

Smoke-test the MCP handshake and one tool call by piping newline-delimited JSON-RPC into the server. Set the override to a local checkout so the call does not hit GitHub:

LENSES_ICONLENS_BIN=../svg-a11y/src/cli.ts bun run src/index.ts <<'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"0.0.0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"iconlens_audit","arguments":{"path":"/absolute/path/to/icon.svg","fail_on":"none"}}}
EOF

The server prints one JSON-RPC response per request line (the initialize result reports serverInfo.name: "lenses-mcp", and the tools/call result carries the CLI's JSON). Calling a missing file returns "isError": true with the CLI's stderr. All diagnostics go to stderr, never stdout.

Layout

src/tools.ts     tool catalog, input validation, pure command builders
src/index.ts     stdio MCP server (Server + StdioServerTransport)
tests/           bun test unit tests

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    EasyAccessPDF is a production MCP server for PDF accessibility and document conversion. Five tools: convert documents (PDF/DOCX/PPT/XLS/HTML/EPUB/RTF/ODT/TXT) to clean Markdown; export PDFs to JSON/HTML/text/annotated-PDF; run veraPDF PDF/UA-1 (ISO 14289) accessibility audits with graded reports; auto-tag and remediate PDFs for WCAG 2.1/2.2, Section 508, ADA Title II and EAA/EN 301 549 compliance.
    5
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Lets developers and MCP agents run deterministic local HTML audits, turning inline HTML into structured findings for missing labels, unnamed buttons, skipped headings, ambiguous links, duplicate IDs, and missing landmarks. It also exposes a rule list and returns stable, actionable reports without external API keys.
    2
    MIT