Skip to content

Commit ebb353d

Browse files
Copilottoby
authored andcommitted
feat: allow registries to bootstrap server list from another registry
1 parent b5c6622 commit ebb353d

File tree

14 files changed

+650
-82
lines changed

14 files changed

+650
-82
lines changed

.github/workflows/ci.yml

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,38 +17,44 @@ jobs:
1717
steps:
1818
- name: Checkout code
1919
uses: actions/checkout@v4
20-
20+
2121
- name: Set up Go
2222
uses: actions/setup-go@v5
2323
with:
2424
go-version: ${{ env.GO_VERSION }}
25-
25+
26+
- name: Cleanup Go module cache
27+
run: sudo rm -rf ~/go/pkg/mod
28+
29+
- name: Cleanup cache
30+
run: sudo rm -rf ~/.cache
31+
2632
- name: Cache Go modules
2733
uses: actions/cache@v4
2834
with:
2935
path: |
3036
~/.cache/go-build
3137
~/go/pkg/mod
32-
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
38+
key: ${{ runner.os }}-go-${{ github.sha }}-${{ hashFiles('**/go.sum', '.golangci.yml') }}
3339
restore-keys: |
3440
${{ runner.os }}-go-
35-
41+
3642
- name: Download dependencies
3743
run: go mod download
38-
44+
3945
- name: Install golangci-lint
4046
run: |
41-
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.3.1
42-
47+
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.58.2
48+
4349
- name: Run lint
4450
run: make lint
45-
51+
4652
- name: Validate schemas and examples
4753
run: make validate
48-
54+
4955
- name: Build application
5056
run: make build
51-
57+
5258
- name: Check for vulnerabilities
5359
run: |
5460
go install golang.org/x/vuln/cmd/govulncheck@latest
@@ -61,12 +67,12 @@ jobs:
6167
steps:
6268
- name: Checkout code
6369
uses: actions/checkout@v4
64-
70+
6571
- name: Set up Go
6672
uses: actions/setup-go@v5
6773
with:
6874
go-version: ${{ env.GO_VERSION }}
69-
75+
7076
- name: Cache Go modules
7177
uses: actions/cache@v4
7278
with:
@@ -76,13 +82,13 @@ jobs:
7682
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
7783
restore-keys: |
7884
${{ runner.os }}-go-
79-
85+
8086
- name: Download dependencies
8187
run: go mod download
82-
88+
8389
- name: Run all tests
8490
run: make test-all
85-
91+
8692
- name: Upload coverage to Codecov
8793
uses: codecov/codecov-action@v4
8894
with:

.golangci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# GolangCI-Lint configuration
22
# See: https://golangci-lint.run/usage/configuration/
33

4-
version: "2"
54
run:
65
modules-download-mode: readonly
76
linters:
@@ -58,6 +57,9 @@ linters:
5857
- wastedassign
5958
- whitespace
6059
settings:
60+
errcheck:
61+
exclude-functions:
62+
- os:Open
6163
cyclop:
6264
max-complexity: 50
6365
funlen:

README.md

Lines changed: 168 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ The MCP Registry service provides a centralized repository for MCP server entrie
2727
- MongoDB and in-memory database support
2828
- Comprehensive API documentation
2929
- Pagination support for listing registry entries
30+
- **Seed data export/import composability with HTTP support**
31+
- **Registry instance data sharing via HTTP endpoints**
3032

3133
## Getting Started
3234

@@ -53,6 +55,27 @@ make dev-compose
5355

