Skip to main content
Glama
steveclarke

MCP Printer Server

by steveclarke

MCP Printer Server šŸ–Øļø

An MCP server for printing documents on macOS/Linux. Provides AI assistants with the ability to print files, manage print queues, and control printers via the CUPS printing system.

Why?

In the era of AI-assisted development, we're generating more documentation, specs, guides, and code than ever before. When working with AI on complex projects, it's often valuable to review generated artifacts offline on paper. This tool makes it effortless to ask your AI assistant: "Print all the markdown files you just created" or "Print the README and all TypeScript files in this directory" — streamlining the workflow from AI generation to offline review.

Related MCP server: Printer AI MCP

Features

  • šŸ“„ Print files - PDF, text, and other formats

  • šŸ“ Render markdown - Convert markdown to beautifully formatted PDFs

  • šŸ“Š Mermaid diagrams - Flowcharts, sequence diagrams, and more render as visual graphics in markdown

  • šŸ’» Syntax-highlighted code - Automatically render code files with syntax highlighting, line numbers, and proper formatting

  • šŸ” Page count preview - Check how many pages a document will print before sending to printer (prevents accidental 200-page printouts!)

  • šŸ–Øļø List printers - See all available printers and their status

  • šŸ“‹ Manage queue - View and cancel print jobs

  • āš™ļø Configure - Set default printers

  • šŸŽÆ Smart - Supports multiple copies, landscape, duplex, and more

Installation

Add to your MCP configuration file (e.g., ~/.cursor/mcp.json for Cursor):

{
  "mcpServers": {
    "Printer": {
      "command": "npx",
      "args": ["-y", "mcp-printer"]
    }
  }
}

That's it! The package will be automatically downloaded from npm on first use.

šŸ–„ļø Platform Support: This server currently supports macOS and Linux only. Windows is not currently supported (contributions welcome!).

šŸ“‹ Requirements: Google Chrome or Chromium is required for rendering markdown and code files to PDF. The server will auto-detect Chrome/Chromium installations on macOS/Linux. See Requirements for details.

āš ļø Security: This server allows AI assistants to print files from allowed directories (~/Documents, ~/Downloads, ~/Desktop by default, customizable via MCP_PRINTER_ALLOWED_PATHS). Dotfiles and hidden directories are always blocked. Only use with trusted AI assistants on your local machine. See Security for configuration options.

Configuration

All configuration is optional. Add an env object to customize behavior:

Variable

Default

Description

MCP_PRINTER_DEFAULT_PRINTER

(none)

Default printer to use when none specified (falls back to system default)

MCP_PRINTER_AUTO_DUPLEX

false

Set to "true" to automatically print double-sided by default (can be overridden per-call)

MCP_PRINTER_DEFAULT_OPTIONS

(none)

Additional CUPS options (e.g., "fit-to-page", "landscape")

MCP_PRINTER_CHROME_PATH

(auto-detected)

Path to Chrome/Chromium for PDF rendering (override if auto-detection fails)

MCP_PRINTER_AUTO_RENDER_MARKDOWN

true

Automatically render markdown files (.md, .markdown) to PDF (can be overridden with force_markdown_render)

MCP_PRINTER_AUTO_RENDER_CODE

true

Automatically render code files to PDF with syntax highlighting (can be overridden with force_code_render)

MCP_PRINTER_ENABLE_MANAGEMENT

false

Management operations are disabled by default for security. Set to "true" to enable set_default_printer and cancel_print_job tools

MCP_PRINTER_ENABLE_PROMPTS

true

Enable prompts (workflow templates). Set to "false" to disable prompt registration if you don't want prompts in your MCP client

MCP_PRINTER_ALLOWED_PATHS

~/Documents, ~/Downloads, ~/Desktop

Colon-separated paths allowed for printing. Overrides default allowed directories when set (e.g., "$HOME/Documents:$HOME/src")

MCP_PRINTER_DENIED_PATHS

(system dirs)

Colon-separated paths denied for printing. Merged with system directory defaults like /etc, /var, etc. (e.g., "/home/user/private")

MCP_PRINTER_FALLBACK_ON_RENDER_ERROR

false

Set to "true" to print original file if PDF rendering fails (markdown/code). When false, errors will be thrown instead

MCP_PRINTER_MAX_COPIES

10

Maximum copies allowed per print job (set to 0 for unlimited)

MCP_PRINTER_CONFIRM_IF_OVER_PAGES

10

If set > 0, print jobs exceeding this many physical sheets will trigger a confirmation prompt from the AI before printing. Set to 0 to disable. (PDF files only)

MCP_PRINTER_CODE_EXCLUDE_EXTENSIONS

(none)

Extensions to exclude from code rendering (e.g., "json,yaml,html") - only applies when code rendering is enabled

MCP_PRINTER_CODE_COLOR_SCHEME

"atom-one-light"

Syntax highlighting color scheme (see Available Themes)

MCP_PRINTER_CODE_AUTO_LINE_NUMBERS

true

