Skip to content

First cut at server.json #153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Conversation

tadasant
Copy link
Contributor

@tadasant tadasant commented Jun 27, 2025

This is a first cut at properly defining the server.json file. We have been working out details of the shape for a while, but to-date it has only been implicitly documented as the OpenAPI response to /servers/:id, which is not an exact definition due to some registry-specific details (like id and is_latest).

Edit: as-written in this PR, this is a more constrained version of server.json that the Registry intends to support at-launch. The broader server.json may have looser constraints, for example no enum constraint on source=github,gitlab. See #155


Motivation

There are a variety of use cases where a static representation of an MCP server is necessary:

  • Discoverability on a centralized registry (i.e. our official Registry work)
  • Discoverability on a decentralized .well-known endpoint
  • As a response to an initialization call, so the client knows information about the MCP server to which it is connecting
  • As an input into crafting a DXT file
  • Packaged in with the source code of an MCP server, so as to have a structured way context

All of these scenarios (and more) would benefit from an agreed-upon, standardized format that makes it easy to port around and maintain a consistent experience for consumers and developers working with the data. At the end of the day, it's all the same data (or a subset of it). MCP server maintainers should have to manage one copy of this file, and all these use cases can serve that file (or a programmatic derivative/subset of it).

Please note: this is different from the file commonly referred to as mcp.json, which is an MCP client's configuration file for running a specific set of MCP servers. See this issue.

In this PR

There is a JSON schema for the file (schema.json) and a set of examples for how some servers might look (examples.md).

This PR does not add any new features/changes that weren't in the codebase already. There are a handful of improvements we can make quickly, but given a bunch of conversations flying about this concept I wanted to get something in place to point to that isn't an OpenAPI spec. I think eventually this spec might do better to live in modelcontextprotocol/modelcontextprotol instead of modelcontextprotocol/registry, but the registry is probably the most heavily dependent piece of work related to it, so may as well keep it here for now.

Relevant Issues

Issue: #90

Fast follows I intend to do before closing that issue:

And there are definitely some pending in the registry backlog that could impact the shape further. Notably at least:

And some later issues that are not blockers for the registry work but maybe other folks will be interested in seeing them incorporated into this shape:

@tadasant tadasant requested review from toby and connor4312 June 27, 2025 01:09
@tadasant
Copy link
Contributor Author

cc @joelverhagen @felixrieseberg

@atrawog
Copy link

atrawog commented Jun 27, 2025

That's quite a sophistication list that's covering almost everything. But the one thing that could be still useful to add is some info about the supported OAuth Identify Provider(s).

Because we are likely going to see a rise of MCP Server with some form of OAuth authentication. Who either require the user to create a user account on a certain website. Or require an OAuth callback configuration from an Identify provider for user identification.

@tadasant
Copy link
Contributor Author

tadasant commented Jun 27, 2025

@atrawog yes, that is in:

And there are definitely some pending in the registry backlog that could impact the shape further. Notably at least:
OAuth Config (Optional) for Remotes #25

I think that would cover what you are describing?

@@ -0,0 +1,371 @@
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a script that auto-gens the overlapping portion of this from the openapi spec or vise versa? The schema is a little involved and I would not want them to accidentally diverge

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely feel that pain: I think I'd rather we have a script that's in CI validating that they are consistent though (e.g. that the OpenAPI spec's /servers/:id returns a shape that is compliant with server.json), rather than literally autogenerate one or the other. Let me know if you feel strongly otherwise

Will add that validation as a third fast follow here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we make changes to one or the other, I would prefer not to have to update both YAML and JSON schema to do so. I think a nice autogen story could be good, but we could also go with a validation step and then add that later on if it's a pain point.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be able to use go generate for this, link.

@connor4312
Copy link
Collaborator

I think this looks good overall, one comment :)

Copy link
Contributor

@jonathanhefner jonathanhefner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@tadasant
Copy link
Contributor Author

Addressed feedback and made some simplifications in 8041f5f. Thanks all for taking a look!

@@ -0,0 +1,306 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MCP Server Detail",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add an $id to this JSON schema, ideally pointing to where the this schema hosted (URL & URI), and maybe including a version, such as the date of release (maybe today). This could be included optionally at publish time for improved error experience (other than complaining of some missing property).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's the intent of this fast follow:

Add a version to the scheme of server.json itself (#139)

},
"source": {
"type": "string",
"enum": [

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a description of what the main public registry will support? Or what any MCP registry can support including private ones? It seems to me like this should just be a string and the set of allowed values is enforced by a specific registry implementation.

Asked another way, do you expect this JSON schema to be used by other deployments or just the main one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. I guess we're going to need two schemas here, similar to how I was thinking we need to separate out the official vs. broader OpenAPI schemas. As-written, this is moreso the public registry one (e.g. constraints like enum on source don't make sense for the generic server.json).

Added ticket: #155

"properties": {
"version": {
"type": "string",
"description": "Server version (equivalent to Implementation.version in MCP spec)",
Copy link

@joelverhagen joelverhagen Jun 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to be a SemVer style version? Or is it any versioning scheme? Based on the implementation today appears to be lex order compared to determine latest.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably SemVer but I haven't thought deeply on the options and nuances here

Add a version to the scheme of server.json itself (#139)

If you have strong opinions and are willing to make a PR laying out the pro's/con's, would love for you to take that pending followup to this PR :) Seemed like @jonathanhefner probably has an opinion here too. This decision likely has much wider implications than just registry so we should probably carve it out to a separate issue and be thorough with it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, from the end user's perspective, I think it would be preferable to allow any format. I think the core issue is how the registry tracks version history.

The FAQ says version numbers should be "bumped" or "incremented", which, obviously, requires version numbers to have an ordering scheme. However, since the registry only tracks which version is "latest" (i.e. doesn't support branching), we could just base "latest" off of the submission date, and change the version number requirement to "unique" instead of "incremented". But perhaps the intention was to leave the door open to support branching in the future?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tadasant - sorry for two comments on version :D. This thread is talking about the server version scheme, as @jonathanhefner is responding about. I saw this part of the code:

if serverDetail.VersionDetail.Version <= existingEntry.VersionDetail.Version {
return fmt.Errorf("version must be greater than existing version")
}

I am not a Go expert, but this appears to do lex comparison which is pretty strange for a version string. 2.0.0 would be > 10.0.0.

I think it's reasonable to say latest ~= most recent, not "greatest version per some arbitrary versioning scheme". That would be simpler. I like SemVer and prefer it, but do not know the needs of the broader ecosystem here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops sorry I pasted the wrong link in my last comment. Meant to paste

Propose a specific versioning scheme (https://github.com/modelcontextprotocol/registry/pull/134/files#r2145287494)

Regarding the code -- it's all just very POC at the moment. These docs are the stronger source of truth (and we'll eventually bring the implementation to align).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants