Skip to main content
Glama

MCP Printer Server

by steveclarke
config.tsβ€’7.5 kB
import yn from "yn" import { homedir } from "os" import { join } from "path" import { parseDelimitedString } from "./utils.js" /** * Configuration interface for MCP Printer settings loaded from environment variables. */ export interface Config { /** Default printer name for print operations */ defaultPrinter: string /** Automatically enable duplex (two-sided) printing by default (can be overridden per-call) */ autoDuplex: boolean /** Default CUPS printing options (array of option strings) */ defaultOptions: string[] /** Path to Chrome/Chromium executable for PDF rendering */ chromePath: string /** Automatically render markdown files to PDF (can be overridden per-call) */ autoRenderMarkdown: boolean /** Automatically render code files to PDF with syntax highlighting (can be overridden per-call) */ autoRenderCode: boolean /** Enable management operations (set_default_printer, cancel_print_job) */ enableManagement: boolean /** Enable prompts (workflow templates that appear as slash commands) */ enablePrompts: boolean /** Fallback to printing original file if PDF rendering fails (for markdown and code) */ fallbackOnRenderError: boolean /** List of directory paths that files must be under to be accessible (merged with defaults) */ allowedPaths: string[] /** List of directory/file paths that are explicitly denied access (merged with defaults) */ deniedPaths: string[] /** Maximum number of copies allowed per print job (0 or negative means unlimited) */ maxCopies: number /** Threshold for page count confirmation. If physical sheets exceed this, print job returns preview instead. 0 = disabled. */ confirmIfOverPages: number /** Code rendering configuration */ code: { /** File extensions to exclude from code rendering. All enabled by default. */ excludeExtensions: string[] /** Highlight.js color scheme for syntax highlighting */ colorScheme: string /** Whether to automatically show line numbers in code rendering (can be overridden per-call) */ autoLineNumbers: boolean /** Font size for code rendering (e.g., "10pt") */ fontSize: string /** Line spacing for code rendering (e.g., "1.5") */ lineSpacing: string } } /** * Standard markdown file extensions. * These are the file extensions that will be treated as markdown files for rendering. */ export const MARKDOWN_EXTENSIONS = ["md", "markdown"] as const /** * Type representing valid markdown file extensions. */ export type MarkdownExtension = (typeof MARKDOWN_EXTENSIONS)[number] /** * Default configuration values. * These are used when environment variables are not set. */ const DEFAULT_PRINTER = "" const DEFAULT_AUTO_DUPLEX = false const DEFAULT_CHROME_PATH = "" const DEFAULT_AUTO_RENDER_MARKDOWN = true const DEFAULT_AUTO_RENDER_CODE = true const DEFAULT_ENABLE_MANAGEMENT = false const DEFAULT_ENABLE_PROMPTS = true const DEFAULT_FALLBACK_ON_RENDER_ERROR = false const DEFAULT_MAX_COPIES = 10 const DEFAULT_CONFIRM_IF_OVER_PAGES = 10 const DEFAULT_CODE_COLOR_SCHEME = "atom-one-light" const DEFAULT_CODE_AUTO_LINE_NUMBERS = true const DEFAULT_CODE_FONT_SIZE = "10pt" const DEFAULT_CODE_LINE_SPACING = "1.5" // Get home directory for security defaults const homeDir = homedir() // Default allowed paths - restricted to common user directories only const defaultAllowedPaths = [ join(homeDir, "Documents"), join(homeDir, "Downloads"), join(homeDir, "Desktop"), ] // Default denied paths (sensitive directories) // NOTE: This is a defense-in-depth measure. The primary security layer is the // universal dotfile blocking in validateFilePath() which catches most // credential stores. This deny list serves as a fallback to ensure system // directories are ALWAYS blocked. Even if you explicitly add these paths to // MCP_PRINTER_ALLOWED_PATHS, they will still be denied. These paths cannot be // overridden by any configuration. const defaultDeniedPaths = [ // Sensitive credential directories (most are also caught by dotfile blocking) join(homeDir, ".ssh"), join(homeDir, ".gnupg"), join(homeDir, ".aws"), join(homeDir, ".config", "gcloud"), // Standard Unix system directories "/bin", "/sbin", "/lib", "/lib64", "/usr/lib", "/usr/sbin", "/boot", "/dev", "/etc", "/proc", "/run", "/sys", "/var", "/tmp", "/root", // macOS specific system directories "/System", "/Library", "/private/etc", "/private/var", "/private/tmp", ] // Parse user-provided allowed paths from environment variable (colon-separated) and expand env vars const userAllowedPaths = parseDelimitedString(process.env.MCP_PRINTER_ALLOWED_PATHS, ":").map( expandEnvVars ) const hasUserPaths = userAllowedPaths.length > 0 // Parse user-provided denied paths from environment variable (colon-separated) and expand env vars const userDeniedPaths = parseDelimitedString(process.env.MCP_PRINTER_DENIED_PATHS, ":").map( expandEnvVars ) /** * Global configuration object loaded from environment variables. * Provides settings for printer defaults, rendering options, and code formatting. */ export const config: Config = { defaultPrinter: process.env.MCP_PRINTER_DEFAULT_PRINTER || DEFAULT_PRINTER, autoDuplex: yn(process.env.MCP_PRINTER_AUTO_DUPLEX, { default: DEFAULT_AUTO_DUPLEX }), defaultOptions: parseDelimitedString(process.env.MCP_PRINTER_DEFAULT_OPTIONS, /\s+/), chromePath: process.env.MCP_PRINTER_CHROME_PATH || DEFAULT_CHROME_PATH, autoRenderMarkdown: yn(process.env.MCP_PRINTER_AUTO_RENDER_MARKDOWN, { default: DEFAULT_AUTO_RENDER_MARKDOWN, }), autoRenderCode: yn(process.env.MCP_PRINTER_AUTO_RENDER_CODE, { default: DEFAULT_AUTO_RENDER_CODE, }), enableManagement: yn(process.env.MCP_PRINTER_ENABLE_MANAGEMENT, { default: DEFAULT_ENABLE_MANAGEMENT, }), enablePrompts: yn(process.env.MCP_PRINTER_ENABLE_PROMPTS, { default: DEFAULT_ENABLE_PROMPTS, }), fallbackOnRenderError: yn(process.env.MCP_PRINTER_FALLBACK_ON_RENDER_ERROR, { default: DEFAULT_FALLBACK_ON_RENDER_ERROR, }), // Use user-provided paths if set, otherwise use default allowed directories allowedPaths: hasUserPaths ? userAllowedPaths : [...defaultAllowedPaths], deniedPaths: [...defaultDeniedPaths, ...userDeniedPaths], maxCopies: parseInt(process.env.MCP_PRINTER_MAX_COPIES || String(DEFAULT_MAX_COPIES), 10), confirmIfOverPages: parseInt( process.env.MCP_PRINTER_CONFIRM_IF_OVER_PAGES || String(DEFAULT_CONFIRM_IF_OVER_PAGES), 10 ), code: { excludeExtensions: parseDelimitedString( process.env.MCP_PRINTER_CODE_EXCLUDE_EXTENSIONS, ",", (s) => s.toLowerCase() ), colorScheme: process.env.MCP_PRINTER_CODE_COLOR_SCHEME || DEFAULT_CODE_COLOR_SCHEME, autoLineNumbers: yn(process.env.MCP_PRINTER_CODE_AUTO_LINE_NUMBERS, { default: DEFAULT_CODE_AUTO_LINE_NUMBERS, }), fontSize: process.env.MCP_PRINTER_CODE_FONT_SIZE || DEFAULT_CODE_FONT_SIZE, lineSpacing: process.env.MCP_PRINTER_CODE_LINE_SPACING || DEFAULT_CODE_LINE_SPACING, }, } /** * Expands environment variables in a path string. * Supports $HOME, ${HOME}, and ~ expansion. * * @param path - Path that may contain environment variables * @returns Path with environment variables expanded */ function expandEnvVars(path: string): string { return path .replace(/^~/, homeDir) // Expand ~ at the start .replace(/\$HOME/g, homeDir) // Expand $HOME .replace(/\$\{HOME\}/g, homeDir) // Expand ${HOME} }

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