{
  "markdown": "<p align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://img.shields.io/badge/🦕-dino--mcp-8b5cf6?style=for-the-badge&labelColor=1a1a2e&color=a78bfa\">\n    <img alt=\"dino-mcp\" src=\"https://img.shields.io/badge/🦕-dino--mcp-8b5cf6?style=for-the-badge&labelColor=f0f0ff&color=7c3aed\">\n  </picture>\n</p>\n\n<p align=\"center\">\n  <em>A production-grade MCP server with interactive HTML dashboard UI —\n  written in Go, styled for delight.</em>\n</p>\n\n<div align=\"center\">\n\n[![Go](https://img.shields.io/badge/Go-1.25-00ADD8?logo=go&logoColor=white)](https://go.dev)\n[![MCP Go SDK](https://img.shields.io/badge/MCP_Go_SDK-v1.7.0-a78bfa?logo=matrix&logoColor=white)](https://github.com/modelcontextprotocol/go-sdk)\n[![Gin](https://img.shields.io/badge/Gin-1.12-0099e5?logo=go&logoColor=white)](https://github.com/gin-gonic/gin)\n[![Tests](https://img.shields.io/badge/tests-7/7-22c55e?logo=checkmarx&logoColor=white)](test_mcp.sh)\n[![License](https://img.shields.io/badge/license-MIT-22c55e?logo=opensourceinitiative&logoColor=white)](LICENSE)\n[![Binary Size](https://img.shields.io/badge/size-~11MB-d97706?logo=files&logoColor=white)](#)\n\n</div>\n\n---\n\n## 📋 Table of Contents\n\n- [What — and Why](#-what--and-why)\n- [Quick Start](#-quick-start)\n- [Architecture at a Glance](#-architecture-at-a-glance)\n- [Features](#-features)\n- [Try It](#-try-it)\n- [Tool Reference](#-tool-reference)\n- [Claude Desktop Integration](#-claude-desktop-integration)\n- [Development](#-development)\n- [Documentation Map](#-documentation-map)\n- [Project Status](#-project-status)\n\n---\n\n## 🦕 What — and Why\n\n**dino-mcp** is a reference implementation of the **Model Context Protocol (MCP)** in Go that demonstrates every layer of the modern MCP stack:\n\n| Layer | Implementation | Why it matters |\n|-------|---------------|----------------|\n| **Transport** | `stdio` + `Streamable HTTP` | Works in Claude Desktop AND web browsers |\n| **MCP Apps** | `@modelcontextprotocol/ext-apps` `App` class | Interactive HTML UIs in Claude Desktop iframes |\n| **Tools** | `dino_think`, `dino_ask`, `dino_dashboard` | Typed Go handlers, structured JSON results |\n| **Resources** | `//go:embed` HTML → `text/html;profile=mcp-app` | Self-contained ~11MB binary, zero deps at runtime |\n\n> Whether you're building an MCP server from scratch, learning the MCP Apps protocol, or need a Go — Gin — ext-apps SDK integration blueprint, this project has you covered.\n\n---\n\n## ⚡ Quick Start\n\n```bash\n# Clone & enter\ngit clone https://github.com/shennawardana23/mcp-dino.git && cd mcp-dino\n\n# Build & run in one shot (≈2 seconds)\nmake build-fast && make dev-http\n\n# Open the standalone dashboard\nopen http://localhost:9010/dashboard\n```\n\n<details>\n<summary><b>Expected output</b> — click to expand</summary>\n\n```\n=== dino-mcp server ===\nTransport: http\nListening on :9010\n\n[GIN] 2026/06/21 - 12:30:00 | 200 | 4.2ms | ::1 | GET \"/dashboard\"\n[GIN] 2026/06/21 - 12:30:01 | 200 | 2.1ms | ::1 | GET \"/api/dinosaurs\"\n```\n</details>\n\n---\n\n## 🏗 Architecture at a Glance\n\n```mermaid\nflowchart TB\n  subgraph CLI[\"CLI Layer\"]\n    STDIO[\"stdio subcommand\"]\n    HTTP[\"http subcommand\"]\n  end\n\n  subgraph SERVER[\"Server (internal/server/)\"]\n    GIN[\"Gin Router :9010\"]\n    MCPH[\"MCP StreamableHTTPHandler\"]\n    CORS[\"CORS Middleware\"]\n    TOOLS[\"Tools: think · ask · dashboard\"]\n    RES[\"Resources: //go:embed HTML\"]\n  end\n\n  subgraph UI[\"View (ui/src/)\"]\n    APP[\"ext-apps App class\"]\n    POST[\"postMessage protocol\"]\n  end\n\n  subgraph FALLBACK[\"Standalone Fallback\"]\n    DASH[\"/dashboard (HTML)\"]\n    API[\"/api/dinosaurs (JSON)\"]\n  end\n\n  CLI --> GIN\n  GIN --> CORS\n  CORS --> MCPH\n  MCPH --> TOOLS\n  TOOLS --> RES\n  RES --> APP\n  APP --> POST\n  MCPH -.->|\"MCP Apps\"| APP\n  GIN -.->|\"direct route\"| DASH\n  GIN -.->|\"direct route\"| API\n\n  style CLI fill:#1a1a2e,color:#e0e0e0,stroke:#2d2a44\n  style SERVER fill:#1a1a2e,color:#e0e0e0,stroke:#2d2a44\n  style UI fill:#1a1a2e,color:#e0e0e0,stroke:#2d2a44\n  style FALLBACK fill:#1a1a2e,color:#e0e0e0,stroke:#2d2a44\n  style STDIO fill:#2d2a44,color:#a78bfa\n  style HTTP fill:#2d2a44,color:#a78bfa\n  style GIN fill:#0099e5,color:#fff\n  style MCPH fill:#a78bfa,color:#fff\n  style TOOLS fill:#22c55e,color:#fff\n  style RES fill:#22c55e,color:#fff\n  style APP fill:#facc15,color:#000\n  style POST fill:#facc15,color:#000\n  style DASH fill:#f87171,color:#fff\n  style API fill:#f87171,color:#fff\n```\n\n**Data flows through three pipes:**\n\n| Pipe | Protocol | Client | Use case |\n|------|----------|--------|----------|\n| **MCP Tools** | JSON-RPC over stdio | Claude Desktop | Text tools (`dino_think`, `dino_ask`) |\n| **MCP Apps** | JSON-RPC over stdio + postMessage | Claude Desktop iframe | Interactive UI (`dino_dashboard`) |\n| **Standalone** | HTTP GET | Browser | Direct access (`/dashboard`, `/api/dinosaurs`) |\n\n---\n\n## ✨ Features\n\n<details open>\n<summary><b>MCP Standards Compliance</b></summary>\n\n| Feature | Status | Notes |\n|---------|--------|-------|\n| Tools (`tools/list`, `tools/call`) | ✅ Complete | 3 typed tools with structured JSON responses |\n| Resources (`resources/list`, `resources/read`) | ✅ Complete | `//go:embed` HTML served at `ui://` URIs |\n| MCP Apps protocol | ✅ Complete | `_meta.ui.resourceUri` + `ui/initialize` handshake |\n| stdio transport | ✅ | Claude Desktop, Cursor, Copilot |\n| Streamable HTTP | ✅ | MCP Inspector, curl, browser, tunnel |\n| SSE transport | ❌ Removed | Deprecated in MCP spec v2025-11-25 |\n\n</details>\n\n<details>\n<summary><b>Developer Experience</b></summary>\n\n- **3-second build cycle** — `make build-fast && make dev-http`\n- **7 integration tests** — `make test` exercises every protocol method\n- **Interactive debugging** — `make test-inspector` launches [MCP Inspector](https://github.com/modelcontextprotocol/inspector)\n- **Remote testing** — `make run-tunnel` creates a public `trycloudflare.com` URL\n- **No API keys** — all dinosaur data is built into the binary\n- **Zero runtime deps** — single static binary with embedded HTML\n\n</details>\n\n<details>\n<summary><b>Interactive Dashboard</b></summary>\n\nThe `dino_dashboard` tool renders an HTML card grid inside Claude Desktop's iframe:\n\n- **Filter by diet** — Carnivore, Herbivore, or show All\n- **Filter by period** — Triassic, Jurassic, Cretaceous\n- **12 dinosaur species** — from T-Rex to Velociraptor\n- **Fallback mode** — open directly at `http://localhost:9010/dashboard`\n\n> Note: the filter is applied server-side at the time the tool is called. Once opened with a specific filter, the in-app filter buttons can only narrow further within that same result set — they can't widen back out to species the initial call excluded.\n\nThe HTML view is built with the official `@modelcontextprotocol/ext-apps` SDK and communicates via JSON-RPC over `postMessage`.\n\n</details>\n\n---\n\n## 🎮 Try It\n\n### In Claude Desktop\n\n```\nShow me the dinosaur dashboard with carnivores\n```\n\n→ Claude detects the MCP App → renders an iframe → you see filterable dinosaur cards\n\n### In your browser\n\n```bash\nopen http://localhost:9010/dashboard\n```\n\n→ Standalone HTML with all dinosaur data fetched from the built-in REST API\n\n### With MCP Inspector\n\n```bash\nmake test-inspector\n```\n\n→ Opens `http://localhost:5173` → connects to `http://localhost:9010/mcp`\n\n### Via curl\n\n```bash\n# Initialize\ncurl -s -X POST http://localhost:9010/mcp \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json, text/event-stream\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-06-18\",\"capabilities\":{},\"clientInfo\":{\"name\":\"curl\",\"version\":\"1.0\"}}}' \\\n  | python3 -m json.tool\n\n# List tools\nSID=\"<session-id-from-above>\"\ncurl -s -X POST http://localhost:9010/mcp \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json, text/event-stream\" \\\n  -H \"Mcp-Session-Id: $SID\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\"}' \\\n  | python3 -m json.tool\n\n# Call dino_think\ncurl -s -X POST http://localhost:9010/mcp \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json, text/event-stream\" \\\n  -H \"Mcp-Session-Id: $SID\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":3,\"method\":\"tools/call\",\"params\":{\"name\":\"dino_think\",\"arguments\":{}}}' \\\n  | python3 -m json.tool\n```\n\n---\n\n## 🔧 Tool Reference\n\n| Tool | Type | Input | Output | Example Prompt |\n|------|------|-------|--------|----------------|\n| `dino_think` | Text | `{}` | Random fact + species JSON | \"Tell me a dinosaur fact\" |\n| `dino_ask` | Text | `{\"question\": \"...\"}` | Answer + question JSON | \"What did T-Rex eat?\" |\n| `dino_dashboard` | **MCP App** | `{\"filter\": \"Carnivore\"}` | HTML iframe + JSON data | \"Show me carnivore dinosaurs\" |\n\n> `dino_ask` currently returns the same general dinosaur-era overview regardless of the question asked — it doesn't yet branch on the question text. Tracked as a known limitation.\n\nExample `dino_think` response:\n\n```json\n{\n  \"content\": [\n    { \"type\": \"text\", \"text\": \"🦕 Did you know? The Velociraptor was only about the size of a turkey!\" }\n  ],\n  \"structuredContent\": {\n    \"fact\": \"The Velociraptor was only about the size of a turkey\",\n    \"species\": \"Velociraptor\"\n  }\n}\n```\n\nExample `dino_dashboard` response:\n\n```json\n{\n  \"content\": [\n    { \"type\": \"text\", \"text\": \"Displaying dinosaur dashboard with 4 dinosaurs (filter: Carnivore)\" }\n  ],\n  \"structuredContent\": {\n    \"filter\": \"Carnivore\",\n    \"dinosaurs\": [\n      {\n        \"name\": \"Tyrannosaurus Rex\",\n        \"period\": \"Cretaceous\",\n        \"diet\": \"Carnivore\",\n        \"length\": \"40 ft (12 m)\",\n        \"weight\": \"9 tons (8,000 kg)\",\n        \"funFact\": \"T-Rex had the strongest bite of any land animal ever\",\n        \"imageStyle\": \"bg-red-900\"\n      }\n    ],\n    \"timestamp\": \"2026-06-21T12:00:00Z\"\n  }\n}\n```\n\n---\n\n## 💬 Claude Desktop Integration\n\n### CLI Mode (stdin/stdout)\n\nLocate the binary and add to your `claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"dino-mcp\": {\n      \"command\": \"/absolute/path/to/mcp-dino/bin/dino-mcp\",\n      \"args\": [\"stdio\"]\n    }\n  }\n}\n```\n\nAfter saving, restart Claude Desktop. You'll see hammer icons (🔨) on tools when chatting — click to invoke directly, or let Claude decide.\n\n### HTTP Mode (for debugging)\n\n```bash\nmake dev-http\n# Server starts on :9010\n```\n\n---\n\n## 🛠 Development\n\n### Prerequisites\n\n| Tool | Version | Purpose |\n|------|---------|---------|\n| [Go](https://go.dev/dl/) | ≥ 1.25 | Server binary |\n| [Node.js](https://nodejs.org/) | ≥ 18 | UI build (Vite) |\n| [cloudflared](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/) | any | Tunnel for remote testing |\n\n### Commands\n\n```bash\n# Build — three options\nmake build            # Full: Vite UI + Go binary\nmake build-fast       # Quick: Go binary only (reuses existing UI)\nmake build-ui         # Vite UI only\n\n# Run\nmake dev-http         # HTTP mode with verbose logging\nmake run-stdio        # stdio mode for Claude Desktop\nmake run-tunnel       # HTTP + Cloudflare Tunnel\n\n# Test & verify\nmake test             # 7 integration tests — all must pass\nmake test-inspector   # Launch MCP Inspector in browser\nmake lint             # go vet + go fmt\n\n# Utility\nmake help             # All targets with descriptions\nmake clean            # Remove all build artifacts\n```\n\n### Project Structure\n\n```\nmcp-dino/\n├── bin/                          # Go build output (~11MB static binary)\n├── cmd/dino-mcp/main.go          # CLI entry point (stdio | http | help)\n├── internal/\n│   ├── server/\n│   │   └── server.go             # Composition root: mcp.Server + Gin + CORS\n│   ├── tools/\n│   │   ├── tools.go              # Shared types, constants, helpers\n│   │   ├── think.go              # RegisterThink (dino_think tool)\n│   │   ├── ask.go                # RegisterAsk (dino_ask tool)\n│   │   └── dashboard.go          # RegisterDashboardTool + 12 dino species + REST API\n│   └── resources/\n│       ├── dashboard.go          # RegisterDashboardResource + //go:embed HTML\n│       └── dashboard_ui.html     # Vite-built HTML (354KB)\n├── ui/\n│   └── src/\n│       └── mcp-app.ts            # ext-apps App class + postMessage\n├── docs/                         # Diátaxis documentation (see below)\n├── test_mcp.sh                   # 7 integration tests\n├── AGENTS.md                     # AI agent instructions (canonical)\n├── ARCHITECTURE.md               # C4 diagrams + sequence flows\n├── TECH_DESIGN.md                # Interface contracts + data model\n├── Makefile                      # All targets\n├── go.mod + go.sum               # Go dependencies\n└── README.md                     # ← you are here\n```\n\n---\n\n## 🗺 Documentation Map\n\ndino-mcp uses the **Diátaxis framework** — four documentation modes, each serving a different need.\n\n| For this audience | Start here | Audience |\n|:---|---:|:---|\n| 👋 New to the project | [Quick Start](docs/tutorials/get-started.md) | Everyone |\n| 🧑‍💻 Adding a tool | [Your First Tool](docs/tutorials/first-tool.md) | Developers |\n| 🦕 Adding a dinosaur | [Add a Dinosaur](docs/how-to/add-dinosaur.md) | Content editors |\n| 🧪 Testing with Inspector | [Test with Inspector](docs/how-to/test-inspector.md) | QA / Developers |\n| 🔍 Reference needed | [CLI Reference](docs/reference/cli.md) | Operators |\n| 🏗 Understanding design | [Architecture](docs/explanation/architecture.md) | Architects |\n| 🤖 Implementing via AI | [AGENTS.md](AGENTS.md) | AI coding agents |\n| 📚 Deep architecture | [ARCHITECTURE.md](ARCHITECTURE.md) | Senior engineers |\n| 📐 Technical specs | [TECH_DESIGN.md](TECH_DESIGN.md) | Implementation teams |\n| ⏳ Development history | [MEMORY.md](MEMORY.md) | All contributors |\n| 📋 Roadmap | [PLAN.md](PLAN.md) | Stakeholders |\n| ⚖️ Design trade-offs | [DESIGN.md](DESIGN.md) | Architects |\n| 🎯 Skills reference | [SKILL.md](SKILL.md) | Developers / AI agents |\n| 🤝 How to contribute | [CONTRIBUTOR.md](CONTRIBUTOR.md) | Contributors |\n| 📜 Code of conduct | [CODE_CONDUCT.md](CODE_CONDUCT.md) | Community |\n| 📄 ADRs | [docs/adr/](docs/adr/) | Decision historians |\n| 🤖 LLM full context | [llms-full.txt](llms-full.txt) | AI agents (RAG) |\n\n---\n\n## 📊 Project Status\n\n```\nMVP ── Production ── Enhanced UI ── Ecosystem ── Advanced\n  ●                    ○               ○             ○\n```\n\n| Phase | Status | Highlights |\n|-------|--------|------------|\n| **MVP** | ✅ Complete | 3 tools, MCP Apps UI, 7 tests, docs |\n| **Production** | 🔄 In progress | Go unit tests, CI, rate limiting, Docker |\n| **Enhanced UI** | 📅 Planned | Real-time data, comparison, timeline |\n| **Ecosystem** | 📅 Planned | Homebrew, GitHub releases, MCP Registry |\n| **Advanced** | 💭 Future | Streaming tool inputs, WebSocket sync |\n\n### Build Metrics\n\n| Metric | Value |\n|--------|-------|\n| Binary size | ~11 MB (compressed) |\n| Binary type | Mach-O 64-bit arm64 |\n| Go version | 1.25 |\n| MCP SDK version | v1.7.0 |\n| Dependencies | 30+ Go modules (all indirect) |\n| UI bundle | 354 KB embedded HTML (single-file Vite) |\n| Test coverage | 7/7 integration tests passing (shell-based; no Go unit tests yet) |\n\n---\n\n## 📖 Further Reading\n\n| Resource | Link |\n|----------|------|\n| MCP Specification | [spec.modelcontextprotocol.io](https://spec.modelcontextprotocol.io) |\n| MCP Go SDK | [github.com/modelcontextprotocol/go-sdk](https://github.com/modelcontextprotocol/go-sdk) |\n| MCP Apps Protocol | [modelcontextprotocol.io/docs/apps/overview](https://modelcontextprotocol.io/docs/apps/overview) |\n| ext-apps SDK | [github.com/modelcontextprotocol/ext-apps](https://github.com/modelcontextprotocol/ext-apps) |\n| Gin Web Framework | [github.com/gin-gonic/gin](https://github.com/gin-gonic/gin) |\n| Go Programming Language | [go.dev](https://go.dev) |\n\n---\n\n<p align=\"center\">\n  Built with ❤️ using <a href=\"https://go.dev\">Go</a>,\n  <a href=\"https://gin-gonic.com\">Gin</a>,\n  <a href=\"https://github.com/modelcontextprotocol/go-sdk\">MCP Go SDK</a>,\n  and <a href=\"https://github.com/modelcontextprotocol/ext-apps\">@modelcontextprotocol/ext-apps</a>\n</p>\n",
  "bytes": 15968,
  "sha": "f89253de4e3f9e9bc5b28541e908105ee38921ff7ef33982c50772595a071ce4",
  "repo_slug": "shennawardana23/mcp-dino",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_shennawardana23_mcp_dino_773d617c/readme"
}