Skip to content

SEP-2633: Standard Client-Side Configuration Format - mcp.json#2633

Draft
BobDickinson wants to merge 6 commits into
modelcontextprotocol:mainfrom
BobDickinson:sep/standard-client-mcp-json-configuration
Draft

SEP-2633: Standard Client-Side Configuration Format - mcp.json#2633
BobDickinson wants to merge 6 commits into
modelcontextprotocol:mainfrom
BobDickinson:sep/standard-client-mcp-json-configuration

Conversation

@BobDickinson

Copy link
Copy Markdown

The MCP ecosystem has server.json (the MCP Registry package specification), and soon the related ServerCard, for describing how servers can be configured. But there's no standard for the other side: how a client will connect to its servers.

Today every MCP client invents its own format for server configuration. Clients use different file names, and even different file types (JSON, JSONC, and TOML). They use different top-level keys (including "servers" and "mcpServers"). They use different values for the type field. They use different mechanisms and encodings for secret interpolation. The list goes on. This makes it hard to share MCP server configurations across clients.

mcp.json is a proposal for a minimal, client-side configuration format that any MCP client can adopt, and that will provide interoperability of MCP server configurations across clients.

Note: Initial draft is opinionated with many decisions made by the author. These decisions should be considered a starting point for discussion.

@BobDickinson BobDickinson changed the title SEP-0000: Standard Client-Side Configuration Format - mcp.json SEP-2633: Standard Client-Side Configuration Format - mcp.json Apr 22, 2026
@BobDickinson BobDickinson marked this pull request as draft April 22, 2026 21:48
@BobDickinson BobDickinson requested a review from tadasant April 22, 2026 21:59

@tadasant tadasant left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

High level thought: we should probably propose this as an Extension instead of straight to core (that is likely the direction Server Card is going as well).


## Abstract

The MCP ecosystem has server.json (the MCP Registry package specification), and soon the related ServerCard, for describing how servers can be configured. But there's no standard for the other side: how a client will connect to its servers.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
The MCP ecosystem has server.json (the MCP Registry package specification), and soon the related ServerCard, for describing how servers can be configured. But there's no standard for the other side: how a client will connect to its servers.
The MCP ecosystem has [server.json](https://github.com/modelcontextprotocol/registry/blob/main/docs/reference/server-json/generic-server-json.md) (the MCP Registry package specification), and soon the related [Server Card](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2127), for describing how servers can be configured. But there's no standard for the other side: how a client will connect to its servers.


```json
{
"mcpServers": {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we definitely want/need to define mcpServers like this?

Could we potentially scope this spec down to be "the object you put inside mcpServers"; implying the choice of e.g. mcpServers vs. servers is up to the client?

Maybe that's confusing, because then we're not really replacing what is commonly today called the .mcp.json file, we're more just replacing the object in the mcpServers field... but that also seems potentially cleaner, in that we're not trying to wholesale replace that whole file (what with e.g. VS Code's management of inputs, etc).

And maybe the design goal here is to define the whole file, so you can copy/paste the whole thing... probably don't feel strongly on this, but what do you think?

}
```

Server names must match `^[a-zA-Z0-9_\[\]-]+$` (alphanumeric, hyphens, underscores, brackets).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should probably allow for name as defined in server.json, i.e. allow . and / as part of DNS prefixing. But of course this is a "localized" name that doesn't have to align with name.

}
```

#### streamable-http — HTTP Streaming

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
#### streamable-http — HTTP Streaming
#### streamable-http — Streamable HTTP


#### streamable-http — HTTP Streaming

For remote servers using HTTP streaming:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
For remote servers using HTTP streaming:
For remote servers using streamable HTTP:

Comment thread seps/2633-standard-client-mcp-json-configuration.md Outdated

| Scheme | Description | Example |
| ------- | --------------- | ----------------------------- |
| `env` | Environment var | `env:ENV_VAR_NAME` |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we still allow for the absence of a scheme to imply env, as is probably convention out there right now, or do you think that's a bad idea for some reason?

Comment thread seps/2633-standard-client-mcp-json-configuration.md
Comment thread seps/2633-standard-client-mcp-json-configuration.md

| Scheme | Description | Example |
| ------- | --------------- | ----------------------------- |
| `env` | Environment var | `env:ENV_VAR_NAME` |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Perhaps ironic given my ask about making this a default: but should we explicitly discourage usage of environment variables as secrets? Typical ways people inject environment variables (i.e. storing in a file and sourcing them) seems to be the pattern by which rogue agents can pick up tokens and make API calls they're not meant to have access to. And thus encouraging clients to support schemes like op might meaningfully nudge along MCP security posture.

Co-authored-by: Tadas Antanavicius <tadas@tadasant.com>
@tobinsouth

Copy link
Copy Markdown

looking at some real world use cases, I think the oauth object is a couple of fields short of being able to describe lots of real OAuth servers we see in the wild. three fields (clientId, scopes, redirectUri) covers the happy path — DCR + PKCE + working RFC 8414 discovery — but falls over on confidential clients, CIMD, broken discovery, and "register your own client."

I've written up the publisher-side half of this as a separate SEP — SEP-2742 (the menu shape that a Server Card / server.json would carry, what auth methods does a server support). Trying to keep the layering clean: server.json = the menu, mcp.json = the choice. The two PRs are meant to be read together.

The short version of what I think is missing here:

  1. Confidential clients — there's no field for a client secret, private key, or mTLS cert. Server requires client_secret / private_key_jwt / tls_client_auth? Can't be configured. I'm pretty sure we support this in ext-auth.
  2. CIMD — a clientId that's an https:// URL is ambiguous. Is it a Client ID Metadata Document or just a static ID that looks like a URL? The connect behavior is totally different and you can't tell from the JSON.
  3. Broken discovery — the spec assumes .well-known/oauth-authorization-server works. A surprising number of real ASes don't publish it (Snowflake's Custom OAuth being a well-documented one). No escape hatch.
  4. Auth posture — can't tell whether the server wants auth before initialize, accepts anon and 401s lazily (e.g., partial auth), or doesn't care.
  5. $schema — no version field. Cheap to add now, very annoying to retrofit.
  6. The serverCard ref open question — already flagged in the SEP, and I think it's the load-bearing one. Got a concrete proposal — happy to sketch it inline or in a follow-up.

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.

3 participants