Back to blog

We Added an MCP Server to Our Link Shortener — Here's Why

Most SaaS APIs are built for humans to call from code. You write an integration, you handle auth, you wire up the UI.

MCP — the Model Context Protocol — is a standard that lets AI assistants call your API directly. Instead of building a Zapier integration or a custom script, a user can just ask Claude: "Create a short link for this URL and tag it with the campaign name" — and it works.

We shipped an MCP server for Peeksy. Here's what we built and why it was straightforward.

What MCP actually is

MCP is a JSON-RPC 2.0 protocol over HTTP. An AI assistant that supports MCP can discover what tools a server offers (via GET /mcp) and then call those tools (via POST /mcp) using a standard message format.

The spec defines:

  • Tools — functions the model can call (e.g. create_link, get_analytics_summary)
  • Resources — data the model can read (we haven't implemented these yet)
  • Prompts — pre-built prompt templates (same)

For Peeksy, the useful surface is tools. The model can take actions: create a link, update it, pull stats.

The implementation

Because Peeksy's API runs on Hono + Cloudflare Workers, the MCP server is just two routes on the existing app:

```typescript

// GET /mcp — manifest (no auth required)

app.get("/mcp", (c) => {

return c.json({

protocol: "mcp",

version: "2024-11-05",

name: "Peeksy",

tools: TOOLS,

});

});

// POST /mcp — JSON-RPC handler (Bearer JWT required)

app.post("/mcp", requireJwt, mcpHandler);

```

The manifest is public so that MCP clients can discover the server. The handler is protected — the user's JWT goes in the Authorization header, same as every other Peeksy API call.

Tools we expose

We started with the most useful set:

| Tool | What it does |

|---|---|

| list_links | Returns the user's links with pagination |

| create_link | Creates a new short link with optional custom slug, title, tags |

| update_link | Updates title, destination URL, or tags on an existing link |

| delete_link | Deletes a link by ID |

| get_analytics_summary | Returns click totals, device breakdown, top referrers for a link |

| list_templates | Returns available OG image templates |

| get_user_profile | Returns the authenticated user's plan and usage |

Each tool definition includes a JSON Schema for its input parameters. The AI uses the schema to construct valid calls.

Auth: just pass the JWT

The cleanest decision we made: no new auth mechanism. The user gets their JWT from the normal login flow and passes it as Authorization: Bearer <token> when configuring the MCP server in their AI client.

This means: