Labsco
cmeans logo

clipboard-mcp

ā˜… 4

from cmeans

MCP server that reads and writes the system clipboard — tables, text, code, JSON, URLs, images, and more. Preserves spreadsheet structure (rows/columns) that is lost when pasting into Claude directly. Claude can also write results back to your clipboard.

šŸ”„šŸ”„šŸ”„āœ“ VerifiedFreeQuick setup

mcp-clipboard logo

mcp-clipboard

Downloads

pip downloads pipenv downloads pipx downloads uv downloads poetry downloads pdm downloads

linux downloads macos downloads windows downloads

An MCP server that gives your AI assistant direct access to your system clipboard: read what you copied, or write clean text straight to it. Works with any MCP-compatible client, including Claude Code, Claude Desktop, Cursor, Windsurf, and others.

Why This Exists

Pasting loses structure

When you copy cells from Google Sheets or Excel and paste into a chat input, the tabular structure (rows and columns) is destroyed. It arrives as a flat string with no delimiters. The model has to guess where one cell ends and the next begins, and it often guesses wrong.

mcp-clipboard preserves it. Instead of pasting, tell your assistant to "read my clipboard." The server reads the clipboard directly, detects tabular data from the HTML that spreadsheet apps put on the clipboard, and returns it as a properly formatted Markdown table, JSON, or CSV. No structure lost, no guessing.

Bonus: it also fixes copying from Claude Code

Claude Code's terminal renderer adds 2-character padding, hard line breaks at ~80 columns, and trailing whitespace to all output. When you select and copy text from the terminal, those artifacts come along for the ride:

  echo "this is a long command that wraps and
  breaks when you paste it because of the hard
  newlines and leading spaces"