Automatically show line numbers in code printouts (can be overridden per-call with the line_numbers parameter)

MCP_PRINTER_CODE_FONT_SIZE

"10pt"

Font size for code (e.g., "8pt", "12pt")

MCP_PRINTER_CODE_LINE_SPACING

"1.5"

Line spacing multiplier for code (e.g., "1", "1.5", "2")

Example configuration:

{
  "mcpServers": {
    "Printer": {
      "command": "npx",
      "args": ["-y", "mcp-printer"],
      "env": {
        "MCP_PRINTER_DEFAULT_PRINTER": "HP_LaserJet_Pro",
        "MCP_PRINTER_AUTO_DUPLEX": "true",
        "MCP_PRINTER_DEFAULT_OPTIONS": "fit-to-page",
        "MCP_PRINTER_AUTO_RENDER_MARKDOWN": "true",
        "MCP_PRINTER_AUTO_RENDER_CODE": "true",
        "MCP_PRINTER_ENABLE_PROMPTS": "true",
        "MCP_PRINTER_CODE_COLOR_SCHEME": "github",
        "MCP_PRINTER_CODE_FONT_SIZE": "9pt",
        "MCP_PRINTER_ALLOWED_PATHS": "/Users/myname/Documents:/Users/myname/Downloads:/Users/myname/projects"
      }
    }
  }
}

šŸ’” Note: The MCP_PRINTER_ALLOWED_PATHS example above replaces the default allowed directories. If you set this variable, you must explicitly include any default directories you want to keep (like Documents, Downloads, Desktop) plus any additional directories like your projects folder. Use colon-separated absolute paths (:).

šŸ’” Tip: You can use the list_printers tool to see all available printers and their exact names.

User-specified options in prompts always override these defaults.

Available Tools

get_config

Get the current MCP Printer configuration settings. Only returns non-sensitive configuration values.

Example:

User: What are my printer settings?
AI: Current MCP Printer Configuration:

MCP_PRINTER_DEFAULT_PRINTER: HP_LaserJet_4001
MCP_PRINTER_AUTO_DUPLEX: true
MCP_PRINTER_DEFAULT_OPTIONS: (not set)
MCP_PRINTER_CHROME_PATH: (auto-detected)
MCP_PRINTER_AUTO_RENDER_MARKDOWN: true
MCP_PRINTER_AUTO_RENDER_CODE: true
MCP_PRINTER_ENABLE_MANAGEMENT: false
MCP_PRINTER_ENABLE_PROMPTS: true

list_printers

List all available printers with their status.

Example:

User: What printers do I have available?
AI: Let me check what printers you have...
→ HP_LaserJet_4001 is idle and accepting jobs
→ Canon_Pixma is disabled

print_file

Print one or more files to a specified printer. Supports batch operations to reduce tool call costs.

Parameters:

  • files (required) - Array of file specifications (use single-element array for one file):

    • file_path (required) - Full path to file

    • printer (optional) - Printer name

    • copies (optional) - Number of copies (default: 1)

    • options (optional) - CUPS options like landscape, sides=two-sided-long-edge

    • skip_confirmation (optional) - Skip page count confirmation check (bypasses MCP_PRINTER_CONFIRM_IF_OVER_PAGES threshold)

    • line_numbers (optional) - Show line numbers when rendering code files (boolean, overrides global setting)

    • color_scheme (optional) - Syntax highlighting theme for code files (e.g., github, monokai, atom-one-light)

    • font_size (optional) - Font size for code files (e.g., 8pt, 10pt, 12pt)

    • line_spacing (optional) - Line spacing for code files (e.g., 1, 1.5, 2)

    • force_markdown_render (optional) - Force markdown rendering to PDF (boolean: true=always render, false=never render, undefined=use config)

    • force_code_render (optional) - Force code rendering to PDF with syntax highlighting (boolean: true=always render, false=never render, undefined=use config)

Note: The code rendering parameters (line_numbers, color_scheme, font_size, line_spacing) only apply when printing code files that are automatically rendered to PDF with syntax highlighting.

Batch Operations: To print multiple files efficiently, pass an array of file specifications. Each file is processed independently, and the operation continues even if individual files fail. The response shows success/failure status for each file.

Batch Size Limit: Batches are limited to 50 items per operation for reliability. If you need to process more items, the AI will automatically split them into multiple tool calls.

Page Count Confirmation: By default, print jobs exceeding 10 physical sheets will trigger a confirmation prompt from the AI before printing. You can adjust this threshold with MCP_PRINTER_CONFIRM_IF_OVER_PAGES or set it to 0 to disable. If you confirm, the AI will automatically retry the print with the confirmation bypassed. This feature only works for PDF files (including auto-rendered markdown and code files).

Example (single file):

User: Print README.md to my HP LaserJet, 2 copies
AI: *prints file*
Print Results: 1/1 successful

āœ“ /path/to/README.md
  Printed to HP_LaserJet_4001 Ɨ 2 copies (rendered: markdown → PDF)

Example (batch):

