Skip to content
Conduit

mcp server

goshort

Self-hosted URL shortener in Go — single binary, SQLite-backed, zero config. Custom aliases, expiration, CLI, Redis cache, MCP server for AI agents (Claude Code, Cursor). Deploy anywhere: Docker, Fly.

anIcedAntFA/goshortcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 21, 2026

CI Best Practices govulncheck codecov Go Report Card Release

License: MIT Go Website API Docs Ko-fi


✨ Features

  • Zero-collision codes — atomic SQLite counter + Sqids: non-sequential, bijective, no retry loops
  • Custom aliases — bring your own slug (/my-link); charset isolation prevents collision with generated codes
  • URL expiration — configurable TTL with lazy expiry on read + hourly background cleanup; update expiry via PATCH
  • Batch creation — POST /api/v1/urls/batch accepts up to 100 URLs; per-item success/failure
  • QR codes — GET /api/v1/urls/{code}/qr?format=png|jpeg|svg returns a QR code for any short link in three formats
  • Link previews — title and description auto-fetched on create (fail-open, private-IP blocked)
  • Spam detection — optional Google Safe Browsing v4 integration; unsafe URLs rejected with 422 (fail-open)
  • Switchable cache — none | memory | redis at config time; cache-aside with TTL capped to remaining expiry
  • API key auth — constant-time comparison; per-IP token bucket rate limiting
  • CLI client — goshort-cli for shorten, list, stats, delete from the terminal
  • Public shorten endpoint — POST /api/v1/urls/public: no auth, 5 req/min rate limit, 30-day expiry; powers the landing page widget
  • Landing page — goshort.ngockhoi96.dev: Astro static site on Cloudflare Workers with live shorten widget
  • MCP server — AI agents (Claude Code, Cursor) can shorten, list, and manage URLs via Model Context Protocol
  • Prometheus metrics + structured logs — /metrics endpoint, slog throughout, no extra dependencies
  • Self-documenting API — OpenAPI 3.1 spec + interactive Scalar UI at /docs

🏗️ Architecture

Full architecture diagrams: high-level, request flow, layer boundaries.


🛠️ Tech Stack

ComponentTechnology
LanguageGo 1.26
HTTPChi v5
DatabaseSQLite via sqlc (pure Go, no CGO)
EncodingSqids (zero-collision, non-sequential)
CLICobra
ConfigKoanf v2 (TOML + env vars)
Cachego-redis v9
MetricsPrometheus
Rate Limitrate (token bucket)
MCPgo-sdk v1.6 (official)
Migrationsgoose v3 (embedded FS, versioned SQL)
QR codesgo-qrcode
Spam detectionGoogle Safe Browsing Lookup API v4 (optional, fail-open)
Reverse ProxyCaddy (Docker Compose)
ReleaseGoReleaser + GitHub Actions
WebsiteAstro v6, Tailwind CSS v4, Biome v2, Bun, Cloudflare Workers

🚀 Quick Start

a. Docker Compose (recommended)

curl -O https://raw.githubusercontent.com/anIcedAntFA/goshort/main/docker-compose.yml
curl -O https://raw.githubusercontent.com/anIcedAntFA/goshort/main/goshort.toml
docker compose up -d

Caddy handles TLS automatically. Edit goshort.toml to set your base_url and api_key.

b. Binary (GitHub Releases)

curl -L https://github.com/anIcedAntFA/goshort/releases/latest/download/goshort_linux_amd64.tar.gz | tar xz
./goshort

Grab goshort_darwin_arm64, goshort_windows_amd64, etc. from the releases page.

c. go install

go install github.com/anIcedAntFA/goshort/cmd/server@latest
goshort

📡 Usage

Create a short URL:

curl -s -X POST http://localhost:8080/api/v1/urls \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key" \
  -d '{"url": "https://example.com/very/long/path", "expires_in": "30d"}'
{
  "short_code": "k7Xm2p",
  "short_url":  "http://localhost:8080/k7Xm2p",
  "original_url": "https://example.com/very/long/path",
  "expires_at": "2025-08-01T00:00:00Z"
}

Redirect:

curl -L http://localhost:8080/k7Xm2p
# → 302 to https://example.com/very/long/path

💻 CLI

# Install
go install github.com/anIcedAntFA/goshort/cmd/cli@latest

# Shorten a URL
goshort-cli shorten https://example.com/long --alias my-link --expires 7d

# List all URLs (paginated)
goshort-cli list --page 1 --per-page 20

# Inspect a short code or alias
goshort-cli stats k7Xm2p

# Delete a short URL
goshort-cli delete k7Xm2p

Config file (~/.goshort.toml):

server_url = "http://localhost:8080"
api_key    = "your-api-key"

Per-command overrides (precedence: flag > env > config):

FlagEnv var
--serverGOSHORT_SERVER_URL
--api-keyGOSHORT_API_KEY
--json—

