Pinboard MCP Server
The Pinboard MCP Server provides read-only access to your Pinboard.in bookmarks, enabling LLMs to search, filter, and retrieve bookmark data.
search_bookmarks: Search across bookmark titles, notes, and tags using a query string, with a focus on recent bookmarks; supports up to 100 results.search_bookmarks_extended: Comprehensive historical search across titles, notes, and tags over a configurable period (up to 730 days); supports up to 200 results.list_recent_bookmarks: Retrieve bookmarks saved within the last N days (up to 30), with a configurable result limit (up to 100).list_bookmarks_by_tags: Filter bookmarks by 1–3 tags, with optionalfrom_date/to_daterange filtering and up to 200 results.list_tags: Retrieve all user-defined tags with their usage counts.
Additional features: smart LRU caching with automatic invalidation, rate limiting (3-second delay between API calls) to respect Pinboard's guidelines, intuitive field name mapping (e.g., description → title), and secure API token handling via environment variables.
Provides read-only access to Pinboard.in bookmarks with tools for searching, filtering, and retrieving bookmark metadata, including the ability to search bookmarks by query, list recent bookmarks, filter bookmarks by tags with date ranges, and list tags with usage counts.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Pinboard MCP Serversearch for python machine learning bookmarks"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Pinboard MCP Server
Read-only access to Pinboard.in bookmarks for LLMs via Model Context Protocol (MCP).
Overview
This server provides LLMs with the ability to search, filter, and retrieve bookmark metadata from Pinboard.in at inference time. Built on FastMCP 2.0, it offers four core tools for bookmark interaction while respecting Pinboard's rate limits and implementing intelligent caching.
Related MCP server: Readwise MCP HTTP Server
Features
Read-only access to Pinboard bookmarks
Five MCP tools:
search_bookmarks,search_bookmarks_extended,list_recent_bookmarks,list_bookmarks_by_tags,list_tagsSmart caching with LRU cache and automatic invalidation using
posts/updateendpointRate limiting respects Pinboard's 3-second guideline between API calls
Field mapping converts Pinboard's legacy field names to intuitive ones (description→title, extended→notes)
Comprehensive testing with integration test harnesses and CI validation
Installation
Via pip (recommended)
pip install pinboard-bookmarks-mcp-serverFrom source
git clone https://github.com/rossshannon/pinboard-bookmarks-mcp-server.git
cd pinboard-bookmarks-mcp-server
pip install -e .Quick Start
Get your Pinboard API token from https://pinboard.in/settings/password
Set environment variable:
export PINBOARD_TOKEN="username:1234567890ABCDEF"Start the server:
pinboard-mcp-serverVerify it's working:
# Test help command (works without token) pinboard-mcp-server --help # Server should show "Starting MCP server" when run with token
Usage with Claude Desktop
Add this configuration to your Claude Desktop settings:
{
"mcpServers": {
"pinboard": {
"command": "pinboard-mcp-server",
"env": {
"PINBOARD_TOKEN": "your-username:your-token-here"
}
}
}
}Available Tools
1. search_bookmarks
Search bookmarks by query string across titles, notes, and tags. Recent-focused with automatic expansion.
Parameters:
query(string): Search querylimit(int, optional): Maximum results (default: 20, max: 100)
Example:
Search for "python testing" bookmarks2. search_bookmarks_extended
Extended search for comprehensive historical results across titles, notes, and tags.
Parameters:
query(string): Search querydays_back(int, optional): How many days back to search (default: 365, max: 730)limit(int, optional): Maximum results (default: 100, max: 200)
Example:
Search the last 2 years for "kubernetes" bookmarks3. list_recent_bookmarks
List bookmarks saved in the last N days.
Parameters:
days(int, optional): Days to look back (default: 7, max: 30)limit(int, optional): Maximum results (default: 20, max: 100)
Example:
Show me bookmarks from the last 3 days4. list_bookmarks_by_tags
List ALL bookmarks filtered by tags with optional date range. Most efficient for historical access.
Parameters:
tags(array): List of tags to filter by (1-3 tags)from_date(string, optional): Start date in ISO format (YYYY-MM-DD)to_date(string, optional): End date in ISO format (YYYY-MM-DD)limit(int, optional): Maximum results (default: 100, max: 200)
Example:
Find bookmarks tagged with "python" and "api" from January 20245. list_tags
List all tags with their usage counts.
Example:
What are my most used tags?Configuration
Environment Variables
PINBOARD_TOKEN(required): Your Pinboard API token in formatusername:token
Rate Limiting
The server automatically enforces a 3-second delay between Pinboard API calls to respect their guidelines. Cached responses are returned immediately.
Caching Strategy
Query cache: LRU cache with 1000 entries for search results
Bookmark cache: Full bookmark list cached for 1 hour
Cache invalidation: Uses
posts/updateendpoint to detect changesTag cache: Tag list cached until manually refreshed
Testing
The project includes comprehensive test coverage with multiple test strategies:
Run all tests
# Activate virtual environment first
source ~/.venvs/pinboard-bookmarks-mcp-server/bin/activate
# Run all tests with coverage
pytest --cov=src --cov-report=term-missingReal API testing
# Set your Pinboard token
export PINBOARD_TOKEN="username:token"
# Run debug utility to test search functionality (development only)
PINBOARD_TOKEN="username:token" python tests/debug_bookmarks.pyMock API testing
# Run comprehensive test suite (development only)
python -m pytest tests/ -vDevelopment
Setup
# Clone and setup
git clone https://github.com/rossshannon/pinboard-bookmarks-mcp-server.git
cd pinboard-bookmarks-mcp-server
# Quick development setup
./scripts/dev-setup.shCode Quality
# Activate environment
source ~/.venvs/pinboard-bookmarks-mcp-server/bin/activate
# Linting and formatting
ruff check src/ tests/
ruff format src/ tests/
# Type checking
mypy src/
# Run tests
pytest -v
# Build package
./scripts/build.shArchitecture
FastMCP 2.0: MCP scaffolding with Tool abstraction and async FastAPI server
pinboard.py: Pinboard API client wrapper with error handling
Pydantic: Data validation and serialization with JSON Schema
ThreadPoolExecutor: Bridges async MCP with sync pinboard.py library
LRU Cache: In-memory caching with intelligent invalidation
Key Files
src/pinboard_mcp_server/main.py- MCP server entry point and tool implementationssrc/pinboard_mcp_server/client.py- Pinboard API client with cachingsrc/pinboard_mcp_server/models.py- Pydantic data modelstests/- Comprehensive test suitetests/debug_bookmarks.py- Debug utility for testing search functionalitydocs/TEST_HARNESS.md- Documentation for test harnesses
Performance
P50 response time: <250ms (cached responses)
P95 response time: <600ms (cold cache)
Rate limiting: 3-second intervals between API calls
Cache hit ratio: >90% for typical usage patterns
Security
API tokens are never logged or exposed in error messages
Read-only access to Pinboard data
Input validation on all tool parameters
Secure environment variable handling
Troubleshooting
Common Issues
"PINBOARD_TOKEN environment variable is required"
Make sure you've set your token:
export PINBOARD_TOKEN="username:token"Get your token from https://pinboard.in/settings/password
Token format should be:
username:1234567890ABCDEF
"Command not found: pinboard-mcp-server"
Ensure you've installed the package:
pip install pinboard-bookmarks-mcp-serverCheck your Python environment is activated
Try reinstalling:
pip uninstall pinboard-bookmarks-mcp-server && pip install pinboard-bookmarks-mcp-server
Server starts but Claude Desktop can't connect
Verify the MCP configuration in Claude Desktop settings
Check that the
commandpath is correct:pinboard-mcp-serverEnsure the
PINBOARD_TOKENis set in theenvsection
"Permission denied" or "Access denied" errors
Verify your Pinboard token is valid and active
Check you have internet connectivity to reach pinboard.in
Test your token manually at https://pinboard.in/api/v1/posts/recent
Contributing
Fork the repository
Create a feature branch (
git checkout -b feature/amazing-feature)Make your changes with tests
Ensure all tests pass and code is formatted
Submit a pull request
License
MIT License - see LICENSE file for details.
Available Tools
5 toolslist_bookmarks_by_tagsA
List ALL bookmarks filtered by tags and optional date range.
Args:
tags: List of tags to filter by (1-3 tags)
from_date: Start date in ISO format (YYYY-MM-DD), optional
to_date: End date in ISO format (YYYY-MM-DD), optional
limit: Maximum number of results to return (1-200, default 100)
Note: Gets ALL bookmarks with specified tags, regardless of age.
Very efficient for tag-based searches. Provides generous data for analysis.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | Yes | ||
| from_date | No | ||
| to_date | No | ||
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It mentions efficiency and generous data but lacks details on ordering, pagination behavior, rate limits, or potential side effects. As a read operation, the safety profile is implicitly clear, but more behavioral context would be beneficial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with a clear purpose line followed by a structured Args section. Every sentence adds value, and it is front-loaded with the main action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does not describe return format or structure, only vaguely stating 'generous data for analysis.' For a tool with 4 parameters, more detail on output (e.g., list of bookmark objects) would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, yet the description fully explains each parameter: tags (1-3 tags), from_date/to_date (ISO format, optional), limit (1-200, default 100). This adds essential meaning beyond the schema titles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List ALL bookmarks filtered by tags and optional date range,' specifying the verb (list) and resource (bookmarks) with filtering context. This distinguishes it from siblings like list_recent_bookmarks and search_bookmarks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description notes that it gets all bookmarks regardless of age and is efficient for tag-based searches, implying when to use. However, it does not explicitly state when not to use or compare to alternatives like search_bookmarks for full-text searches.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_recent_bookmarksA
List bookmarks saved in the last N days.
Args:
days: Number of days to look back (1-30, default 7)
limit: Maximum number of results to return (1-100, default 20)
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | ||
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Describes input parameters and default behavior. Without annotations, it adequately indicates a read-only operation listing bookmarks, though no mention of authorization or side effects is needed for this simple list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise two-line summary followed by clear parameter descriptions in Args format. No extraneous content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequate for a simple list tool with two parameters. Missing output schema description, but the format is standard and expectable. Could mention ordering (e.g., by date).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaning beyond the schema: 'days' is explained as lookback period, 'limit' as max results. Schema has no descriptions, so the description compensates effectively.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states action (list), resource (bookmarks), and time constraint (last N days). Distinguishes from sibling tools like list_bookmarks_by_tags and search_bookmarks by its specific scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implicitly tells when to use (when needing recent bookmarks). Does not explicitly mention when not to use or alternatives like search_bookmarks for more complex queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tagsA
List all tags with their usage counts.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, placing the burden on the description. The description states that the tool lists tags with counts but does not disclose whether it is read-only, potential ordering, or pagination behavior. However, for a simple 0-parameter list, 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that is front-loaded with the verb and resource. Every word is necessary and there is no superfluous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters, no output schema, and a straightforward purpose, the description is largely complete. It specifies what is returned (tags with usage counts). A minor improvement would be to mention ordering or that the list includes all tags, but overall sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has no parameters, and schema description coverage is 100%. The description does not need to add parameter semantics since there are none. The baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: listing all tags along with their usage counts. It uses a specific verb ('list') and resource ('tags'), differentiating it from sibling tools which deal with bookmarks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implicitly indicates when to use this tool (when you need a list of all tags and their usage counts). No explicit when-not or alternatives are provided, but the sibling tools have distinctly different purposes, so confusion is unlikely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_bookmarksA
Search bookmarks by query string across titles, notes, and tags (recent focus).
Args:
query: Search query to match against bookmark titles, notes, and tags
limit: Maximum number of results to return (1-100, default 20)
Note: Searches recent bookmarks first, expands automatically if needed.
For comprehensive historical search, use search_bookmarks_extended.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided. The description discloses behavioral traits: prioritizes recent bookmarks and automatically expands search if needed. This adds value beyond a simple search description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Compact two-sentence description plus a note. First sentence states purpose, then args, then behavioral note. Every sentence is essential, no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With only 2 simple params, no output schema, and no annotations, the description fully covers purpose, input semantics, behavioral nuance (recent focus, expansion), and usage alternatives. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has only titles/types with 0% description coverage. The description adds full meaning: query matches against titles, notes, tags; limit is max results (1-100, default 20), fully compensating for the schema's lack of descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it searches bookmarks by query across titles, notes, and tags, and explicitly differentiates from sibling search_bookmarks_extended via 'recent focus' and 'comprehensive historical search'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Searches recent bookmarks first' and provides alternative 'For comprehensive historical search, use search_bookmarks_extended', giving clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_bookmarks_extendedA
Extended search for comprehensive historical results across titles, notes, and tags.
Args:
query: Search query to match against bookmark titles, notes, and tags
days_back: How many days back to search (1-730, default 365 = 1 year)
limit: Maximum number of results to return (1-200, default 100)
Note: Provides comprehensive results while being mindful of server load.
Use tag-based searches for most efficient access to historical bookmarks.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| days_back | No | ||
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It describes the search scope and parameter ranges but lacks details on ordering, pagination, side effects, or read-only behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise with a clear purpose statement, an Args block, and a practical note. No extraneous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with 3 parameters and no output schema, the description covers purpose, parameter details, and a usage tip. It lacks output format or error handling, but is fairly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description adds meaning by clarifying that 'query' matches against titles, notes, and tags, and specifies valid ranges for 'days_back' and 'limit'. This goes beyond the schema's default and type information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Extended search for comprehensive historical results across titles, notes, and tags.' This clearly identifies the tool as a comprehensive search variant, distinguishing it from simpler siblings like 'search_bookmarks'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides guidance to use tag-based searches for efficiency and mentions being mindful of server load. However, it does not explicitly compare with 'search_bookmarks' or state when not to use this tool.
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.
5 tool updates
- First observed
list_bookmarks_by_tags - First observed
list_recent_bookmarks - First observed
list_tags - First observed
search_bookmarks - First observed
search_bookmarks_extended
TDQS
Scored across 5 tools
Each tool has a distinct purpose: listing by tags, recent bookmarks, tag counts, and two search variants differentiated by scope (recent vs. historical). Minimal overlap.
All tools follow a consistent verb_noun pattern: 'list_' for listing and 'search_' for searching, with descriptive suffixes. No style mixing.
5 tools for a bookmark server is a reasonable count, though the set lacks write operations like add/delete. Still well-scoped for a query-focused service.
The tool set covers only read and search operations. Missing essential CRUD actions (create, update, delete bookmarks), which are typical for bookmark management.
Maintenance
Related MCP Connectors
Your portable context layer — load it into any AI.
Personal context for every AI: search, read, and write back to your private Markdown library.
AI research library. Save, organise and reuse notes and webpages as clean markdown context.
Compact, citation-verifiable public web context for AI agents, paid per use with x402.
Related MCP Servers
- FlicenseBqualityFmaintenanceAn integration that allows Large Language Models to interact with Raindrop.io bookmarks through the Model Context Protocol, enabling users to create and search bookmarks directly through AI assistants.375-
- AlicenseAqualityBmaintenanceEnables searching and accessing Readwise highlights and documents through HTTP endpoints using the Model Context Protocol. Provides vector and full-text search capabilities with streaming responses for retrieving reading highlights and notes.171MIT
- FlicenseNot gradedqualityFmaintenanceEnables users to access and manage their Pinboard bookmarks directly through Claude Desktop. Supports retrieving, adding, and updating bookmarks with date filtering, tagging, and bookmark analysis capabilities.9-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to access and manage Raindrop.io bookmarks, collections, tags, and highlights through the Model Context Protocol. Supports CRUD operations, advanced search, file uploads, and bulk editing of bookmarks.44 npmMIT