User: Print all markdown files in docs/
AI: *prints multiple files in one tool call*
Print Results: 3/3 successful

āœ“ /path/to/docs/setup.md
  Printed to HP_LaserJet_4001 (rendered: markdown → PDF)

āœ“ /path/to/docs/guide.md
  Printed to HP_LaserJet_4001 (rendered: markdown → PDF)

āœ“ /path/to/docs/reference.md
  Printed to HP_LaserJet_4001 (rendered: markdown → PDF)

get_page_meta

Get page count and physical sheet information for one or more files before printing. This tool pre-renders files (markdown, code) if needed and returns page metadata. Supports batch operations.

Parameters:

  • files (required) - Array of file specifications (use single-element array for one file):

    • file_path (required) - Full path to file

    • options (optional) - CUPS options for duplex detection (e.g., sides=two-sided-long-edge)

    • line_numbers (optional) - Show line numbers when rendering code files (boolean, overrides global setting)

    • color_scheme (optional) - Syntax highlighting theme for code files

    • font_size (optional) - Font size for code files (e.g., 8pt, 10pt, 12pt)

    • line_spacing (optional) - Line spacing for code files (e.g., 1, 1.5, 2)

    • force_markdown_render (optional) - Force markdown rendering to PDF

    • force_code_render (optional) - Force code rendering to PDF with syntax highlighting

Note: Page counting only works for PDF files, including:

  • Markdown files (auto-rendered to PDF)

  • Code files with syntax highlighting (auto-rendered to PDF)

  • Existing PDF files

Plain text files, images, and other non-PDF formats cannot have their page count determined.

Batch Operations: Check page counts for multiple files in a single tool call. Each file is processed independently, and the operation continues even if individual files fail.

Batch Size Limit: Batches are limited to 50 items per operation for reliability. If you need to process more items, the AI will automatically split them into multiple tool calls.

Example (single file):

User: How many pages would README.md be?
AI: *gets page metadata*
Page Metadata Results: 1/1 successful

āœ“ /path/to/README.md
  32 pages (16 sheets, duplex) (rendered: markdown → PDF)

Example (batch):

User: How many pages would all the markdown files in docs/ be?
AI: *gets metadata for multiple files*
Page Metadata Results: 3/3 successful

āœ“ /path/to/docs/setup.md
  8 pages (4 sheets, duplex) (rendered: markdown → PDF)

āœ“ /path/to/docs/guide.md
  24 pages (12 sheets, duplex) (rendered: markdown → PDF)

āœ“ /path/to/docs/reference.md
  16 pages (8 sheets, duplex) (rendered: markdown → PDF)

Use cases:

  • Check page count before printing large documents

  • Estimate paper usage for duplex vs single-sided printing

  • Preview rendered output of markdown or code files

  • Calculate total pages across multiple documents

get_print_queue

Check the print queue for pending jobs.

Parameters:

  • printer (optional) - Specific printer to check

Example:

User: What's in my print queue?
AI: Let me check your print queue...
→ Job 123: document.pdf (active)
→ Job 124: notes.txt (pending)

cancel_print_job

Cancel one or more print jobs. Supports batch operations.

Parameters:

  • jobs (required) - Array of job cancellation specifications (use single-element array for one job):

    • job_id (optional) - Specific job to cancel

    • printer (optional) - Printer name

    • cancel_all (optional) - Cancel all jobs for printer

Batch Operations: Cancel multiple jobs in a single tool call. Each cancellation is processed independently, and the operation continues even if individual cancellations fail.

Batch Size Limit: Batches are limited to 50 items per operation for reliability. If you need to process more items, the AI will automatically split them into multiple tool calls.

Example (single job):

User: Cancel job 123
AI: Cancel Results: 1/1 successful

āœ“ Cancelled job: 123

Example (batch):

User: Cancel jobs 123, 124, and 125
AI: Cancel Results: 3/3 successful

āœ“ Cancelled job: 123

āœ“ Cancelled job: 124

āœ“ Cancelled job: 125

get_default_printer

Get the system's default printer (not the MCP_PRINTER_DEFAULT_PRINTER config setting).

Example:

User: What's my default printer?
AI: Your default printer is: HP_LaserJet_4001

set_default_printer

Set a printer as the default.

Parameters:

  • printer (required) - Printer name

Example:

User: Make HP LaserJet my default printer
AI: āœ“ Set default printer to: HP_LaserJet_4001

Available Prompts

Prompts are workflow templates that appear as slash commands in your AI assistant (e.g., Cursor). They provide guided workflows for common printing tasks.

/print-changed

Print files that have changed in your git repository for offline review.

What it does:

  • Finds files that have changed based on git context (staged, uncommitted, or in a branch)

  • Prints all changed files with consistent settings

  • Perfect for reviewing code changes on paper before committing or merging

Parameters:

  • context - What to print: "staged", "uncommitted", "branch", or a specific branch name

  • options (optional) - Print options (e.g., "landscape", "two-sided")

Examples:

