Linky logoLinky
Docs navigation

Agents

Give your agent native Linky access

Paste one mcp.json snippet into Cursor, Claude Desktop, Codex, Continue, or Cline. Your agent sees all 11 Linky tools — create, list, update, read insights, manage keys — without leaving the harness.

What this is

Linky speaks the Model Context Protocol over the Streamable-HTTP transport. Authentication is a standard bearer API key, so the same key that works with the CLI or SDK works with every MCP harness. Scopes ship from access control: links:readis safe to drop into an agent's context; links:write lets an agent create and edit bundles; keys:admin can manage keys (rare).

Self-hosters get the same endpoint at /api/mcp on their deployment. No separate service.

1 · Create a read-only key

Go to /dashboard/api-keys, pick Read-only, set a rate limit (default 1000/hr is fine — it's a per-key cap on throughput), and copy the raw key. Read-only is the right starting scope for any agent that's just summarizing or linking to existing bundles — it can't delete, patch, or mint new keys.

Use links:write if you want the agent to create or update Linkies. Every key has its own rate-limit bucket so a runaway agent burns its own quota, not yours.

2 · Paste into your agent

Five snippets. Every snippet lists the default config path for the harness so you know where to drop it. Replace lkyu_YOUR_PREFIX.YOUR_SECRET with the key you just minted.

Cursor

JSON

Config path: .cursor/mcp.json

Cursor speaks Streamable-HTTP natively; no local bridge required.

{
  "mcpServers": {
    "linky": {
      "url": "https://getalinky.com/api/mcp",
      "headers": {
        "Authorization": "Bearer lkyu_YOUR_PREFIX.YOUR_SECRET"
      }
    }
  }
}

Claude Desktop

JSON

Config path: ~/Library/Application Support/Claude/claude_desktop_config.json

Claude Desktop uses the stdio bridge shipped in getalinky.

{
  "mcpServers": {
    "linky": {
      "command": "npx",
      "args": ["-y", "getalinky", "mcp"],
      "env": {
        "LINKY_API_KEY": "lkyu_YOUR_PREFIX.YOUR_SECRET",
        "LINKY_BASE_URL": "https://getalinky.com"
      }
    }
  }
}

Codex CLI

TOML

Config path: ~/.codex/config.toml

[mcp_servers.linky]
command = "npx"
args = ["-y", "getalinky", "mcp"]

[mcp_servers.linky.env]
LINKY_API_KEY = "lkyu_YOUR_PREFIX.YOUR_SECRET"
LINKY_BASE_URL = "https://getalinky.com"

Continue

JSON

Config path: .continue/config.json

{
  "mcpServers": [
    {
      "name": "linky",
      "transport": {
        "type": "streamable-http",
        "url": "https://getalinky.com/api/mcp",
        "headers": { "Authorization": "Bearer lkyu_YOUR_PREFIX.YOUR_SECRET" }
      }
    }
  ]
}

Cline

JSON

Config path: cline_mcp_settings.json

{
  "mcpServers": {
    "linky": {
      "url": "https://getalinky.com/api/mcp",
      "headers": { "Authorization": "Bearer lkyu_YOUR_PREFIX.YOUR_SECRET" }
    }
  }
}

3 · Verify with mcp-inspector

Before wiring an agent harness, confirm the endpoint is reachable and your key works. The official @modelcontextprotocol/inspector lists every tool and lets you call each one interactively.

npx @modelcontextprotocol/inspector \
  --url https://getalinky.com/api/mcp \
  --header "Authorization: Bearer lkyu_YOUR_PREFIX.YOUR_SECRET"

4 · Self-host

Replace https://getalinky.comwith your deployment's URL anywhere it appears above. No separate config, no extra service — /api/mcp ships in the same Next.js app that serves the dashboard. You can also kill the surface at runtime by setting LINKY_MCP_ENABLED=false (the route returns 503 with a clear message).

Tool reference (11)

Every tool mirrors one authed HTTP route. Scopes + roles are enforced server-side; an agent holding a links:read key will see all 11 tools but get a-32002 Forbidden error if it tries one that requires write or admin.

ToolDescription
linky_createCreate a new Linky bundle of URLs. Returns the short URL and slug. Optional: title, description, per-URL metadata, email for claim flow, and an identity-aware resolution policy.
linky_listList the caller's Linky bundles, newest-updated first. Owner-scoped: returns org-owned bundles when called from an org key, user-owned otherwise.
linky_getRead a single Linky by slug. Returns the full DTO including urls, metadata, owner, and any attached resolution policy.
linky_updatePATCH an existing Linky. At least one updatable field must be supplied: urls, urlMetadata, title, description, or resolutionPolicy. Pass resolutionPolicy=null to clear an existing policy.
linky_deleteSoft-delete a Linky. The public launcher returns 410 afterwards. Requires admin role on org-owned bundles.
linky_versionsAppend-only edit history for a Linky. Returns the version list, newest first.
linky_insightsOwner-side analytics for a Linky: totals (views / unique viewer-days / open-all rate), per-rule breakdown, and daily sparkline series. Range defaults to 30d.
whoamiIdentity probe. Returns the bearer subject, derived role, and attached scopes. Safe for a links:read key — does NOT require keys:admin.
keys_listList API keys for the caller. Requires keys:admin scope; org-owned subjects also require the admin role.
keys_createMint a new API key owned by the caller (user or active org). Requires keys:admin. Returns the raw key ONCE — store it immediately; it cannot be recovered. Use `rateLimitPerHour` to cap throughput for agent-held keys (default 1000; 0 disables the limit).
keys_revokeRevoke an API key by numeric id. Requires keys:admin. Idempotent: already-revoked keys return their existing revocation record.

Troubleshooting

  • 401 on connect — the bearer header is missing or the key was revoked. Mint a new one at /dashboard/api-keys.
  • -32002 Forbidden on a tool call — the key lacks the required scope. Mint a new key with the scope the error message names, or use a higher-scope key.
  • -32004 Rate limited— the per-key hourly bucket is spent. The error's data block carries retryAfterSeconds. Either wait it out or raise the limit by revoking and re-minting.
  • 503 MCP_DISABLED — the operator flipped LINKY_MCP_ENABLED=false. Not a client-side bug; contact the operator.