mcp-shlink
This server provides MCP tools to manage Shlink short URLs and tags.
Create shortened URLs with optional custom slug, tags, max visits, and expiration (valid_until).
List all shortened URLs with pagination info.
Get details of a specific short URL by short code, including metadata and visit count.
Delete shortened URLs by short code.
List all tags with their associated short URL counts.
Retrieve server metrics: per-tool call counts, error counts, and latency.
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., "@mcp-shlinkCreate a short URL for https://www.example.com with slug 'my-link'"
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.
mcp-shlink
A Model Context Protocol (MCP) server for Shlink link shortening service. This server exposes Shlink's URL shortening, management, and tagging capabilities as MCP tools for AI assistants.
Features
Create shortened URLs with custom slugs, tags, and expiration
List all shortened URLs with pagination info
Get details of specific URLs by short code
Delete shortened URLs
List and manage tags
Full type safety with Pydantic models
Built with the official MCP Python SDK
Related MCP server: DWZ Short URL MCP Server
Requirements
Python >= 3.10
A Shlink instance with API access
Installation
pip install mcp-shlinkConfiguration
Copy .env.example to .env (gitignored) or export the variables directly:
Variable | Description | Required |
| Your Shlink instance base URL (e.g., | Yes |
| Your Shlink API key | Yes |
| Environment name shown in logs (default: | No |
| Opt-in anonymous tool usage events (default: | No |
| Optional HTTP collector for usage events | No |
| Opt-in Sentry error tracking (see below) | No |
| Feature flags (see Features & flags) | No |
Generate an API key in Shlink:
shlink api-key:generate --name=my_api_keyFeatures & flags
Risky behavior ships behind environment-driven feature flags (default OFF):
Flag | Env override | Purpose |
|
| Retry Shlink 5xx/connection errors with exponential backoff |
|
| Stage deletions behind a confirmation step |
|
| Anonymous tool usage events |
Observability
Structured logging: one JSON line per event on stderr, including
trace_id,request_id,environment, and per-toolduration_ms. Credentials, tokens, and URLs are redacted automatically.Metrics: the built-in
get_metricstool reports per-tool call counts, error counts, and latency (mean/p95/max); metrics are also dumped at shutdown.Error tracking: set
SENTRY_DSNto enable Sentry (full stack traces with environment context). Install withpip install "mcp-shlink[error-tracking]".
Documentation
Architecture & service dependencies (generated diagram, verified in CI)
Runbooks (incident response)
Secrets management (policy and enforcement)
Usage
Running as a standalone MCP server
SHLINK_BASE_URL=https://shlink.example.com SHLINK_API_KEY=your-key python -m mcp_shlink.serverInstalling into Claude Desktop
uv run mcp install src/mcp_shlink/server.py --name "shlink"Running with MCP Inspector
SHLINK_BASE_URL=https://shlink.example.com SHLINK_API_KEY=your-key uv run mcp dev src/mcp_shlink/server.pyAvailable Tools
Tool | Description |
| Create a new shortened URL |
| List all shortened URLs |
| Get details of a URL by short code |
| Delete a shortened URL |
| List all tags |
| Server metrics: per-tool calls, errors, latencies |
Development
# Clone the repository
git clone https://github.com/magnus919/mcp-shlink
cd mcp-shlink
# Install in development mode
pip install -e ".[dev]"
# Install pre-commit hooks
pre-commit install
# Run tests (unit + integration, parallel, 80% coverage gate)
pytest
# Lint and format
ruff check .
ruff format .
# Type check
mypy src/
# Full verification
ruff check . && ruff format . --check && mypy src/ && pytestIntegration tests run against a local Shlink stub (tests/shlink_stub_server.py);
no real Shlink instance is needed.
Local interactive QA
You can exercise the full tool surface without a real Shlink deployment:
# 1. Start the local Shlink stub API
SHLINK_API_KEY=changeme python -m tests.shlink_stub_server --port 8765
# 2. Drive the MCP server with MCP Inspector against the stub
SHLINK_BASE_URL=http://127.0.0.1:8765 SHLINK_API_KEY=changeme \
uv run mcp dev src/mcp_shlink/server.pyInvoke any of the five tools in the Inspector UI; all are safe against the stub.
Project Structure
src/mcp_shlink/
├── server.py # FastMCP server entry point
├── client.py # Shlink API client
├── tools.py # MCP tool definitions
├── models.py # Pydantic models for API requests/responses
├── config.py # Typed settings loaded from environment
├── observability.py # Structured logs, redaction, trace ids, metrics
├── features.py # Feature flag registry
└── analytics.py # Opt-in anonymous usage events
tests/ # Unit + integration tests (local Shlink stub)
scripts/ # CI/pre-commit helper scripts
docs/ # Architecture, runbooks, secrets policyLicense
Apache 2.0. See LICENSE.
Available Tools
5 toolscreate_short_urlC
Create a new shortened URL in Shlink.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | ||
| long_url | Yes | ||
| max_visits | No | ||
| custom_slug | No | ||
| valid_until | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| tags | No | Associated tags |
| long_url | Yes | The original long URL |
| short_url | Yes | The shortened URL |
| short_code | Yes | The short code |
| date_created | Yes | Creation date in ISO 8601 format |
| visits_count | Yes | Number of visits |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavioral traits. It only mentions 'create', which implies mutation, but lacks details about permanence, reversibility, or any side effects. This is insufficient for an agent to understand the tool's 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 very short (8 words), but it sacrifices necessary information. Conciseness should retain key details; here, it omits parameter context and usage guidance. The single sentence is front-loaded but too terse.
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 5 parameters (one required) and an existing output schema, the description is severely incomplete. It does not mention parameters, output format, or any constraints. The agent lacks essential context to invoke this tool correctly.
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 5 parameters with 0% description coverage, meaning the description does not clarify any parameter meanings. It only says 'Create a new shortened URL', which adds no semantic value beyond what the parameter names imply. The description fails to compensate for the lack of schema 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?
The description clearly states the action ('Create') and the resource ('shortened URL'), with the context 'in Shlink'. It is specific enough to understand the tool's basic purpose, but does not differentiate from sibling tools like list_short_urls or delete_short_url.
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 no guidance on when to use this tool versus alternatives, such as when to use get_short_url or list_short_urls. It simply states the action without context for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_short_urlC
Delete a shortened URL by its short code.
| Name | Required | Description | Default |
|---|---|---|---|
| short_code | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description gives no behavioral details such as whether deletion is permanent, side effects, or authentication requirements. This is a critical gap.
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 sentence with no extraneous information. It is appropriately concise and front-loaded.
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 low schema coverage and absence of annotations, the description fails to provide sufficient context. It does not explain the output schema, error cases, or idempotency, leaving the agent underinformed.
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% and the description adds no additional meaning beyond the parameter name 'short_code'. It merely restates what is obvious from the schema.
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 action (delete), resource (shortened URL), and method (by short code). It distinguishes from sibling tools like create_short_url and list_short_urls.
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 no guidance on when to use this tool versus alternatives. There is no mention of prerequisites, when not to use it, or comparison to siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_short_urlA
Get details of a shortened URL by its short code.
| Name | Required | Description | Default |
|---|---|---|---|
| short_code | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | No | URL metadata |
| tags | No | Associated tags |
| long_url | Yes | The original long URL |
| short_url | Yes | The shortened URL |
| short_code | Yes | The short code |
| date_created | Yes | Creation date in ISO 8601 format |
| visits_count | Yes | Number of visits |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description bears full burden. It only says 'Get details' without disclosing read-only nature, any side effects, permissions, or rate limits. Minimal transparency.
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?
Single sentence with no extraneous words; concise and front-loaded.
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 low complexity, single parameter, and existing output schema, description is adequate. Could mention what 'details' entail but not essential.
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?
Despite 0% schema coverage, the description explains that 'short_code' is the identifier used to retrieve details, adding meaning beyond the schema's type and title.
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 verb 'Get' and the resource 'shortened URL', and specifies the identifier 'short code', distinguishing itself from sibling tools like create, delete, and list.
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?
No guidance on when to use this tool vs alternatives; does not compare to list_short_urls or explain what 'details' means, leaving ambiguity for the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_short_urlsB
List all shortened URLs in Shlink.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| pagination | Yes | Pagination info |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description must disclose behavioral traits. It only states 'list all' implying a read operation, but fails to mention pagination, rate limits, or potential performance implications. No safety or side-effect details are given.
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, short, front-loaded sentence with no extraneous information. It efficiently conveys the core purpose.
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's simplicity (no parameters, output schema present), the description is largely adequate. However, it could improve by clarifying if the list is paginated or returns all results, and whether any ordering is applied.
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 tool has zero parameters and schema coverage is 100% (trivially). The description adds no parameter information, which is acceptable due to no parameters, so baseline 3 applies.
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 action 'list' and the resource 'all shortened URLs' within the specific context 'Shlink'. It distinguishes itself from siblings like 'get_short_url' (single URL) and 'list_tags' (different resource).
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?
No guidance is provided on when to use this tool versus alternatives (e.g., when to use 'get_short_url' or 'list_tags'). The description lacks 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.
list_tagsA
List all tags in Shlink.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes |
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 only states the basic action, omitting details like pagination, sorting, or whether it returns all tags at once. A read-only hint 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?
A single, front-loaded sentence with no wasted words. Highly concise.
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 no parameters and an output schema, the description is mostly complete. Lacks mention of sorting or performance, but adequate for a simple list-all tool.
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?
No parameters exist, and schema coverage is 100%. The description adds no param details, but none are needed. Baseline for zero params is 4.
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 tags in Shlink' – a specific verb and resource. It distinguishes from sibling tools that manage short URLs, as none list tags.
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?
No explicit guidance on when to use or avoid. Since no sibling tag tools exist, usage is implied but not stated.
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
v0.1.6- First observed
create_short_url - First observed
delete_short_url - First observed
get_short_url - First observed
list_short_urls - First observed
list_tags
TDQS
Scored across 5 tools
Each tool has a distinct purpose: create, delete, get, list short URLs, and list tags. No overlap or ambiguity.
All tool names follow a consistent verb_noun pattern (e.g., create_short_url, list_tags), with clear and predictable naming.
5 tools cover the core URL shortening domain reasonably well. The count is appropriate, though slightly on the lower end for a full-featured API.
Missing an update operation for short URLs, which is a notable gap. Basic CRUD would require update in addition to create, read, and delete.
Maintenance
Related MCP Connectors
Create and manage short links, track clicks, and automate URL management
Create short links, QR codes, UTM templates, vCards, and landing pages from your AI assistant.
Short-link service embedded in your AI workflow — shorten links, track campaigns, read stats.
Free URL shortener: manage short links, QR codes and click analytics from AI clients.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables AI agents to create, update, and manage short links through your Dub.co account, allowing for creation, modification, and deletion of custom shortened URLs.418 npmMIT
- AlicenseAqualityDmaintenanceEnables AI assistants to create, manage, and analyze short URLs through complete URL shortening functionality. Supports batch operations, custom domains, click statistics, and comprehensive link management.67 npm1MIT
- AlicenseNot gradedqualityCmaintenanceConnects AI assistants to the Clypt Link Intelligence platform to shorten URLs, manage tags, and generate QR codes. It enables users to view link analytics and perform bulk link operations through natural language commands.30 npmMIT
- AlicenseAqualityCmaintenanceEnables interaction with Shiori, a self-hosted bookmark and read-it-later manager, for managing bookmarks and tags.13MIT