b59.link MCP Server
Authentication
The server works without signing in at 2 requests per minute (with a small burst so a client can connect). Signed-in clients get 300 requests per minute and own the trackers and links they create.
- Call the
authtool with yourapi_key(on your profile), or with anemailand thenemail + otp. The same flow isPOST /api/authon the REST API. - Put the returned session key in your client's MCP config as an HTTP header. It lasts 30 days.
{
"mcpServers": {
"b59link": {
"type": "http",
"url": "https://b59.link/api/mcp",
"headers": { "Authorization": "Bearer <session_key>" }
}
}
}A wrong or expired key gets HTTP 401 — drop the header or sign in again. Tools return stats URLs; the stats themselves are viewed on b59.link.
Overview
b59.link exposes a Model Context Protocol (MCP) server at https://b59.link/api/mcp. Connect MCP, OpenAI, or Gemini agents to create page-view trackers, shorten links, make QR codes, and find stats pages — no sign-up needed.
Available tools
authSign in for 300 requests/minute. api_key gives a session key at once; email sends a 6-digit code, then email + otp gives a session key (and signs new emails up). Send it as the Authorization header on every request.
Parameters
api_key?: string // 256-char account key
email?: string // to get a code
otp?: string // the code from the emailReturns
{ otp_sent: true, email, expires_in_seconds }
// or
{
session_key: "b59s_...",
token_type: "Bearer",
expires_at: string,
email: string,
api_key?: string // after email + otp
}create_trackerCreate a page-view tracker for a site. Returns the tag image URL and snippets to put on the site's pages, plus the stats URL. Owned by your account when signed in.
Parameters
site_url: string // e.g. example.com
name?: stringReturns
{
tracker_id: string,
tag_url: string, // https://b59.link/tag?<id>
snippet_img: string,
snippet_js: string,
stats_url: string,
manage_token?: string // when not signed in
}get_stats_urlFind the stats page for a slug, short URL, page URL, domain, tracker id or tag URL — anything tracked by a short link, QR code or tracker tag. Returns URLs, not numbers.
Parameters
identifier: stringReturns
{
found: boolean,
results: [{
type: "short_link" | "page_tracker",
stats_url: string,
...
}]
}shorten_urlShorten a long URL. Returns a short_url and stats_url. Custom slug optional.
Parameters
url: string // required
slug?: string // optional custom slugReturns
{
slug: string,
short_url: string,
stats_url: string
}generate_qrMake a trackable QR code for a URL. Creates a short link at the same time so scans are counted.
Parameters
url: string // requiredReturns
{
slug: string,
short_url: string,
stats_url: string,
qr_code_data: string // base64 PNG
}make_qr_imageQR image for any text (link, Wi-Fi, email, phone) with colors, size and SVG. No short link. Returns an image block plus a permanent image URL.
Parameters
data: string
size?: number // 64-1200, default 300
fg?: string // hex, e.g. 000000
bg?: string // hex, e.g. ffffff
format?: "png" | "svg"Returns
{ image_url, format, size }
+ image content (PNG), or svg textlookup_urlCheck if a URL already has a b59 link. Handles http/https/www/trailing-slash variations.
Parameters
url: string // requiredReturns
{ found: false }
// or
{
found: true,
slug: string,
short_url: string,
stats_url: string,
qr_code_data: string | null
}Use with Claude (claude.ai)
In Claude's settings, add a new MCP server with the URL below. Claude will automatically discover the available tools and can call them during conversation.
https://b59.link/api/mcpExample prompt: "Shorten https://my-long-url.com/path and give me a QR code."
Use with Claude Code (CLI)
Add b59.link as an MCP server in your ~/.claude/claude.json or via the CLI:
Via CLI
claude mcp add b59link --transport http https://b59.link/api/mcpOr add to claude.json manually
{
"mcpServers": {
"b59link": {
"type": "http",
"url": "https://b59.link/api/mcp"
}
}
}After adding, restart Claude Code. Type /mcp to verify the server is connected.
Use with OpenAI
Fetch the OpenAI-compatible function schema and pass it as the tools parameter. Route tool calls to POST /api/mcp.
import OpenAI from "openai";
const openai = new OpenAI();
// 1. Fetch tool definitions
const schemaRes = await fetch("https://b59.link/api/mcp/schema");
const { tools } = await schemaRes.json();
// 2. Call the model
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Shorten https://example.com/long/path" }],
tools,
tool_choice: "auto",
});
// 3. Execute tool calls
const msg = response.choices[0].message;
if (msg.tool_calls) {
for (const call of msg.tool_calls) {
const mcpRes = await fetch("https://b59.link/api/mcp", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "tools/call",
params: {
name: call.function.name,
arguments: JSON.parse(call.function.arguments),
},
}),
});
const result = await mcpRes.json();
console.log(result.result.content[0].text);
}
}Use with Gemini
Gemini uses the same function-calling schema as OpenAI. Fetch the schema and convert it to Gemini's FunctionDeclaration format.
import { GoogleGenerativeAI } from "@google/generative-ai";
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
// Fetch and convert tool schema
const { tools: openaiTools } = await fetch("https://b59.link/api/mcp/schema").then(r => r.json());
const tools = [{
functionDeclarations: openaiTools.map(t => ({
name: t.function.name,
description: t.function.description,
parameters: t.function.parameters,
})),
}];
const model = genAI.getGenerativeModel({ model: "gemini-1.5-pro", tools });
const chat = model.startChat();
const result = await chat.sendMessage("Shorten https://example.com for me.");
// Handle function calls
const response = result.response;
const calls = response.functionCalls();
if (calls) {
for (const call of calls) {
const mcpRes = await fetch("https://b59.link/api/mcp", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0", id: 1,
method: "tools/call",
params: { name: call.name, arguments: call.args },
}),
});
const toolResult = await mcpRes.json();
console.log(toolResult.result.content[0].text);
}
}Raw JSON-RPC
The MCP server speaks JSON-RPC 2.0 over HTTP POST. Supported methods: initialize, tools/list, tools/call, ping. Notifications (requests without an id) get HTTP 202.
List tools
curl -X POST https://b59.link/api/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'Call a tool
curl -X POST https://b59.link/api/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <session_key>" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "shorten_url",
"arguments": {
"url": "https://example.com/very/long/path",
"slug": "my-link"
}
}
}'