5456
This will start the MCP Registry service and MongoDB with Docker, running at [`localhost:8080`](http://localhost:8080).
5557

58+
### Registry Composability
59+
60+
The registry supports composability through seed data import/export, allowing registry instances to share data:
61+
62+
```bash
63+
# Start first registry with seed data
64+
MCP_REGISTRY_SEED_FILE_PATH=data/seed_2025_05_16.json ./registry
65+
66+
# Start second registry importing from first via HTTP
67+
./registry --seed-file-path=http://localhost:8080/v0/seed.json
68+
```
69+
70+
You can also use environment variables:
71+
```bash
72+
# Import from local file
73+
MCP_REGISTRY_SEED_FILE_PATH=data/seed_2025_05_16.json ./registry
74+
75+
# Import from remote registry
76+
MCP_REGISTRY_SEED_FILE_PATH=http://other-registry:8080/v0/seed.json ./registry
77+
```
78+
5679
## Building
5780

5881
If you prefer to run the service locally without Docker, you can build and run it directly:
@@ -78,6 +101,20 @@ To build the CLI tool for publishing MCP servers to the registry:
78101
make publisher
79102
```
80103

104+
### Command Line Options
105+
106+
The registry supports command line flags for configuration:
107+
108+
```bash
109+
# Specify seed file path via command line flag
110+
./registry --seed-file-path=data/seed_2025_05_16.json
111+
112+
# Import from HTTP endpoint
113+
./registry --seed-file-path=http://localhost:8080/v0/seed.json
114+
```
115+
116+
Command line flags take precedence over environment variables.
117+
81118
## Development
82119

83120
### Available Make Targets
@@ -385,6 +422,53 @@ Response example:
385422
}
386423
```
387424

425+
#### Export Seed Data
426+
427+
```
428+
GET /v0/seed.json
429+
```
430+
431+
Exports all servers in the registry in seed format for import by other registry instances.
432+
433+
Response example:
434+
```json
435+
[
436+
{
437+
"id": "01129bff-3d65-4e3d-8e82-6f2f269f818c",
438+
"name": "io.github.gongrzhe/redis-mcp-server",
439+
"description": "A Redis MCP server implementation for interacting with Redis databases.",
440+
"repository": {
441+
"url": "https://github.com/GongRzhe/REDIS-MCP-Server",
442+
"source": "github",
443+
"id": "907849235"
444+
},
445+
"version_detail": {
446+
"version": "0.0.1-seed",
447+
"release_date": "2025-05-16T19:13:21Z",
448+
"is_latest": true
449+
},
450+
"packages": [
451+
{
452+
"registry_name": "docker",
453+
"name": "@gongrzhe/server-redis-mcp",
454+
"version": "1.0.0",
455+
"package_arguments": [
456+
{
457+
"description": "Docker image to run",
458+
"is_required": true,
459+
"format": "string",
460+
"value": "mcp/redis",
461+
"default": "mcp/redis",
462+
"type": "positional",
463+
"value_hint": "mcp/redis"
464+
}
465+
]
466+
}
467+
]
468+
}
469+
]
470+
```
471+
388472
### Ping Endpoint
389473

390474
```
@@ -413,10 +497,92 @@ The service can be configured using environment variables:
413497
| `MCP_REGISTRY_GITHUB_CLIENT_ID` | GitHub App Client ID | |
414498
| `MCP_REGISTRY_GITHUB_CLIENT_SECRET` | GitHub App Client Secret | |
415499
| `MCP_REGISTRY_LOG_LEVEL` | Log level | `info` |
416-
| `MCP_REGISTRY_SEED_FILE_PATH` | Path to import seed file | `data/seed.json` |
417-
| `MCP_REGISTRY_SEED_IMPORT` | Import `seed.json` on first run | `true` |
500+
| `MCP_REGISTRY_SEED_FILE_PATH` | Path or URL to import seed file (supports local files and HTTP URLs) | `data/seed.json` |
418501
| `MCP_REGISTRY_SERVER_ADDRESS` | Listen address for the server | `:8080` |
419502

503+
### Command Line Flags
504+
505+
Command line flags take precedence over environment variables:
506+
507+
| Flag | Description | Environment Variable |
508+
|------|-------------|---------------------|
509+
| `--seed-file-path` | Path or URL to import seed file | `MCP_REGISTRY_SEED_FILE_PATH` |
510+
511+
## Registry Composability
512+
513+
The MCP Registry supports composability through seed data export/import functionality, enabling registry instances to share data with each other via HTTP endpoints.
514+
515+
### Use Cases
516+
517+
1. **Distributed Registries**: Set up multiple registry instances that share a common dataset
518+
2. **Registry Synchronization**: Import data from a central registry to local instances
519+
3. **Development Environments**: Import production data to development instances
520+
4. **Registry Migration**: Move data between different registry deployments
521+
522+
### Export Seed Data
523+
524+
Any registry instance can export its complete dataset:
525+
526+
```bash
527+
# Export all servers in seed format
528+
curl http://localhost:8080/v0/seed.json > exported_data.json
529+
```
530+
531+
### Import Seed Data
532+
533+
Registry instances can import data from:
534+
535+
**Local files:**
536+
```bash
537+
# Via environment variable
538+
MCP_REGISTRY_SEED_FILE_PATH=data/seed_2025_05_16.json ./registry
539+
540+
# Via command line flag
541+
./registry --seed-file-path=data/seed_2025_05_16.json
542+
```
543+
544+
**HTTP endpoints:**
545+
```bash
546+
# Via environment variable
547+
MCP_REGISTRY_SEED_FILE_PATH=http://localhost:8080/v0/seed.json ./registry
548+
549+
# Via command line flag
550+
./registry --seed-file-path=http://other-registry:8080/v0/seed.json
551+
```
552+
553+
### Composability Workflow Example
554+
555+
```bash
556+
# Step 1: Start primary registry with initial seed data
557+
MCP_REGISTRY_SEED_FILE_PATH=data/seed_2025_05_16.json ./registry
558+
559+
# Step 2: Start secondary registry importing from primary
560+
./registry --seed-file-path=http://localhost:8080/v0/seed.json --server-address=:8081
561+
562+
# Step 3: Verify both registries have the same data
563+
curl http://localhost:8080/v0/servers | jq '.servers | length'
564+
curl http://localhost:8081/v0/servers | jq '.servers | length'
565+
```
566+
567+
This enables true composability where registry instances can be distributed and synchronized, with new instances importing data from existing ones via HTTP.
568+
569+
570+
## Testing
571+
572+
Run the test script to validate API endpoints:
573+
574+
```bash
575+
./scripts/test_endpoints.sh
576+
```
577+
578+
You can specify specific endpoints to test:
579+
580+
```bash
581+
./scripts/test_endpoints.sh --endpoint health
582+
./scripts/test_endpoints.sh --endpoint servers
583+
```
584+
585+
>>>>>>> cf595b5 (Fix linting errors and update README with seed data composability features)
420586
## License
421587

422588
See the [LICENSE](LICENSE) file for details.

cmd/registry/main.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
func main() {
2323
// Parse command line flags
2424
showVersion := flag.Bool("version", false, "Display version information")
25+
seedFilePath := flag.String("seed-file-path", "", "Path to seed file for importing initial data")
2526
flag.Parse()
2627

2728
// Show version information if requested
@@ -43,6 +44,11 @@ func main() {
4344
// Initialize configuration
4445
cfg := config.NewConfig()
4546

47+
// Override seed file path if provided via command line flag
48+
if *seedFilePath != "" {
49+
cfg.SeedFilePath = *seedFilePath
50+
}
51+
4652
// Initialize services based on environment
4753
switch cfg.DatabaseType {
4854
case config.DatabaseTypeMemory:
@@ -79,9 +85,9 @@ func main() {
7985
return
8086
}
8187

82-
// Import seed data if requested (works for both memory and MongoDB)
83-
if cfg.SeedImport {
84-
log.Println("Importing data...")
88+
// Import seed data if seed file path is provided (works for both memory and MongoDB)
89+
if cfg.SeedFilePath != "" {
90+
log.Printf("Importing data from %s...", cfg.SeedFilePath)
8591
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
8692
defer cancel()
8793

go.mod

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,3 @@ require (
3838
golang.org/x/tools v0.32.0 // indirect
3939
gopkg.in/yaml.v3 v3.0.1 // indirect
4040
)
41-
42-
// temporary replace directive to use local version of the module so we can share in different orgs
43-
replace github.com/modelcontextprotocol/registry => ./

0 commit comments

Comments
 (0)