User: /print-changed
[Form appears]
context: staged
options: 

AI: [Finds staged files using git diff --cached --name-only, prints each file]
āœ“ Printed 3 files: src/server.ts, src/config.ts, README.md

User: /print-changed
context: branch
options: two-sided

AI: [Finds files changed in current branch vs main]
āœ“ Printed 8 files with duplex printing enabled

Use cases:

  • Review staged changes before committing

  • Print uncommitted work for offline debugging

  • Review all changes in a feature branch

  • Create paper copies for code review meetings

Usage Examples

Print Code with Syntax Highlighting

User: Print src/index.ts
AI: *automatically renders with syntax highlighting*
āœ“ File sent to printer: HP_LaserJet_Pro
  Rendered: code → PDF (syntax highlighted)

Print Documentation (Batch)

User: Print all the markdown files in docs/
AI: *prints all files in one batch operation*
Print Results: 3/3 successful

āœ“ /path/to/docs/setup.md
  Printed to HP_LaserJet_Pro (rendered: markdown → PDF)

āœ“ /path/to/docs/guide.md
  Printed to HP_LaserJet_Pro (rendered: markdown → PDF)

āœ“ /path/to/docs/reference.md
  Printed to HP_LaserJet_Pro (rendered: markdown → PDF)

Force Rendering

User: Print this .ts file without syntax highlighting
AI: *prints with force_code_render=false*
āœ“ File sent as plain text

User: Print this README.md with formatting even though I don't have auto-render enabled
AI: *prints with force_markdown_render=true*
āœ“ Rendered markdown → PDF

Print with Options

User: Print this PDF in landscape, double-sided
AI: *prints with options: landscape, sides=two-sided-long-edge*

Manage Queue

User: What's in my print queue?
AI: You have 2 jobs:
- Job 125: report.pdf (printing)
- Job 126: invoice.pdf (pending)

User: Cancel job 126
AI: āœ“ Cancelled job: 126

Page Count Preview and Confirmation

User: How many pages would this markdown file be?
AI: *previews file*
šŸ“„ Preview: 32 pages (16 sheets, duplex)
  File: /path/to/document.md
  Rendered: markdown → PDF

# With MCP_PRINTER_CONFIRM_IF_OVER_PAGES=10 set:
User: Print document.md
AI: *checks page count before printing*
šŸ“„ Preview: This document will print 32 pages (16 sheets, duplex)
  File: /path/to/document.md
  Rendered: markdown → PDF

āš ļø  This exceeds the configured page threshold.
This is a large document. Are you sure you want to print 32 pages?

User: Yes, print it
AI: *automatically retries print with confirmation bypassed*
āœ“ File sent to printer: HP_LaserJet_4001
  File: /path/to/document.md
  Rendered: markdown → PDF

CUPS Options

Any valid CUPS/lpr options can be passed via the options parameter. Common examples:

  • landscape - Print in landscape orientation

  • sides=two-sided-long-edge - Double-sided (long edge)

  • sides=two-sided-short-edge - Double-sided (short edge)

  • page-ranges=1-5 - Print specific pages (e.g., page-ranges=3-5,7,10-12)

  • media=Letter or media=A4 - Paper size

  • fit-to-page - Scale to fit page

  • number-up=2 - Print multiple pages per sheet

Natural Language Requests: Thanks to the flexibility of the underlying CUPS printing system and the AI's knowledge of print options, you don't need to memorize these options. Simply ask naturally—"print pages 3 to 5 in landscape on letter size paper" or "print this double-sided"—and the AI will translate your request into the appropriate CUPS options automatically. Feel free to experiment with common printing scenarios; the AI is smart enough to figure out what you need.

For a complete list of available options:

  • Run lpoptions -l in your terminal to see printer-specific options

  • See the CUPS documentation for standard printing options

  • Check man lpr for command-line options

Supported File Types

The server uses CUPS, which supports:

  • āœ… PDF

  • āœ… Plain text

  • āœ… Images (JPEG, PNG)

  • āœ… Markdown

  • āœ… Code files (see Code Rendering for details)

  • āš ļø PostScript (printer-dependent - some printers may not support it)

Other document formats may need conversion to PDF first.

Markdown Rendering

Markdown files are rendered to beautifully formatted PDFs using crossnote.

Features

  • ✨ Beautiful styling - Clean, modern GitHub-style theme optimized for printing

  • šŸ”¢ Automatic page numbers - Every page shows "Page X / Y" at the bottom

  • šŸ“Š Mermaid diagrams - Flowcharts, sequence diagrams, class diagrams render as visual graphics

  • šŸŽØ Syntax highlighting - Code blocks within markdown are beautifully highlighted

  • āž• Math rendering - KaTeX support for mathematical expressions

  • šŸ“ Tables & formatting - Table styling, blockquotes, and all standard markdown features

Diagram Support

Markdown rendering includes support for:

  • Mermaid - Flowcharts, sequence diagrams, class diagrams, state diagrams, etc.

  • WaveDrom - Digital timing diagrams

  • GraphViz - Graph visualizations

  • Vega & Vega-Lite - Data visualizations

