Mirror of https://github.com/modelcontextprotocol/registry — A community driven registry service for Model Context Protocol (MCP) servers.
  • Go 92.9%
  • PLpgSQL 3.1%
  • HTML 1.9%
  • Shell 1.6%
  • Makefile 0.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Kalle Bylin 0ffcd36047
Add optional subfolder field to Repository schema (#363)
Adds an optional `subfolder` field to the Repository object in
server.json schema to support MCP servers located within subdirectories
of monorepo structures.

## Motivation and Context

Addresses issue #360 .

The current MCP registry schema doesn't explicitly define how to
reference servers that are located within a subdirectory of a Git
repository (a "monorepo" structure). This is a common pattern (e.g.,
[microsoft/mcp](https://github.com/microsoft/mcp) &
[awslabs/mcp](https://github.com/awslabs/mcp).

## How Has This Been Tested?

- **Validator tests**: Added 6 new test cases covering valid subfolders
and security validation (path traversal, absolute paths, invalid
characters, etc.)
- **Schema validation**: All 11 examples in `examples.md` validate
successfully against both `server.schema.json` and
`registry-schema.json`
- **End-to-end validation**: Publisher tool (`mcp-publisher init`) works
correctly and generates valid templates without subfolder
- **Backward compatibility**: Existing server.json files without
subfolder continue to work unchanged

## Breaking Changes

**None.** This is a fully backward-compatible change:
- The `subfolder` field is optional (uses `omitempty` JSON tag)
- Existing server.json files work unchanged
- Publisher tools generate valid templates without subfolder by default
- All existing validation and schemas remain compatible

## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] Documentation update

## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed


### Implementation Details

**Schema Changes:**
- Added `subfolder` property to Repository definition in
`server.schema.json` and `openapi.yaml`
- Field is optional with description and example (`"src/everything"`)

**Go Model:**
- Added `Subfolder string` field to Repository struct with
`json:"subfolder,omitempty"` tag
- Maintains backward compatibility through omitempty behavior

**Security-Focused Validation:**
- Validates subfolder is a clean relative path (no leading `/`)
- Prevents path traversal attacks (no `..` sequences)
- Blocks malformed paths (no trailing `/`, empty segments, invalid
characters)
- Uses regex validation for allowed characters: `^[a-zA-Z0-9\-_./]+$`

**Documentation:**
- Added monorepo example to `examples.md` demonstrating subfolder usage
- Updated `repository_references.md` with concise subfolder
documentation
- Maintained consistency across all documentation with same example path

**Testing:**
- 6 new integration tests in validator covering security and format
validation
- Updated example count validation tool for new example
- All existing tests continue to pass

### Design Decisions

1. **Optional by design**: Most servers don't need subfolder
(single-repo pattern is common)
2. **Clean separation**: Repository URL stays clean, subfolder is
separate metadata
3. **Security first**: Comprehensive validation prevents common
path-based attacks
4. **Publisher tool unchanged**: Default templates don't include
subfolder to avoid confusion for typical use cases

This enables publishers with monorepo structures to clearly specify
server locations while maintaining simplicity for the common
single-repository case.
2025-09-05 21:29:09 +01:00
.githooks Add linting documentation and pre-commit hooks (#177) 2025-07-15 09:31:17 -07:00
.github/workflows Replace Codecov with GitHub Actions artifacts (#310) 2025-08-27 12:23:56 +01:00
.vscode Move publisher CLI from tools/ to cmd/ (#326) 2025-08-29 14:45:36 +01:00
cmd Reflect the latest registry changes in openapi.yaml (#345) 2025-09-05 21:07:08 +01:00
data Reflect the latest registry changes in openapi.yaml (#345) 2025-09-05 21:07:08 +01:00
deploy Remove Azure/AKS deployment configuration from deploy (#347) 2025-09-02 22:32:36 +01:00
docs Add optional subfolder field to Repository schema (#363) 2025-09-05 21:29:09 +01:00
internal Add optional subfolder field to Repository schema (#363) 2025-09-05 21:29:09 +01:00
pkg Add optional subfolder field to Repository schema (#363) 2025-09-05 21:29:09 +01:00
scripts feat: Add support for MCP Bundles (MCPB) in registry (#295) 2025-08-27 04:44:53 +01:00
tests/integration Add registry validators (#350) 2025-09-04 22:45:59 +01:00
tools Add optional subfolder field to Repository schema (#363) 2025-09-05 21:29:09 +01:00
.dockerignore fix(docker): ignore local mongo .db during rebuild 2025-05-25 12:41:19 -07:00
.env.example config: remove unused database and logging configuration options (#349) 2025-09-03 16:02:02 +01:00
.gitignore feat(infra): Add Pulumi-based Kubernetes deployment infrastructure (#237) 2025-08-11 19:43:49 +01:00
.golangci.yml Disable ireturn linter rule (#307) 2025-08-26 15:16:43 +01:00
CLAUDE.md Consolidate documentation and remove redundancy (#222) 2025-08-06 16:05:07 +01:00
docker-compose.yml feat: implement OIDC authentication for admin users (#316) 2025-08-27 18:59:49 +01:00
Dockerfile build: Optimize Dockerfile by splitting out dependency installation and go build (#286) 2025-08-21 22:20:13 +01:00
go.mod Database implementation cleanup (#335) 2025-09-02 13:37:28 +01:00
go.sum feat: implement OIDC authentication for admin users (#316) 2025-08-27 18:59:49 +01:00
LICENSE Update LICENSE copyright holder to MCP Contributors (#293) 2025-08-21 09:11:42 -06:00
Makefile Database implementation cleanup (#335) 2025-09-02 13:37:28 +01:00
README.md Bump release date (#357) 2025-09-04 22:46:05 +01:00

MCP Registry

Warning

The registry is under active development. The registry API spec is unstable and the official MCP registry database may be wiped at any time.

📖 API Documentation | 📚 Technical Docs

What is the registry?

The registry will provide MCP clients with a list of MCP servers, like an app store for MCP servers. (In the future it might do more, like also hosting a list of clients).

There are two parts to the registry project:

  1. 🟦 The MCP registry spec: An API specification that allows anyone to implement a registry.
  2. 🟥 The Official MCP registry: A hosted registry following the MCP registry spec at registry.modelcontextprotocol.io. This serves as the authoritative repository for publicly-available MCP servers. Server creators publish once, and all consumers (MCP clients, aggregators, marketplaces) reference the same canonical data. This is owned by the MCP open-source community, backed by major trusted contributors to the MCP ecosystem such as Anthropic, GitHub, PulseMCP and Microsoft.

The registry is built around the server.json format - a standardized way to describe MCP servers that works across discovery, initialization, and packaging scenarios.

In time, we expect the ecosystem to look a bit like this:

Note that MCP registries are metaregistries. They host metadata about packages, but not the package code or binaries. Instead, they reference other package registries (like NPM, PyPi or Docker) for this.

Additionally, we expect clients pull from subregistries. These subregistries add value to the registry ecosystem by providing curation, or extending it with additional metadata. The Official MCP registry expects a lot of API requests from ETL jobs from these subregistries.

Development Status

2025-09-04 update: We're targeting a 'preview' go-live on 8th September. This may still be unstable and not provide durability guarantees, but is a step towards being more solidified. A general availability (GA) release will follow later.

Current key maintainers:

Contributing

We use multiple channels for collaboration - see modelcontextprotocol.io/community/communication.

Often (but not always) ideas flow through this pipeline:

  • Discord - Real-time community discussions
  • Discussions - Propose and discuss product/technical requirements
  • Issues - Track well-scoped technical work
  • Pull Requests - Contribute work towards issues

Quick start:

Pre-requisites

  • Docker
  • Go 1.24.x
  • golangci-lint v2.4.0

Running the server

# Start full development environment
make dev-compose

This starts the registry at localhost:8080 with PostgreSQL and seed data. It can be configured with environment variables in docker-compose.yml - see .env.example for a reference.

Alternative: Local setup without Docker

Prerequisites:

  • PostgreSQL running locally
  • Go 1.24.x installed
# Build and run locally
make build
make dev-local

The service runs on localhost:8080 by default. This can be configured with environment variables in .env - see .env.example for a reference.

Alternative: Running a pre-built Docker image

Pre-built Docker images are automatically published to GitHub Container Registry:

# Run latest from main branch
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:latest

# Run specific commit build
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:main-20250806-a1b2c3d

Available tags: latest, main-<date>-<sha>

Publishing a server

To publish a server, we've built a simple CLI. You can use it with:

# Build the latest CLI
make publisher

# Use it!
./cmd/publisher/bin/mcp-publisher --help

See the publisher README for more details.

Other commands

# Run lint, unit tests and integration tests
make check

There are also a few more helpful commands for development. Run make help to learn more, or look in Makefile.

Architecture

Project Structure

├── cmd/                     # Application entry points
│   └── publisher/           # Server publishing tool
├── data/                    # Seed data
├── deploy/                  # Deployment configuration (Pulumi)
├── docs/                    # Technical documentation
│   ├── server-json/         # server.json specification & examples
│   └── server-registry-api/ # API specification
├── internal/                # Private application code
│   ├── api/                 # HTTP handlers and routing
│   ├── auth/                # Authentication (GitHub OAuth, JWT, namespace blocking)
│   ├── config/              # Configuration management
│   ├── database/            # Data persistence (PostgreSQL, in-memory)
│   ├── service/             # Business logic
│   ├── telemetry/           # Metrics and monitoring
│   └── validators/          # Input validation
├── pkg/                     # Public packages
│   ├── api/                 # API types and structures
│   │   └── v0/              # Version 0 API types
│   └── model/               # Data models for server.json
├── scripts/                 # Development and testing scripts
├── tests/                   # Integration tests
└── tools/                   # CLI tools and utilities
    └── validate-*.sh        # Schema validation tools

Authentication

Publishing supports multiple authentication methods:

  • GitHub OAuth - For publishing by logging into GitHub
  • GitHub OIDC - For publishing from GitHub Actions
  • DNS verification - For proving ownership of a domain and its subdomains
  • HTTP verification - For proving ownership of a domain

The registry validates namespace ownership when publishing. E.g. to publish...:

  • io.github.domdomegg/my-cool-mcp you must login to GitHub as domdomegg, or be in a GitHub Action on domdomegg's repos
  • me.adamjones/my-cool-mcp you must prove ownership of adamjones.me via DNS or HTTP challenge

More documentation

See the docs folder for more details if your question has not been answered here!