🤖 MCP (AI Agent Integration)

GoShort ships an MCP server so AI agents like Claude Code and Cursor can shorten, list, and manage URLs directly.

Local — stdio

make build

Create .mcp.json in your project root:

{
  "mcpServers": {
    "goshort": {
      "command": "./bin/goshort",
      "args": ["--mcp"],
      "env": { "GOSHORT_STORAGE_SQLITE_PATH": "./data/goshort.db" }
    }
  }
}

Remote — Streamable HTTP

The /mcp endpoint is served on the main port alongside the REST API. No separate server needed.

# Connect Claude Code to deployed instance
claude mcp add goshort-remote \
  --transport http \
  https://goshort.app/mcp \
  --header "X-API-Key: your-api-key"

Tools

ToolDescription
shorten_urlCreate a short URL (alias + expiry optional)
batch_shorten_urlsCreate up to 100 short URLs in one call
list_urlsList URLs with pagination
get_url_statsClick count and full details for a URL
delete_urlDelete a short URL
lookup_urlResolve a short code to its original URL
update_urlUpdate the expiry of an existing short URL

Resources

URIDescription
goshort://stats/summaryTotal URL count and top URLs by clicks
goshort://urls/{code}Full details for a specific short code
goshort://urls/{code}/qrQR code blob for a short URL (PNG/JPEG/SVG via ?format=)

Prompts

PromptDescription
shorten_and_shareShorten + format for sharing (platform-aware)
batch_shortenShorten multiple URLs and return a table

⚙️ Configuration

[server]
port     = 8080
base_url = "https://short.yourdomain.com"

[auth]
api_key = "your-secret-key"   # empty = no auth

[cache]
driver = "none"               # none | memory | redis

[shortener]
default_expiry = "0"          # "0" = no expiry; or "7d", "30d", "365d"

Every key maps to GOSHORT_<SECTION>_<KEY> env var — e.g., GOSHORT_AUTH_API_KEY=secret. Full reference: goshort.toml.


📋 API

MethodPathAuthDescription
POST/api/v1/urlsYesCreate short URL
POST/api/v1/urls/batchYesCreate up to 100 URLs
GET/api/v1/urlsYesList URLs (paginated)
GET/api/v1/urls/:codeYesGet URL details
PATCH/api/v1/urls/:codeYesUpdate URL expiry
DELETE/api/v1/urls/:codeYesDelete short URL
POST/api/v1/urls/publicNoPublic shorten (30d TTL)
GET/api/v1/urls/:code/qrNoQR code (PNG/JPEG/SVG)
GET/:codeNoRedirect (302)
GET/healthNoHealth check
GET/metricsNoPrometheus metrics
GET/docsNoInteractive API docs
POST/mcpYesMCP Streamable HTTP

Auth: X-API-Key: <key> header. Redirect codes: 302 Found, 404 Not Found, 410 Gone (expired).

POST /api/v1/urls body:

FieldTypeRequiredNotes
urlstringYesMax 2048 chars
custom_aliasstringNo^[a-zA-Z0-9-]{3,30}$
expires_instringNo1h, 7d, 30d, 90d, 365d, never

Interactive docs at goshort.app/docs. Landing page at goshort.ngockhoi96.dev.


📁 Project Structure

See docs/DESIGN.md for the full architecture, layer boundaries, and design rationale.


🧑‍💻 Development

git clone https://github.com/anIcedAntFA/goshort
cd goshort
lefthook install        # install git hooks (once after clone)
make help               # list all targets

Run make help for the full list of targets. See CONTRIBUTING.md for the full development workflow including Redis integration tests and git hooks.


🚢 Deployment

See docs/DEPLOYMENT.md for comprehensive guides.

Docker Compose — GoShort + Caddy (auto-TLS):

docker compose up -d

Fly.io — API + redirects + MCP at goshort.app:

fly launch && fly deploy

Landing page — goshort.ngockhoi96.dev (Cloudflare Workers, static Astro build):

make website/build && cd website && wrangler deploy

Bare VPS — Nginx + systemd + Certbot (see DEPLOYMENT.md)


🗺️ Roadmap

PhaseFocusStatus
1Core library — SQLite, sqlc, Sqids, TDD✅ v0.1.0
2HTTP API, caching, config, Prometheus✅ v0.2.0
3Auth, rate limiting, CLI, Docker, release infra✅ v0.3.0
3.5Deploy — Fly.io + Cloudflare CDN✅ goshort.app
4MCP server — Claude / Cursor integration✅ v0.4.0
5Batch, QR codes, link previews, spam detection✅ v0.5.0
6Landing page (Cloudflare Workers), public endpoint✅ v0.6.0
7+Analytics, PostgreSQL, Redis counter🔲

Each phase ships a working, deployable product.


⭐ Star History

Star History Chart


📄 License

MIT — see LICENSE.

↑↓ navigate openesc close