All diagrams render as visual graphics in the PDF output, not code blocks.

Configuration

  • To enable/disable markdown rendering: Set MCP_PRINTER_AUTO_RENDER_MARKDOWN to "true" or "false" (default: true)

  • To force rendering on a per-call basis: Use the force_markdown_render parameter in print_file

Custom Page Numbering

Page numbers are automatically added to the footer of every rendered markdown PDF. If you want to customize or disable page numbering for a specific file, you can add YAML front-matter:

---
chrome:
  displayHeaderFooter: false
---

# Your Document

Content without page numbers...

Or customize the footer template:

---
chrome:
  displayHeaderFooter: true
  footerTemplate: '<div style="font-size:10px; text-align:right; width:100%; padding-right:1cm; font-family: -apple-system, BlinkMacSystemFont, sans-serif;">Page <span class="pageNumber"></span></div>'
---

# Your Document

Content with custom page numbers...

Code Rendering

Code files are automatically rendered to PDF with syntax highlighting, line numbers, and proper formatting for optimal printing quality.

Supported Languages

The system uses a strict whitelist approach - only files with recognized extensions or shebangs are automatically rendered as code. This prevents false positives on plain text files like LICENSE or README.

Programming Languages: JavaScript (.js, .jsx), TypeScript (.ts, .tsx), Python (.py), Java (.java), C (.c, .h), C++ (.cpp, .cc, .cxx, .hpp), C# (.cs), Go (.go), Rust (.rs), Swift (.swift), Kotlin (.kt), Ruby (.rb), PHP (.php), Scala (.scala), Perl (.pl, .perl), Lua (.lua), R (.r)

Shell/Scripts: Bash/Shell (.sh, .bash, .zsh, .fish), PowerShell (.ps1), Vim (.vim)

Markup/Data: HTML (.html), CSS (.css), SCSS (.scss), Sass (.sass - uses SCSS highlighting), Less (.less), JSON (.json), YAML (.yaml, .yml), XML (.xml), Markdown (.md), SQL (.sql)

Special Files (no extension): Makefile, Dockerfile, Gemfile, Rakefile, Vagrantfile

