The README prerequisites were both stale, and the docs restated the Go version in three places. ## Prerequisites: name the source, do not restate the version | README said | Reality | |---|---| | `Go 1.24.x` | `go 1.26` in [go.mod](https://github.com/modelcontextprotocol/registry/blob/main/go.mod) | | `golangci-lint v2.4.0` | `v2.11.4` pinned in [ci.yml:30](https://github.com/modelcontextprotocol/registry/blob/main/.github/workflows/ci.yml#L30) | Rather than swap in fresher numbers — which only resets the clock on the same drift — this **removes the numbers** and names the authoritative file: ``` - **Go** - version per the `go` directive in go.mod; the Go toolchain fetches it for you - **golangci-lint** - version per the `golangci-lint-action` pin in ci.yml, so local lint matches CI ``` The Go version was stated in **three** places, which is exactly why all three drifted together. All three now point at a single source, so the prerequisites list cannot go stale. Two notes on why the numbers earn so little in prose: - **Go corrects itself.** `go.mod` has no `toolchain` directive, so under the default `GOTOOLCHAIN=auto` the toolchain downloads the required version automatically. A contributor on an older Go gets an upgrade, not a failure — it only hard-errors under `GOTOOLCHAIN=local`. (An earlier version of this description said such a contributor "cannot build"; that was too strong.) - **golangci-lint does not.** Version skew here genuinely changes what you see: running CI's config under a newer golangci-lint (2.12.2) surfaces 23 `goconst` findings in `cmd/publisher/commands/validate_test.go` that CI's pinned 2.11.4 does not report. That is why the README now points at the pin rather than a number someone has to keep in sync. ## `make check` does more than documented Documented in three files as "lint, unit tests and integration tests". Actually [`check: dev-down lint validate test-all`](https://github.com/modelcontextprotocol/registry/blob/main/Makefile#L85) — it also runs schema validation and **stops your running `dev-compose` environment**. Worth knowing before running it mid-session. The Makefile's own `##` help string already said this correctly; only the prose was stale. ## Other verified corrections - **README project structure** omitted `cmd/registry/` — the server entry point and ko/goreleaser build target — and `internal/importer/`. - **`tests/integration/README.md`** said the suite launches **MongoDB**. It launches PostgreSQL (`postgres-integration-test`), as the same file admits nine lines later. It also cited `/v0/servers/{server_id}`, a path removed a while ago; the test actually calls `GET /v0/servers` and `GET /v0/servers/{serverName}/versions/latest` ([main.go:210,255](https://github.com/modelcontextprotocol/registry/blob/main/tests/integration/main.go#L210)). - **`scripts/mirror_data/README.md`** pointed at `internal/database/migrations/008_separate_official_metadata.sql`, which does not exist — that migration is `009_`, while `008_` is `clean_invalid_data.sql`. (Migration 008's own header still calls itself "007a", which is how the numbering slipped.) Also swapped two "edit line NN" pointers for identifier names, since both had already drifted (`maxMigration` is at :30 not :24; the connection string at :23 not :17), and corrected the fetch URL from `/v0.1/servers` to the `/v0/servers` the script actually requests. - **`.env.example`** was missing `MCP_REGISTRY_ENABLE_REGISTRY_VALIDATION`, even though the config reads it ([config.go:18](https://github.com/modelcontextprotocol/registry/blob/main/internal/config/config.go#L18)) and README:50 tells contributors to set it while pointing at `.env.example` as *the* reference. - **`docker-compose.yml`** set `MCP_REGISTRY_ENVIRONMENT`, which nothing reads — no `ENVIRONMENT` env tag in `internal/config`, and no other occurrence in the repo. Removed. (The Pulumi-side `mcp-registry:environment` key is a separate, real thing and is untouched.) - **Deleted `CHANGES.md`** — 0 bytes, untouched since the squashed history base, zero references anywhere. ## Verification `docker compose config` validates. `grep` for `Go 1.x` / `golangci-lint vX` across all `.md`/`.mdx` now returns nothing outside `complete.md` (which #1522 deletes). Both `../../README.md#pre-requisites` links resolve and the anchor matches the real `#### Pre-requisites` heading. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
237 lines
No EOL
6.5 KiB
Markdown
237 lines
No EOL
6.5 KiB
Markdown
# Mirror Production Data
|
|
|
|
> **Note:** These tools were created by Claude Code as a simple way to kick the tires on data migrations.
|
|
> They are not intended for production use.
|
|
|
|
Tools to fetch and load production registry data for local testing and migration debugging.
|
|
|
|
## Overview
|
|
|
|
These scripts help you:
|
|
1. Fetch all server data from the production registry API
|
|
2. Load it into a local PostgreSQL database
|
|
3. Test migrations against real production data
|
|
|
|
## Prerequisites
|
|
|
|
- Go — see the [prerequisites in the root README](../../README.md#pre-requisites) for the required version
|
|
- PostgreSQL (via Docker or local installation)
|
|
- Required Go packages:
|
|
```bash
|
|
go get github.com/google/uuid github.com/lib/pq
|
|
```
|
|
|
|
## Usage
|
|
|
|
### 1. Fetch Production Data
|
|
|
|
```bash
|
|
# From the project root directory
|
|
go run scripts/mirror_data/fetch_production_data.go
|
|
```
|
|
|
|
This will:
|
|
- Fetch all servers from https://registry.modelcontextprotocol.io/v0/servers
|
|
- Handle pagination automatically
|
|
- Save data to `scripts/mirror_data/production_servers.json`
|
|
- Be respectful to the API with rate limiting
|
|
|
|
Output: `production_servers.json` containing all server records
|
|
|
|
### 2. Set Up Test Database
|
|
|
|
Start a PostgreSQL container for testing:
|
|
|
|
```bash
|
|
docker run -d --name test-postgres \
|
|
-p 5433:5432 \
|
|
-e POSTGRES_PASSWORD=testpass \
|
|
-e POSTGRES_DB=registry_test \
|
|
postgres:16
|
|
```
|
|
|
|
Or reset an existing database:
|
|
|
|
```bash
|
|
docker exec test-postgres psql -U postgres postgres -c "DROP DATABASE IF EXISTS registry_test;"
|
|
docker exec test-postgres psql -U postgres postgres -c "CREATE DATABASE registry_test;"
|
|
```
|
|
|
|
### 3. Load Production Data
|
|
|
|
```bash
|
|
# From the project root directory
|
|
go run scripts/mirror_data/load_production_data.go
|
|
```
|
|
|
|
This will:
|
|
1. Connect to PostgreSQL at `localhost:5433`
|
|
2. Apply migrations up to a configurable point (default: migration 007)
|
|
3. Load all production server data
|
|
4. Analyze the data and report statistics
|
|
5. Show sample servers with NULL status values
|
|
|
|
To test a different migration, edit `maxMigration` in `load_production_data.go`
|
|
|
|
### 4. Test Migrations
|
|
|
|
After loading the data, you can test migrations against real production data.
|
|
|
|
#### Testing a Single Migration
|
|
|
|
```bash
|
|
# Test the separate_official_metadata migration
|
|
cat internal/database/migrations/009_separate_official_metadata.sql | \
|
|
docker exec -i test-postgres psql -U postgres -d registry_test
|
|
```
|
|
|
|
#### Debugging Failed Migrations
|
|
|
|
1. **Check the error output:**
|
|
```bash
|
|
# Run migration and capture all output
|
|
cat internal/database/migrations/009_separate_official_metadata.sql | \
|
|
docker exec -i test-postgres psql -U postgres -d registry_test 2>&1 | \
|
|
grep -E "(ERROR|NOTICE|WARNING)"
|
|
```
|
|
|
|
2. **Inspect data before migration:**
|
|
```bash
|
|
# Check for NULL values that might cause issues
|
|
docker exec test-postgres psql -U postgres -d registry_test -c \
|
|
"SELECT COUNT(*) FROM servers WHERE value->>'status' IS NULL;"
|
|
|
|
# Find sample problematic records
|
|
docker exec test-postgres psql -U postgres -d registry_test -c \
|
|
"SELECT value->>'name', value->>'version' FROM servers \
|
|
WHERE value->>'status' IS NULL LIMIT 5;"
|
|
```
|
|
|
|
3. **Test partial migrations:**
|
|
```bash
|
|
# Extract and run only part of a migration to isolate issues
|
|
# For example, run only up to the NOT NULL constraint:
|
|
docker exec test-postgres psql -U postgres -d registry_test <<EOF
|
|
BEGIN;
|
|
-- Paste migration SQL up to the problematic line
|
|
-- Check intermediate state
|
|
SELECT COUNT(*) FROM servers WHERE status IS NULL;
|
|
ROLLBACK; -- or COMMIT if testing further
|
|
EOF
|
|
```
|
|
|
|
#### Testing Migration Rollback
|
|
|
|
```bash
|
|
# Start a transaction to test and rollback
|
|
docker exec test-postgres psql -U postgres -d registry_test <<EOF
|
|
BEGIN;
|
|
\i /dev/stdin < internal/database/migrations/009_separate_official_metadata.sql
|
|
-- Inspect the results
|
|
\d servers
|
|
SELECT COUNT(*) FROM servers;
|
|
ROLLBACK; -- Undo all changes
|
|
EOF
|
|
```
|
|
|
|
#### Iterative Testing Workflow
|
|
|
|
1. **Reset database to clean state:**
|
|
```bash
|
|
docker exec test-postgres psql -U postgres postgres -c "DROP DATABASE IF EXISTS registry_test;"
|
|
docker exec test-postgres psql -U postgres postgres -c "CREATE DATABASE registry_test;"
|
|
go run scripts/mirror_data/load_production_data.go
|
|
```
|
|
|
|
2. **Test your migration changes:**
|
|
```bash
|
|
cat internal/database/migrations/009_separate_official_metadata.sql | \
|
|
docker exec -i test-postgres psql -U postgres -d registry_test
|
|
```
|
|
|
|
3. **Verify the results:**
|
|
```bash
|
|
# Check final table structure
|
|
docker exec test-postgres psql -U postgres -d registry_test -c "\d servers"
|
|
|
|
# Verify data integrity
|
|
docker exec test-postgres psql -U postgres -d registry_test -c \
|
|
"SELECT COUNT(*), COUNT(DISTINCT server_name) FROM servers;"
|
|
```
|
|
|
|
#### Common Migration Issues to Check
|
|
|
|
- **NULL values:** Check columns before adding NOT NULL constraints
|
|
- **Unique constraints:** Verify no duplicates exist before adding
|
|
- **Check constraints:** Validate all existing data matches the constraint
|
|
- **Data type changes:** Ensure all values can be cast to new type
|
|
- **Foreign keys:** Verify referential integrity before adding
|
|
|
|
### 5. Clean Up
|
|
|
|
```bash
|
|
docker stop test-postgres
|
|
docker rm test-postgres
|
|
```
|
|
|
|
## Configuration
|
|
|
|
The `load_production_data.go` script connects to:
|
|
- Host: `localhost`
|
|
- Port: `5433`
|
|
- Database: `registry_test`
|
|
- User: `postgres`
|
|
- Password: `testpass`
|
|
|
|
Modify the `sql.Open` connection string in `load_production_data.go` if you need different connection parameters.
|
|
|
|
## Example Output
|
|
|
|
When running `load_production_data.go`:
|
|
|
|
```
|
|
Running migrations 001-007...
|
|
Applying migration 1: 001_initial_schema.sql
|
|
Applying migration 2: 002_add_server_extensions.sql
|
|
...
|
|
|
|
Loading production data...
|
|
Loading 779 servers...
|
|
Data loaded successfully!
|
|
|
|
Total servers in database: 779
|
|
|
|
Analyzing status field in JSON data...
|
|
Total servers: 779
|
|
NULL status: 126
|
|
Empty status: 0
|
|
'null' string status: 0
|
|
'active' status: 652
|
|
'deprecated' status: 0
|
|
'deleted' status: 0
|
|
Other/Invalid: 1
|
|
|
|
Sample servers with NULL status:
|
|
- com.biodnd/agent-ip@0.1.2
|
|
- io.github.jkakar/cookwith-mcp@1.0.0
|
|
...
|
|
|
|
Database is ready for testing migration 008!
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Port already in use
|
|
If port 5433 is already in use, either:
|
|
- Stop the existing service using that port
|
|
- Use a different port in both the Docker command and the Go script
|
|
|
|
### Connection refused
|
|
Ensure the PostgreSQL container is running and healthy:
|
|
```bash
|
|
docker ps | grep test-postgres
|
|
docker logs test-postgres
|
|
```
|
|
|
|
### Migration failures
|
|
The script stops at migration 007 intentionally. To test later migrations (008 onwards), run them manually after the data is loaded, in order. |