This has been reported repeatedly on the claude-code repo (issues #4686, #6827, #7670, #13378, #15199, #25040, #25427, #26016) with dozens of upvotes and no fix shipped.

mcp-clipboard sidesteps the problem entirely. Instead of copying text from the terminal, ask Claude Code to put it on your clipboard:

"Copy that command to my clipboard"

Claude Code calls clipboard_copy, writes the clean text directly to your system clipboard, and you paste it wherever you need it. No padding, no hard wraps, no cleanup.

Tip: To make this automatic, add a line to your project or global CLAUDE.md:

When you produce a shell command for the user to run, also copy it to the clipboard using clipboard_copy.

Claude Code will then copy every command it suggests without you having to ask.

Bonus: read your X11/Wayland selection without Ctrl-C

Linux desktops have two clipboards: the CLIPBOARD that Ctrl-C / Ctrl-V uses, and the PRIMARY selection. PRIMARY is whatever text you currently have highlighted, pasted by middle-click. It updates as soon as you select something; you don't have to copy it.

mcp-clipboard reads PRIMARY too. Pass selection="primary" to clipboard_paste, clipboard_read_raw, or clipboard_list_formats and the server reads the selection buffer instead of the Ctrl-C clipboard. Some workflows this enables:

  • Terminal triage. An error message scrolls past, mouse-select it, ask the model what it means. Your Ctrl-C buffer stays intact for whatever you had on it.
  • vim / IDE visual selection. v-select a function, ask the model to explain it or refactor it.
  • Browser / PDF reading. Drag-select a paragraph, ask "what's this saying?" without leaving the reading flow.
  • Two-buffer workflows. Keep a snippet in CLIPBOARD (Ctrl-C) and pull a different one through PRIMARY in the same conversation.

Linux only. macOS and Windows have no equivalent buffer; passing selection="primary" on those platforms returns a clear error.

Tools

ToolDescription
clipboard_pastePrimary tool. Read any clipboard content: tables, text, code, JSON, URLs, images. Tables are formatted as Markdown/JSON/CSV; pass include_schema=true to append inferred column types. Images are returned as image content the model can see. Optional selection="primary" reads the X11/Wayland PRIMARY selection (middle-click / select-text-to-paste buffer) instead of the default Ctrl-C clipboard.
clipboard_copyWrite text content to the system clipboard. Accepts an optional mime_type parameter (text/plain by default; also text/html, text/rtf, image/svg+xml, or any text/* on Wayland/X11).
clipboard_copy_markdownRender markdown to HTML and place both formats on the clipboard so paste targets pick the right one — Slack/Gmail/Notion/Discord get rich text; vim/terminal get the source. macOS/Windows write both atomically; Wayland/X11 are single-MIME and write only text/html.
clipboard_copy_imageWrite a PNG or JPEG image to the system clipboard from base64-encoded bytes. Pass-through with no re-encoding; magic bytes are validated against the declared MIME. Use clipboard_copy for text.
clipboard_list_formatsList what MIME types are currently on the clipboard. Accepts selection="primary" for the X11/Wayland PRIMARY selection.
clipboard_read_rawReturn raw clipboard content for a given MIME type (diagnostic). Any non-binary type passes through; only image/*, audio/*, video/*, and application/octet-stream are rejected. Use clipboard_paste for images. Accepts selection="primary" for the X11/Wayland PRIMARY selection.
clipboard_versionReturn the running mcp-clipboard package version as {"name": "mcp-clipboard", "version": "<x.y.z>"}. Diagnostic. Useful for hosts that don't surface the standard MCP serverInfo block to the model, and for test harnesses that need to record which build served a given run.

Content handling

Content typeWhat happens
Spreadsheet tableParsed from HTML/TSV, returned in your choice of format (Markdown, JSON, CSV, Slack, Jira, HTML, Notion)
JSONPretty-printed in a JSON code block
CodeReturned in a fenced code block
URLReturned cleanly as a URL
Rich HTML (no table)HTML tags stripped, readable text returned
RTFReturned in a fenced code block (macOS, Windows, and Wayland/X11 via pass-through)
Plain textReturned as-is
Images (PNG, etc.)Returned as an MCP image content block the model can see and analyze
SVGReadable as text via clipboard_read_raw with image/svg+xml, or returned as image via clipboard_paste. Writable via clipboard_copy(mime_type="image/svg+xml") — apps that consume SVG (Inkscape, Figma, browsers) get the image. On Wayland, wl-copy automatically also advertises text/plain, so editors get the source for free. On X11 / macOS / Windows the SVG-only path is single-MIME — non-SVG-aware apps will not see any text fallback until multi-format simultaneous write lands (#109).
Audio / videoNot supported; returns a message identifying the format

How It Works

  1. Platform detection: At startup, the server detects your clipboard backend (Wayland, X11, macOS, or Windows) and selects the appropriate system commands.
  2. Reading (clipboard_paste): Calls the platform's clipboard read command. Tries text/html first (Google Sheets and Excel put <table> markup on the clipboard), parses with Python's built-in html.parser. Falls back to text/plain tab-separated values, then text/rtf, then checks for images.
  3. Writing text (clipboard_copy): Pipes text to the platform's clipboard write command (wl-copy, xclip -selection clipboard, pbcopy, or PowerShell Set-Clipboard). Supports a mime_type parameter for writing typed content (e.g. text/html, text/rtf, image/svg+xml).
  4. Writing images (clipboard_copy_image): Decodes base64 PNG or JPEG bytes and writes them to the platform's clipboard via wl-copy --type, xclip -target, NSPasteboard setData:forType: (macOS), or Clipboard::SetImage (Windows). Magic bytes are validated against the declared MIME type before any subprocess runs.
  5. Image passthrough on read: If the clipboard contains an image (PNG, etc.), it's returned as a base64-encoded MCP image content block that the model can see and analyze.
  6. Content classification: Non-tabular text content is classified as JSON, URL, code, or plain text and returned with appropriate formatting (pretty-printed JSON, fenced code blocks, etc.).

Development

# Install with dev dependencies
uv sync --extra dev

# Run tests
uv run pytest

# Run the server directly (stdio mode)
uv run mcp-clipboard

# Run with debug logging
uv run mcp-clipboard --debug

# Test with MCP Inspector
uv run mcp dev src/mcp_clipboard/server.py

Debug logging can also be enabled via MCP_CLIPBOARD_DEBUG=1, which is useful when the server is launched by Claude Desktop or Claude Code.

Project structure

mcp-clipboard/
ā”œā”€ā”€ src/mcp_clipboard/
│   ā”œā”€ā”€ __init__.py          # Package version
│   ā”œā”€ā”€ server.py            # MCP server, tool definitions, debug logging
│   ā”œā”€ā”€ clipboard.py         # Platform-agnostic clipboard backend
│   ā”œā”€ā”€ parser.py            # HTML table parser, formatters, content detection
│   ā”œā”€ā”€ instructions/        # Tool and server descriptions (loaded at startup)
│   │   ā”œā”€ā”€ server.md
│   │   ā”œā”€ā”€ clipboard_copy.md
│   │   ā”œā”€ā”€ clipboard_copy_image.md
│   │   ā”œā”€ā”€ clipboard_copy_markdown.md
│   │   ā”œā”€ā”€ clipboard_paste.md
│   │   ā”œā”€ā”€ clipboard_read_raw.md
│   │   ā”œā”€ā”€ clipboard_list_formats.md
│   │   └── clipboard_version.md
│   └── icons/               # SVG icons for MCP client display (light/dark)
│       ā”œā”€ā”€ mcp-clipboard-logo-light.svg
│       └── mcp-clipboard-logo-dark.svg
ā”œā”€ā”€ tests/
│   ā”œā”€ā”€ test_parser.py       # Parser and formatter tests
│   └── test_server.py       # Server, backend, and Wayland detection tests
ā”œā”€ā”€ .github/
│   ā”œā”€ā”€ workflows/
│   │   ā”œā”€ā”€ publish.yml      # PyPI publish on v* tags (OIDC trusted publisher)
│   │   └── test-publish.yml # TestPyPI publish on test-v* tags
│   └── ISSUE_TEMPLATE/      # Bug report, feature request, platform test forms
ā”œā”€ā”€ pyproject.toml
ā”œā”€ā”€ CHANGELOG.md
ā”œā”€ā”€ CLAUDE.md                # Claude Code project guidance
ā”œā”€ā”€ LICENSE                  # Apache 2.0
└── README.md