Shebang Detection: Files without recognized extensions that contain a shebang (#!/bin/bash, #!/usr/bin/env python3, etc.) in the first 1024 bytes are automatically detected as code. This enables syntax-highlighted rendering of shell scripts and other executable files without extensions.

Unknown Extensions: Files with unknown extensions (like .txt, .bak, .weird) and no shebang will NOT be automatically rendered. To render these files with syntax highlighting, the AI can use the force_code_render=true parameter in the print_file tool call.

šŸ’” Tip: You don't need to know the technical parameter names! Simply ask your AI assistant in natural language: "Print this file and render it as code" or "Make sure to render that shell script with syntax highlighting". The AI will understand and use the force_code_render parameter automatically. This is especially useful for shell scripts without .sh extensions or other code files with non-standard names.

Configuration:

  • To enable/disable automatic code rendering: Set MCP_PRINTER_AUTO_RENDER_CODE to "true" or "false" (default: true)

  • To disable automatic code rendering for specific extensions: MCP_PRINTER_CODE_EXCLUDE_EXTENSIONS="json,yaml,html"

  • To force code rendering for a specific file: Use the force_code_render parameter in print_file

Color Schemes

The following light themes are recommended for printing (set via MCP_PRINTER_CODE_COLOR_SCHEME):

  • atom-one-light (default)

  • github

  • googlecode

  • xcode

  • vs

  • stackoverflow-light

  • gruvbox-light

  • solarized-light

Troubleshooting

"Printer not found"

Run lpstat -p in terminal to see exact printer names. They often have underscores instead of spaces.

"Permission denied"

Ensure CUPS is running: sudo cupsctl

"File format not supported"

Some file formats need to be converted to PDF before printing. Export to PDF from the original application or use a conversion tool.

"Chrome not found"

Chrome/Chromium is required for PDF rendering (markdown and code files). It should be auto-detected, but you can specify the path:

{
  "env": {
    "MCP_PRINTER_CHROME_PATH": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
  }
}

Code not rendering with syntax highlighting

  1. Ensure Chrome/Chromium is installed (required for PDF generation)

  2. Verify MCP_PRINTER_AUTO_RENDER_CODE is set to "true" (it's enabled by default)

  3. Check that the file extension is recognized (see Code Rendering)

  4. Verify MCP_PRINTER_CODE_EXCLUDE_EXTENSIONS does not include your file's extension

  5. Try setting a different color scheme if the current one isn't working

Code prints but with wrong colors/theme

The color scheme might not exist. Try these reliable options:

  • atom-one-light (default)

  • github

  • vs

  • xcode

Security

MCP Printer includes multiple security protections to prevent unauthorized file access and system modifications:

File Access Control

The server uses a secure-by-default approach with multiple layers of protection:

Default Allowed Directories

By default, printing is only allowed from these directories:

  • ~/Documents

  • ~/Downloads

  • ~/Desktop

This default configuration covers common use cases while being restrictive. You can configure additional directories as needed.

Universal Dotfile/Dotdir Blocking

All dotfiles and hidden directories are blocked from printing, with no way to override. This prevents access to:

  • ~/.ssh (SSH keys)

  • ~/.gnupg (GPG keys)

  • ~/.aws (AWS credentials)

  • ~/.config (application configurations)

  • .env files (environment variables)

  • Any file or directory starting with . (except . and ..)

This rule applies even if the path is within an allowed directory or specified via symlink. For example:

  • āŒ ~/Documents/.secrets.txt (blocked - dotfile)

  • āŒ ~/Documents/link → ~/.ssh/id_rsa (blocked - resolves to dotfile)

  • āœ… ~/Documents/report.pdf (allowed)

System Directory Protection

Common system directories are always blocked regardless of configuration, including:

  • /etc, /var, /root, /sys, /proc, /bin, /boot, /tmp, and more

  • /System, /Library, /private/etc, /private/var (macOS)

Custom Security Configuration

You can configure additional allowed paths for specific workflows using environment variables.

Important: When you set MCP_PRINTER_ALLOWED_PATHS, it completely overrides the default allowed directories. You must re-specify them if you want to keep them.

Environment Variable Expansion:

The MCP_PRINTER_ALLOWED_PATHS and MCP_PRINTER_DENIED_PATHS variables support environment variable expansion:

  • ~, $HOME, or ${HOME} expand to your home directory

Examples:

// Developer workflow - allow printing from source code directory
"env": {
  "MCP_PRINTER_ALLOWED_PATHS": "$HOME/Documents:$HOME/Downloads:$HOME/Desktop:$HOME/src"
}
// Shared workspace - print from external mount
"env": {
  "MCP_PRINTER_ALLOWED_PATHS": "$HOME/Documents:$HOME/Downloads:/mnt/shared"
}

Use colon (:) to separate multiple paths, just like the Unix PATH variable.

Additional denied paths can be specified and will be merged with system directory defaults:

"env": {
  "MCP_PRINTER_DENIED_PATHS": "/home/user/private:/home/user/secrets"
}

Management Operations

Management operations (set_default_printer and cancel_print_job) are disabled by default.

To enable them, set the environment variable:

{
  "mcpServers": {
    "Printer": {
      "command": "npx",
      "args": ["-y", "mcp-printer"],
      "env": {
        "MCP_PRINTER_ENABLE_MANAGEMENT": "true"
      }
    }
  }
}

Note: Only enable management operations if you understand the implications, as they can affect system-wide printer settings and other users' print jobs.

Other Security Features

  • Secure temporary files: All temporary files are created in randomly-named directories to prevent race conditions and symlink attacks

  • HTML injection protection: File paths are properly escaped when rendered to prevent script injection

  • Symlink protection: File paths are resolved to their real paths before validation to prevent bypassing security checks

Development

Setup

git clone https://github.com/steveclarke/mcp-printer.git
cd mcp-printer
pnpm install
pnpm run build

Commands

# Watch mode for development
pnpm run dev

# Build
pnpm run build

# Test locally
echo "Hello from MCP Printer Server!" > test.txt
# Then ask AI to print test.txt

Testing Markdown Rendering

The repository includes reference documents for testing markdown rendering:

Quick test (1 page):

# Print markdown-test-short.md
# Fast iteration during development
# Tests: formatting, code blocks, Mermaid, tables, math, page numbers

Comprehensive test (2-3 pages):

# Print markdown-reference.md
# Full feature verification
# Tests: all text formatting, multiple diagram types, complex code blocks,
#        blockquotes, nested lists, emoji, math equations, page numbering

Use these files to verify markdown rendering quality after making changes to the rendering pipeline.

Running Locally in MCP

Configure your MCP client to run from your local development directory:

{
  "mcpServers": {
    "Printer": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-printer/dist/index.js"],
      "env": {
        "MCP_PRINTER_DEFAULT_PRINTER": "Your_Printer_Name",
        "MCP_PRINTER_AUTO_DUPLEX": "true"
      }
    }
  }
}

Alternative Installation Methods

If you prefer not to use the npx approach in your MCP config, you can install the package globally first:

# npm
npm install -g mcp-printer

# pnpm
pnpm add -g mcp-printer

# yarn
yarn global add mcp-printer

Then reference it directly in your MCP config (without npx):

{
  "mcpServers": {
    "Printer": {
      "command": "mcp-printer"
    }
  }
}

Requirements

  • macOS or Linux - Uses CUPS printing system

    • macOS: CUPS is built-in

    • Linux: Install CUPS if not present (sudo apt install cups on Ubuntu/Debian)

    • Windows is not currently supported (contributions welcome!)

  • Node.js 22+

  • Google Chrome or Chromium - Required for both code and markdown PDF rendering (auto-detected)

    • Both Chrome and Chromium work equally well (same browser engine)

    • Auto-detection searches for: Chrome, Chromium, chromium-browser (Linux), Chrome Canary

    • Linux users: chromium or chromium-browser are fully supported

    • You can specify a custom path by setting MCP_PRINTER_CHROME_PATH

  • Printers configured in your system

Contributing

Contributions welcome! Areas for improvement:

  • Windows support (using Windows Print Spooler)

  • More print options

License

MIT

Available Tools

6 tools
get_configGet ConfigurationA

Get the current MCP Printer configuration settings. Returns environment variables and their current values.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, and the description only states 'Get' implying a read-only operation. It lacks explicit disclosure of side effects, permissions, or rate limits, but for a simple read tool the description is minimally adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that efficiently communicates the tool's purpose and output. Every word contributes value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has no parameters and no output schema, the description is mostly complete. It identifies the return type (environment variables), though it could specify the output format more precisely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has no parameters, so the input schema coverage is trivially 100%. The description adds no parameter-specific information beyond the schema, resulting in a baseline score of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves configuration settings, specifically environment variables and their values. This distinguishes it from sibling tools like get_default_printer or print_file.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implicitly indicates this tool is for viewing configuration, but it does not explicitly state when to use it over alternatives or provide any exclusion criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_default_printerGet Default PrinterB

Get the name of the default printer

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided. Description only says 'get the name' implying read-only, but does not disclose error handling (e.g., if no default printer exists) or return format details. Behavioral transparency is minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, no wasted words. Appropriately sized for a simple tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool is simple with no params and no output schema. Description covers the basic action but lacks edge case details (e.g., no default printer, response format). Could be slightly more complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters; schema coverage is 100%. Description adds no extra meaning beyond the schema, but baseline for 0 params is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool gets the name of the default printer. However, it does not explicitly differentiate from the sibling tool 'list_printers', which lists all printers. The purpose is clear but lacks explicit sibling distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives like list_printers. No context about prerequisites or when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_page_metaGet Page MetadataA

Get page count and physical sheet information for a file before printing. Pre-renders the file (if needed) and returns page metadata including page count and physical sheets required.

ParametersJSON Schema
NameRequiredDescriptionDefault
filesYesArray of files to get metadata for (use single-element array for one file)

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses that the tool may pre-render the file, which is a behavioral trait. However, with no annotations provided, it does not fully disclose potential side effects (e.g., temporary file creation, performance impact) or permissions required. It is moderately transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise at two sentences, front-loading the core purpose and adding one additional behavioral detail. Every sentence is essential and there is no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of the nested parameters and no output schema, the description covers the return values (page count, physical sheets) but does not specify the structure of the response (e.g., per file or aggregate). It is adequate but not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% coverage with descriptions for all parameters. The tool description does not add additional meaning beyond the schema; it only rephrases the return values. Baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: retrieving page count and physical sheet information for a file before printing. It uses specific verbs ('get', 'returns') and identifies the resource ('page metadata'). This distinguishes it from sibling tools like print_file or get_default_printer.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context ('before printing') but does not explicitly state when to use this tool versus alternatives, nor does it provide exclusions or conditions. There is no guidance on when not to use it or mention of sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_print_queueGet Print QueueA

Check the print queue for a specific printer or all printers. Shows pending and active print jobs.

ParametersJSON Schema
NameRequiredDescriptionDefault
printerNoPrinter name to check queue for (optional, checks all if not specified)

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden for behavioral disclosure. Description indicates a read operation showing jobs, but does not detail potential side effects, auth needs, rate limits, or return format. Adequate but minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. Front-loaded with key purpose and scope. Every sentence serves a clear function.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given low complexity (1 optional param, no output schema, no annotations), description covers core functionality. Lacks explicit mention of return structure but 'shows pending and active print jobs' implies list of job objects, adequate for simple query tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single parameter. Description adds that printer is optional and defaults to all, matching schema. Adds little beyond schema, baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the verb 'check', resource 'print queue', and scope 'specific printer or all printers'. It distinguishes from siblings like get_config or list_printers.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies usage for checking pending/active jobs but lacks explicit when-to-use or when-not-to-use guidance compared to alternatives. No mention of prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_printersList PrintersA

List all available printers on the system with their status. Returns printer names, states, and whether they're accepting jobs.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description bears full burden for behavioral disclosure. It accurately describes the read-only listing operation and expected output, but does not mention permissions, rate limits, or any other behavioral traits beyond the stated functionality.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two efficient sentences: first states the action and scope, second details the returned fields. No wasted words, front-loaded with key information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool is simple (0 params, no output schema) and annotations are absent, the description completely covers the purpose, scope, and return values. It is sufficient for an agent to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so the schema provides no information. The description compensates by explaining the return values (printer names, states, accepting jobs), adding meaning beyond the empty schema. Per guidelines, 0 params baseline is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'list', the resource 'printers', and the scope 'all available on system with status'. It specifies return values (names, states, accepting jobs), which distinguishes it from siblings like get_default_printer and get_print_queue.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives such as get_print_queue or get_default_printer. The description does not include when-not-to-use or any context for selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 8 tool updatesv1.0.0
    • Removedcancel_print_job
    • Addedget_config
    • Changedget_default_printer2 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
    • Addedget_page_meta
    • Changedget_print_queue2 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedlist_printers2 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedprint_file8 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / copies
        Removed value: -{
        -  "default": 1,
        -  "description": "Number of copies to print (default: 1)",
        -  "type": "number"
        -}
      • removedInput schema / properties / file_path
        Removed value: -{
        -  "description": "Full path to the file to print",
        -  "type": "string"
        -}
      • addedInput schema / properties / files
        Added value: +{
        +  "description": "Array of files to print (use single-element array for one file)",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "color_scheme": {
        +        "description": "Syntax highlighting color scheme for code files (e.g., 'github', 'monokai', 'atom-one-light')",
        +        "type": "string"
        +      },
        +      "copies": {
        +        "default": 1,
        +        "description": "Number of copies to print (default: 1)",
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "file_path": {
        +        "description": "Full path to the file to print",
        +        "type": "string"
        +      },
        +      "font_size": {
        +        "description": "Font size for code files (e.g., '8pt', '10pt', '12pt')",
        +        "type": "string"
        +      },
        +      "force_code_render": {
        +        "description": "Force code rendering to PDF with syntax highlighting (true=always render, false=never render, undefined=use config)",
        +        "type": "boolean"
        +      },
        +      "force_markdown_render": {
        +        "description": "Force markdown rendering to PDF (true=always render, false=never render, undefined=use config)",
        +        "type": "boolean"
        +      },
        +      "line_numbers": {
        +        "description": "Show line numbers when rendering code files (overrides global setting)",
        +        "type": "boolean"
        +      },
        +      "line_spacing": {
        +        "description": "Line spacing for code files (e.g., '1', '1.5', '2')",
        +        "type": "string"
        +      },
        +      "options": {
        +        "description": "Additional CUPS options (e.g., 'landscape', 'sides=two-sided-long-edge')",
        +        "type": "string"
        +      },
        +      "printer": {
        +        "description": "Printer name (use list_printers to see available printers). Optional if default printer is set.",
        +        "type": "string"
        +      },
        +      "skip_confirmation": {
        +        "description": "Skip page count confirmation check (bypasses MCP_PRINTER_CONFIRM_IF_OVER_PAGES threshold)",
        +        "type": "boolean"
        +      }
        +    },
        +    "required": [
        +      "file_path"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • removedInput schema / properties / options
        Removed value: -{
        -  "description": "Additional CUPS options (e.g., 'landscape', 'sides=two-sided-long-edge')",
        -  "type": "string"
        -}
      • removedInput schema / properties / printer
        Removed value: -{
        -  "description": "Printer name (use list_printers to see available printers). Optional if default printer is set.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "file_path"
        -]New value: +[
        +  "files"
        +]
    • Removedset_default_printer
  2. 6 tool updates
    • First observedcancel_print_job
    • First observedget_default_printer
    • First observedget_print_queue
    • First observedlist_printers
    • First observedprint_file
    • First observedset_default_printer

TDQS

A3.8/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose with no overlap: get_config retrieves settings, get_default_printer identifies the default printer, get_page_meta analyzes file metadata, get_print_queue monitors job status, list_printers enumerates available printers, and print_file handles actual printing. The descriptions make it easy for an agent to select the right tool without confusion.

Naming Consistency5/5

All tools follow a consistent verb_noun naming pattern (e.g., get_config, list_printers, print_file) using snake_case throughout. The verbs are appropriate and predictable (get, list, print), making the toolset easy to navigate and understand at a glance.

Tool Count5/5

With 6 tools, this server is well-scoped for printer management, covering configuration, discovery, queue monitoring, and printing operations. Each tool earns its place without feeling excessive or sparse, aligning perfectly with the domain's typical needs.

Completeness4/5

The toolset provides strong coverage for core printer operations, including listing, querying, and printing files. A minor gap exists in lifecycle management, such as tools for canceling print jobs or modifying printer settings, but agents can still handle most workflows effectively with the available tools.

Maintenance

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables users to connect Claude with various 3D printer management systems, allowing tasks like printer status monitoring, file management, print job control, and STL file manipulation.
    112
    GPL 2.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    A cross-platform MCP server that enables AI assistants to manage printers, query printer status, and print files on Windows, macOS, and Linux.
    14
    -
  • F
    license
    A
    quality
    B
    maintenance
    Enables LLM agents to control Bambu Lab 3D printers via the bambu-gateway HTTP API, supporting printer listing, filament management, print session creation, and safe print initiation with user confirmation.
    7
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables printing structured documents to ESC/POS thermal printers via a CUPS queue, with tools for printer info, print jobs, and template management.
    1
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/steveclarke/mcp-printer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server