{"id":51262553,"url":"https://github.com/robconery/cassini-workshop","last_synced_at":"2026-06-29T13:01:58.414Z","repository":{"id":366009654,"uuid":"1274725504","full_name":"robconery/cassini-workshop","owner":"robconery","description":"Read-only MCP server over the Cassini-Huygens mission plan dataset — a Cloudflare Workers + D1 workshop demo","archived":false,"fork":false,"pushed_at":"2026-06-19T20:31:38.000Z","size":3309,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-19T22:13:59.001Z","etag":null,"topics":["ai-workshop","cassini","cloudflare-workers","mcp","sqlite","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robconery.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-19T20:31:22.000Z","updated_at":"2026-06-19T20:31:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/robconery/cassini-workshop","commit_stats":null,"previous_names":["robconery/cassini-workshop"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/robconery/cassini-workshop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robconery%2Fcassini-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robconery%2Fcassini-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robconery%2Fcassini-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robconery%2Fcassini-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robconery","download_url":"https://codeload.github.com/robconery/cassini-workshop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robconery%2Fcassini-workshop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34927687,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-workshop","cassini","cloudflare-workers","mcp","sqlite","typescript"],"created_at":"2026-06-29T13:01:56.527Z","updated_at":"2026-06-29T13:01:58.406Z","avatar_url":"https://github.com/robconery.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cassini Mission Plan MCP\n\nA read-only [Model Context Protocol](https://modelcontextprotocol.io) server over the Cassini-Huygens mission dataset (~62k activity rows). Built as an AI workshop demo: clean, readable TypeScript that runs live in Claude Desktop.\n\n**Live endpoint:** `https://cassini-mission-plan.redfour.workers.dev`\n\n---\n\n## What it does\n\nExposes 7 MCP tools so an LLM client can query the Cassini `master_plan` table:\n\n| Tool | What it answers |\n|---|---|\n| `list_activities` | Filtered, paginated rows (date range, team, target) |\n| `get_activity` | Single row by id |\n| `search_activities` | FTS5 full-text search over title + description |\n| `count_activities` | Row count matching the same filters as list |\n| `aggregate_activities` | Group-by counts (team / target / spass_type) |\n| `timeline` | Bucketed counts over a date range (year or month) — zero-filled |\n| `list_distinct` | Distinct values of team / target / spass_type |\n\n## Architecture\n\n- **Runtime:** Cloudflare Workers (TypeScript)\n- **Data:** Cloudflare D1 (SQLite) — `master_plan` table + FTS5 virtual table\n- **Transport:** hand-rolled MCP-over-HTTP (JSON-RPC 2.0 over plain HTTP POST)\n- **Validation:** zod schemas per tool; errors surface as JSON-RPC error objects\n\nSee `docs/ARCHITECTURE.md` for the full design.\n\n## Project setup\n\n```bash\nnpm install\n```\n\n## Run tests\n\n```bash\nnpm test                  # Jest — all specs against in-memory SQLite\n```\n\nThe deploy spec (`spec/deploy-and-initialize.spec.ts`) needs a live URL:\n\n```bash\nDEPLOY_URL=https://cassini-mission-plan.redfour.workers.dev npm test\n```\n\n## Deploy (one-time setup)\n\n1. **Create the D1 database:**\n   ```bash\n   npx wrangler d1 create cassini\n   ```\n   Copy the `database_id` into `wrangler.toml`.\n\n2. **Import the data** (generates `data/cassini.d1.sql` from `data/cassini.db`):\n   ```bash\n   node scripts/import.js      # or: npx ts-node scripts/import.ts\n   npx wrangler d1 execute cassini --remote --file=data/cassini.d1.sql\n   ```\n\n3. **Deploy:**\n   ```bash\n   npm run deploy\n   ```\n\n## Local dev\n\n```bash\nnpm run dev   # wrangler dev (uses local D1)\n```\n\n## Docs\n\n| File | What's in it |\n|---|---|\n| `docs/PROJECT.md` | Problem, audience, goals, scope |\n| `docs/ARCHITECTURE.md` | Components, data model, key decisions |\n| `docs/SPEC.md` | Tool API reference + functional/non-functional requirements |\n| `docs/STORIES.md` | User stories (source for the spec suite) |\n| `docs/PLAN.md` | Build task checklist (all complete) |\n| `docs/MEMORY.md` | Decision log maintained with Claude Code |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobconery%2Fcassini-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobconery%2Fcassini-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobconery%2Fcassini-workshop/lists"}