An MCP server that makes Claude less wrong about the current state of AI. It pulls primary sources (release notes, GitHub activity, download stats, HN posts), computes metrics nobody publishes (hype-to-adoption ratio, momentum, lab velocity), and lets practitioners submit corrections when Claude gets something wrong. The corrections stick.
Same stack as signal-cascade: Python, FastAPI, fastmcp, PostgreSQL, Alembic, deployed on Render.
- MCP server running on Render
- ~100 key AI projects and ~10 labs seeded and tracked
- Daily ingest: GitHub stats, PyPI downloads, releases, HN posts
- Derived metrics: momentum, hype-to-adoption ratio, lab velocity
- Claude can answer "what actually shipped this week", "is X hype or real adoption", "which lab is shipping fastest"
- Practitioners can submit corrections through Claude, and those corrections persist
The organisations doing the work.
| Column | Type | Notes |
|---|---|---|
| id | serial PK | |
| name | text | "Anthropic", "OpenAI", etc. |
| slug | text unique | "anthropic", "openai" |
| url | text | Main website |
| blog_url | text | nullable |
| github_org | text | nullable, e.g. "anthropics" |
| created_at | timestamptz | default now() |
Seed ~10: Anthropic, OpenAI, Google DeepMind, Meta AI, Mistral, Cohere, Stability AI, Hugging Face, Together AI, Groq.
The repos, tools, frameworks, and models we track.
| Column | Type | Notes |
|---|---|---|
| id | serial PK | |
| name | text | "Claude Code", "vllm", "ollama" |
| slug | text unique | "claude-code", "vllm", "ollama" |
| category | text | model, framework, tool, library, infra, agent |
| lab_id | int FK | nullable — not everything belongs to a lab |
| github_owner | text | nullable |
| github_repo | text | nullable |
| pypi_package | text | nullable |
| npm_package | text | nullable |
| description | text | one-liner |
| url | text | nullable |
| is_active | bool | default true |
| created_at | timestamptz | |
| updated_at | timestamptz |
Seed ~100 projects across categories: major models (GPT-4, Claude, Gemini, Llama, Mistral), frameworks (LangChain, LlamaIndex, DSPy, CrewAI, Haystack), inference (vLLM, Ollama, llama.cpp, TGI), tools (Cursor, Claude Code, Copilot, Aider), libraries (transformers, openai-python, anthropic-sdk), infra (Modal, Replicate, Together), agents (AutoGPT, OpenDevin, SWE-agent).
Point-in-time captures of GitHub repo state. One row per project per day.
| Column | Type | Notes |
|---|---|---|
| id | serial PK | |
| project_id | int FK | |
| captured_at | timestamptz | |
| stars | int | |
| forks | int | |
| open_issues | int | |
| watchers | int | |
| commits_30d | int | commits in last 30 days |
| contributors | int | total contributor count |
| last_commit_at | timestamptz | most recent commit |
| license | text | nullable |
Unique constraint: (project_id, captured_at::date) — one snapshot per project per day.
Package download stats over time.
| Column | Type | Notes |
|---|---|---|
| id | serial PK | |
| project_id | int FK | |
| captured_at | timestamptz | |
| source | text | "pypi", "npm" |
| downloads_daily | bigint | last day |
| downloads_weekly | bigint | last 7 days |
| downloads_monthly | bigint | last 30 days |
Unique constraint: (project_id, source, captured_at::date).
Shipped things. From GitHub releases API, lab blogs, changelogs.
| Column | Type | Notes |
|---|---|---|
| id | serial PK | |
| project_id | int FK | nullable |
| lab_id | int FK | nullable |
| version | text | nullable — not everything is versioned |
| title | text | |
| summary | text | Claude-generated summary of release notes |
| body | text | raw release notes / changelog entry |
| url | text | link to release |
| released_at | timestamptz | when it shipped |
| captured_at | timestamptz | when we ingested it |
| source | text | "github", "blog", "changelog" |
Unique constraint: (url) — deduplicate by URL.
Hacker News signal. Filtered to AI-relevant posts.
| Column | Type | Notes |
|---|---|---|
| id | serial PK | |
| hn_id | int unique | HN item ID |
| title | text | |
| url | text | nullable (some are Ask HN) |
| author | text | |
| points | int | |
| num_comments | int | |
| post_type | text | "show", "ask", "link" |
| posted_at | timestamptz | |
| captured_at | timestamptz | |
| project_id | int FK | nullable — linked if we can match |
The community layer. What makes this compound.
| Column | Type | Notes |
|---|---|---|
| id | serial PK | |
| topic | text | what this is about — a project, a claim, a trend |
| correction | text | the actual correction |
| context | text | nullable — what Claude said that was wrong |
| submitted_by | text | nullable — contributor identifier |
| submitted_at | timestamptz | default now() |
| status | text | "active", "superseded", "rejected" |
| upvotes | int | default 0 — other users confirming |
| tags | text[] | for categorisation |
Index on topic, full-text index on correction.
Same pattern as signal-cascade. Fire-and-forget analytics.
| Column | Type | Notes |
|---|---|---|
| id | serial PK | |
| tool_name | text | |
| params | jsonb | |
| duration_ms | int | |
| success | bool | |
| error_message | text | nullable |
| result_size | int | |
| created_at | timestamptz |
Ingest audit trail.
| Column | Type | Notes |
|---|---|---|
| id | serial PK | |
| sync_type | text | "github", "downloads", "releases", "hn", "views" |
| status | text | "success", "failed" |
| records_written | int | |
| error_message | text | nullable |
| started_at | timestamptz | |
| finished_at | timestamptz |
Rate of change in adoption signals. The leading indicator.
-- Stars velocity: compare latest snapshot to 7 and 30 days ago
-- Download velocity: same
-- Output: project_id, stars_7d_delta, stars_30d_delta,
-- downloads_7d_delta, downloads_30d_delta,
-- stars_velocity (% change), downloads_velocity (% change)The metric nobody publishes. Stars / monthly downloads.
-- High ratio = lots of excitement, not much real use (hype)
-- Low ratio = quiet adoption, nobody's written the explainer yet (signal)
-- Output: project_id, stars, monthly_downloads, hype_ratio,
-- hype_bucket ("hype", "balanced", "quiet_adoption", "no_data")How fast are labs actually shipping?
-- Releases per lab per 30-day window
-- Commit activity across lab's projects
-- Output: lab_id, releases_30d, releases_90d,
-- avg_days_between_releases, is_accelerating (bool)One-stop view for any project. Joins latest snapshot, downloads, momentum, hype ratio.
-- Output: project_id, name, category, lab_name,
-- stars, forks, monthly_downloads,
-- stars_velocity, downloads_velocity,
-- hype_ratio, hype_bucket,
-- last_release_at, last_release_title,
-- days_since_last_release, last_commit_at,
-- correction_count"What actually shipped this week?"
Returns: recent releases across all tracked projects and labs, sorted by date. Grouped by lab. Includes release summaries. Flags anything with unusual momentum.
Deep dive on a specific project.
Returns: latest GitHub stats, download trends, momentum, hype ratio, recent releases, last commit, relevant HN posts, active corrections. Everything Claude needs to give a current, grounded answer about this project.
What is this lab actually shipping?
Returns: recent releases across all tracked projects for this lab, release cadence, whether they're accelerating or decelerating, commit activity. Facts, not press releases.
What's accelerating right now?
Returns: projects ranked by momentum (stars velocity + downloads velocity), optionally filtered by category. The things that are moving, not the things that are big.
Is this hype or real adoption?
Returns: the hype-to-adoption ratio (stars / downloads), how it compares to similar projects, trend over time. One number that cuts through the noise.
Read-only SQL. Same pattern as signal-cascade. Max 1000 rows.
Table and column listing so Claude can write informed queries.
The correction engine. Claude drafts it, the user confirms.
Topic is free-text but should match a project name, lab name, or concept. Context captures what Claude said that was wrong (so corrections are traceable).
"Yeah, that's right." Lightweight confirmation from another practitioner.
View active corrections, optionally filtered by topic.
What this server is, what it tracks, how corrections work, when data was last updated. The orientation tool.
- GitHub REST API with token auth
- Rate limit: 5000 req/hr with token
- For each active project with github_owner + github_repo:
- GET
/repos/{owner}/{repo}— stars, forks, issues, watchers, license, last push - GET
/repos/{owner}/{repo}/stats/commit_activity— weekly commit counts (last year) - GET
/repos/{owner}/{repo}/contributors?per_page=1&anon=true— total contributors (from Link header)
- GET
- Insert into
github_snapshots - Schedule: daily
- PyPI:
https://pypistats.org/api/packages/{package}/recent— last day/week/month- Rate limit: 30 req/min
- npm:
https://api.npmjs.org/downloads/point/{period}/{package}- Periods: last-day, last-week, last-month
- Insert into
download_snapshots - Schedule: daily
- GitHub Releases API:
GET /repos/{owner}/{repo}/releases?per_page=10 - For each release:
- Capture version, title, body (markdown), url, published_at
- Generate summary from body (Claude or simple truncation for MVP)
- Deduplicate by URL
- Schedule: every 6 hours, or on-demand via
refresh_projecttool
- Algolia HN API:
https://hn.algolia.com/api/v1/search_by_date - Query: AI-related terms (LLM, GPT, Claude, Anthropic, OpenAI, etc.)
- Filter: last 7 days, min 10 points
- Match to projects where possible (fuzzy on title)
- Schedule: every 6 hours
- Same tiered refresh pattern as signal-cascade
- Tier 0: mv_momentum, mv_hype_ratio, mv_lab_velocity
- Tier 1: mv_project_summary (depends on all tier 0)
- Schedule: after each ingest cycle
pt-edge/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI + MCP mount
│ ├── db.py # SQLAlchemy engine/session
│ ├── settings.py # Pydantic BaseSettings
│ ├── models/
│ │ ├── __init__.py
│ │ ├── base.py # DeclarativeBase
│ │ ├── core.py # Lab, Project
│ │ ├── snapshots.py # GitHubSnapshot, DownloadSnapshot
│ │ ├── content.py # Release, HNPost
│ │ ├── community.py # Correction
│ │ └── meta.py # ToolUsage, SyncLog
│ ├── ingest/
│ │ ├── __init__.py
│ │ ├── github.py # GitHub API client
│ │ ├── downloads.py # PyPI + npm stats
│ │ ├── releases.py # GitHub releases
│ │ ├── hn.py # Hacker News via Algolia
│ │ └── runner.py # Orchestrator
│ ├── mcp/
│ │ ├── __init__.py
│ │ ├── server.py # MCP tool definitions
│ │ └── tracking.py # Usage tracking decorator
│ ├── views/
│ │ ├── __init__.py
│ │ └── refresh.py # Materialized view refresh
│ └── migrations/
│ ├── env.py
│ └── versions/
├── scripts/
│ ├── seed.py # Seed labs + projects
│ ├── ingest_all.py # Run full ingest cycle
│ ├── ingest_github.py # GitHub stats only
│ ├── ingest_downloads.py # Download stats only
│ ├── ingest_releases.py # Releases only
│ ├── ingest_hn.py # HN posts only
│ └── refresh_views.py # Refresh materialized views
├── seeds/
│ ├── labs.json # Lab definitions
│ └── projects.json # Project definitions (~100)
├── pyproject.toml
├── requirements.txt
├── alembic.ini
├── Dockerfile
├── docker-compose.yml # Local Postgres
├── render.yaml
├── .env.example
├── .gitignore
└── PLAN.md
Morning: Scaffold
- Init git repo, pyproject.toml, requirements.txt
- Copy and adapt from signal-cascade: db.py, settings.py, main.py, base model, Dockerfile, docker-compose.yml, .env.example, .gitignore
- Settings: DATABASE_URL, API_TOKEN, GITHUB_TOKEN
- FastAPI app with healthz endpoint
- Alembic init
Afternoon: Core schema + GitHub ingest
- Models: Lab, Project, GitHubSnapshot, SyncLog
- First migration: create tables
- Seed data: labs.json (~10 labs), projects.json (~100 projects with GitHub coords)
scripts/seed.py— load from JSON- GitHub ingest client:
- Async httpx with token auth
- Rate-limit aware (check X-RateLimit-Remaining header)
- Fetch repo stats + commit activity + contributor count
scripts/ingest_github.py— run for all projects- Test: seed + ingest + verify data in Postgres
Morning: More ingest
- Models: DownloadSnapshot, Release, HNPost
- Migration: add tables
- Downloads ingest: PyPI stats API (and npm for JS projects)
- Releases ingest: GitHub Releases API, store raw + summary
- HN ingest: Algolia search API, AI keyword filter
scripts/ingest_all.py— orchestrate full cycle
Afternoon: Materialized views + derived metrics
- mv_momentum — stars/downloads velocity (7d and 30d deltas)
- mv_hype_ratio — stars / monthly downloads
- mv_lab_velocity — release frequency per lab
- mv_project_summary — unified view
- Migration: create all views
scripts/refresh_views.py- Test: verify derived metrics make sense
Morning: MCP server
- Copy tracking.py from signal-cascade (fire-and-forget usage logging)
- Model: ToolUsage, Correction
- Migration: add tables
- Implement tools:
about()— orientationdescribe_schema()— table listingquery(sql)— read-only SQLwhats_new(days)— recent releases + trendingproject_pulse(project)— deep divelab_pulse(lab)— lab shipping cadencetrending(category)— momentum rankinghype_check(project)— the ratiosubmit_correction(topic, correction, context)— the engineupvote_correction(correction_id)— confirmationlist_corrections(topic)— browse corrections
- Bearer token auth middleware (same as signal-cascade)
Afternoon: Deploy + polish
- render.yaml — web service + managed Postgres
- Push to GitHub, connect Render
- Run seed + full ingest on production
- Refresh views
- Connect Claude Desktop to production MCP endpoint
- Smoke test: ask Claude real questions, verify answers are grounded
[
{"name": "Anthropic", "slug": "anthropic", "github_org": "anthropics"},
{"name": "OpenAI", "slug": "openai", "github_org": "openai"},
{"name": "Google DeepMind", "slug": "google-deepmind", "github_org": "google-deepmind"},
{"name": "Meta AI", "slug": "meta-ai", "github_org": "facebookresearch"},
{"name": "Mistral AI", "slug": "mistral", "github_org": "mistralai"},
{"name": "Cohere", "slug": "cohere", "github_org": "cohere-ai"},
{"name": "Hugging Face", "slug": "hugging-face", "github_org": "huggingface"},
{"name": "Stability AI", "slug": "stability-ai", "github_org": "Stability-AI"},
{"name": "Together AI", "slug": "together-ai", "github_org": "togethercomputer"},
{"name": "Groq", "slug": "groq", "github_org": "groq"}
]Models & APIs: claude, gpt-4, gemini, llama, mistral-models, command-r, stable-diffusion, flux, phi, qwen, deepseek, gemma
Frameworks: langchain, llamaindex, dspy, crewai, haystack, semantic-kernel, autogen, pydantic-ai, smolagents, mastra
Inference: vllm, ollama, llama-cpp, tgi, sglang, mlx, exllamav2, tensorrt-llm
Tools: cursor, claude-code, aider, continue-dev, cody, open-interpreter, fabric
Libraries: transformers, openai-python, anthropic-sdk, litellm, instructor, outlines, guidance, lmstudio
Infra: modal, replicate, together-platform, anyscale, fireworks-ai, chromadb, qdrant, weaviate, pgvector, lancedb
Agents: opendevin, swe-agent, devika, gpt-engineer, sweep, cognition-devin
Evaluation: lm-eval-harness, ragas, promptfoo, giskard
- arXiv papers — daily new AI papers, linked to labs/projects
- Lab blog monitoring — RSS/scrape for announcements not on GitHub
- Multi-user corrections — API keys per user, attribution
- Correction confidence — weighted by contributor track record
- Weekly digest tool —
weekly_briefing()summarising the week - Benchmark tracking — MMLU, HumanEval, etc. scores over time
- Model pricing tracker — $/token across providers over time
- Comparison tools —
compare(project_a, project_b)head-to-head - Scheduled ingest — cron job or Render cron, not manual scripts
- Embeddings on corrections — semantic search over community knowledge
-
Same stack as signal-cascade — no reason to change what works. Python, FastAPI, fastmcp, PostgreSQL, Alembic, Render.
-
Snapshots over diffs — store full point-in-time snapshots rather than deltas. More storage, much simpler queries. Diffs are computed in views.
-
Free-text topics on corrections — not forcing corrections to link to a specific project_id. People will correct claims about concepts, trends, comparisons — not just project facts. Full-text search handles retrieval.
-
Claude generates release summaries — the raw body of a GitHub release can be thousands of lines of changelog. Store both raw and summary. For MVP, summary can be simple truncation; Claude can summarise on read.
-
No embeddings for MVP — pure SQL, same as signal-cascade. Keyword matching and full-text search are enough for a corpus of this size. Add pgvector later if needed.
-
Daily ingest is fine — we're not building a real-time feed. Daily GitHub + downloads, 6-hourly releases + HN. The value is in the derived metrics and corrections, not millisecond freshness.
-
~100 projects is enough — better to have good coverage of 100 important projects than noisy coverage of 1000. The seed list is an editorial choice and it matters. Easy to add more later.