-
Notifications
You must be signed in to change notification settings - Fork 835
[RFC] Namespaces #334
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
[RFC] Namespaces #334
Conversation
Went through the doc — I think namespacing is a great idea! I'd love to see what a namespaced tool list looks like in terms of a JSON-RPC payload. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Namespacing has to be addressed and this looks like a reasonable apprach.
Absolutely - if folks like this proposal I'll get the namespaces/list dance put together |
One comment from another thread is to allow "." (periods) in the namespace name to allow for domain names. |
Yes, this. In the Registry working group, we've been discussing reverse domain namespacing with domain ownership verification as a way of making certain that the owner of the domain is the only entity who can register their server. So the official GitHub MCP server would be registered into the "com.github" namespace. It's not concrete yet, but the tool namespacing should line up with whatever approach is adopted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do agree with the concept of namespacing needing to exist at some level.
I'm not sure I'm convinced it needs to live at the tool/resource/prompt level in the spec. My initial thought would have been we just need namespacing at the server level, and let the clients handle it from there.
There is maybe an argument to be had that different servers should be able to share the same "namespace" if they are implementing the same functionality. @toby has a community working group running exploring this (#tool-interfaces-wg in the CWG Discord). I think we should make sure any namespacing effort is considering that work and how the two efforts relate.
I do think we should land the registry work (with its likely reverse-DNS namespacing approach at the server level) before considering adding any additional notion of namespacing.
@cliffhall I'm not sure if your approval of this PR was in pursuit of actually merging it; in case it was: I think there is a lot to unravel here before we (and more importantly MCP core team) actually push to make it part of the spec, so I'd recommend holding off on that.
## Namespace Prefixing | ||
|
||
### Listing | ||
1. As an optionl capability (for backwards compatibility), the server **MAY** expose a namespace list feature. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optional
This looks like a reasonable convention. I know this RFC deliberately and sensibly sidesteps ownership of the "@" namespace, but there may need to be some connection to the registry on the roadmap, or an alternative "freeform" indicator to prevent clashes. |
@tadasant I actually disagree about registry taking precedence over this - a generic namespace solution should actually be agreed on first that covers things like toolsets (namespace grouping of tools), domain names (registry), proxies, etc. So, I would argue, the worst case scenario here is that the registry working group comes up with something that makes name spacing harder, essentially a tail wagging the dog scenario. Put another way, I would imagine a registry or proxy use case to be implemented in a namespace friendly way - so, if you want to limit your use of a registry to a single downstream service, the way I’ve outlined namespacing would allow that, rather than building an over the top filter parameter for a registry where you only want to address a single upstream server. Does that sort of make sense? I’m not saying what I’ve proposed is necessarily the best way to do this, but I actually think it’s more important to agree on namespacing before a lot of registry and proxy use cases come together. |
Ya, I was worried a bit about collisions with current tool names, and I wanted this to be as backwards compatible as possible. Maybe we do something like if you support the namespace capability, you’re opting in to @ as a reserved character? |
@tadasant I would be curious how you’d think about this at the server level but NOT the feature level, would certainly be open to an even more light touch implementation, this is meant to be very light touch |
Regarding the proposal for namespaces, I have a few questions: Namespace vs Multiple MCP Server How should one decide whether to divide an MCP Server into multiple namespaces or to develop the same number of separate MCP Servers?
Compatibility and Parameter Passing The tool list in an MCP Server is ultimately passed to the LLM via the tools parameter in the LLM interface.
However, other members of the community have mentioned the desire to filter the tool list on the client side, providing only the truly necessary tools to the LLM, in order to improve the accuracy of the LLM's tool selection. If there is namespace capability, the client might be able to configure to expose only the tools under a specific namespace to the LLM? |
I think this is 100% up to the implementor - if you're just building a smaller server, you'd just have tools available to be invoked, and you'd probably just totally disable namespacing. If you're building an enterprise proxy and expect to have 1,000 tools, you'd definitely want to have namespaces enabled.
This is baked into the spec - tool_a would be named @namespace1/tool_a, so the tool name itself is guaranteed to be unique (event if you had a tool_a in namespace2) and totally backwards compatible (every client today can invoke a tool with a name like @namespace2/tool1). Thanks for the thoughtful questions! |
Sure. I took it as hot since it wasn't a draft. |
I'm absolutely in favor of some sort of Namespacing convention as well, but somewhat ambivalent on trying to force it into current tool names (even though this is the pattern seen most frequently across multiple mcp-gateway implementations). Some thoughts:
|
I always worry about backwards compatibility haha - especially with a spec that's just gaining tracking
Ya, this feature of things is 100% to avoid adding a namespace field - you get free collision avoidance without clients having to start looking at a separate property on the tool list. But, if folks like it, I'm open!
I think of the name as generally opaque-ish to the llm compared to the description, but interesting point
Ya no strong opinion here, I think the best way to do this is if you opt in to namespaces you are opting in to @ being reserved, but no strong opinion |
Spec changes must be accepted by core
Hey @darrelmiller - thanks so much for chiming in, great thoughts. @dsp-ant and I actually spoke for a few minutes at the MCP Dev Summit about this very topic. I'd love to hear your feedback on how, a few years out, you like / dislike tags in OpenAPI, could really help shape this conversation. From my perspective - this proposal ISN'T about solving scenarios or "interfaces" (which is what a different proposal floating around calls it) - this is about server side name collisions and broad strokes grouping functionality. Put another way, the MCP server really nudges you toward smaller servers at the protocol level - I'd say this because the only way to enumerate tools or resources, at the protocol level, is pagination. There's a limit to how much you can paginate on standup of a client, which you'll need to do every time you standup unless we specify a better way to do change capture of tools and resources. So, that limit might be 1k, 10k, 100k, whatever, but it basically is a protocol level limitation to the number of tools and resources on a server. This proposal, along with #322 about search, is a couple of small-ish, opt-in changes which allow you to either group your server effectively along namespace (you could imagine this lining up with departments at large enterprises) so they can be effectively paginated, or to leave everything in a large list, but allow searching so you're never trying to paginate everything. To that extent, while I think labels / scenarios are a cool idea, in the enterprise department use case, you're going to have a TON of naming collisions, so creating a structure that prevents naming collisions across namespace is a big plus of this proposal. If we could get into a bit more theoretical CS here - I actually think of namespacing as a mechanism not just to help with scale, but to generally help with composing mcp servers. We're already seeing some really cool use cases where someone has google mail and google calendar both setup - those are going to expose a handful of colliding tool names (get_me, etc) - so, if you want to have an MCP server that composes two or three upstream servers (this was the OpenAI talk at the Dev Summit, which was SUPER interesting), you're going to run into these problems immediately. So, you have huge enterprise servers, you have small servers where you compose tools - the nature of tools not having a baked in path basically just means you are guaranteed to have name collisions pretty quickly, and that's where this proposal is coming from. I'll add - the reason I bring up OpenAPI tags is that is sort of how david suggested we change this up above - to have a property on tools which is the namespace (very similar to the tag property on paths in OpenAPI). The ONE difference, which is really critical, is that paths solve for naming collisions in OpenAPI, so tags have a guarantee of no possibility of a name collision. So, in some ways, what I'm proposing would be more like what you have to do in the OpenAPI world at the proxy level. When you proxy to multiple upstream OpenAPI server, you inject a path component to ensure no path collisions. |
|
||
## Overview | ||
|
||
Namespacing functionality is implemented through a simple, single depth hierarchy, `@weather`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
semantic nit: "single depth hierarchy, e.g. @weather
", or maybe "single depth hierarchy, such as @weather
"
Just to avoid the ambiguity potentially implying that @weather
itself is a spec thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya good call, fixing in push I'm about to push
### Tool, Resource, and Prompt Names | ||
As part of being in a namespace, a tool name, resource name, or prompt name **MUST** begin with the namespace | ||
`@weather/get_weather_forecast_by_location`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two things:
- Ambiguity in phrasing as noted before -
@weather/get_weather_forecast_by_location
is just an example here but is phrased as if it's a thing unto itself. Not going to add this comment everywhere, but I also see this done further down in this page. - Is this implying that namespaces would become part of the tool/resource/prompt name itself? As in, calling the non-namespaced list operation would return namespaces, and using namespaced things requires passing that namespace as part of the name? I think that's the right approach, but I wanted to confirm that since it wasn't 100% clear here. I also think it'd be helpful to include a one-liner addition to the tool/resource/prompt spec pages mentioning namespaces to match this, with an example for each.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense for the namespace to be required if a tool is part of a namespace. This works quite well in other systems, like npm where @modelcontextprotocol/inspector
is not confused with inspector
- two completely different and unrelated packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Good call out, I'll clean that up
- YES, @weather/tools/list is a SEPARATE invocation that tools/list, tools/list is essentially querying some sort of default namespace. I'm open to changes around this, this was really just a strawman to get the debate going
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also could clarify that tools/list either 500's or returns all tools
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think tools/list
should still work (otherwise it's only technically backwards-compatible), but my question was just if tools/list
would still include the namespaces or not - and if tools/call
would also require the namespace as given by tools/list
in that scenario.
@<namespace>/tools/list
being separate makes sense - I think the existing tools/list
should return all namespaces, since it means existing clients will work without changes even if servers adopt namespaces first, and clients can incrementally adopt support for namespace-related optimizations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like there is a "levels" muddling going on here.
In the opening post of this PR, namespaces is outlined as a feature to prevent name collisions between servers that may be providing tools to a single LLM context:
This implementation takes guidance from the NPM / Github model of a single, @ denoted hierarchy (https://github.com/weather). This proposal introduces namespaces as part of names (tools, prompts, etc), so a tool can have a name like @weather/get_weather. This deals with the tricky problem of handling backwards compatible naming collisions.
This 100% makes sense. @weather/get_weather
and @weather_channel/get_weather
could potentially collide in the same context and this fixes that. The namespace @weather_channel
here is akin to a unique server name. But there's nothing to keep J. Random Hacker from naming their server @weather_channel
and still arriving at a collision, so there's that.
Let's assume for a moment that we aren't using namespaces to differentiate servers, since agents have other ways to do that, such as prepending the server name, FQDN of the server owner, or even a random string assigned to each server. So, I have server_x
and server_y
, and they both have do_thing
tools. A call to server_x/do_thing
will not collide with server_y/do_thing
.
However within a single server there is no reason why the developer could not make all tool names be unique. The usefulness of namespaces within a given server would be chiefly as a grouping mechanism for narrowing the entire tool list to a subset for presentation to the LLM.
If I ask the @github.com
server for all namespaces and it gives me @repository
, @pulls
, @actions
, and so on, then the agent could reasonably pick between them to find the tool that will help with the current need.
If the agent needs to do a repository-related tool call, getting a list of the tools in the @repository
namespace might return create_repository
, fork_repository
, etc., and from there they could call @github.com/fork_repository
rather than @github.com/@repository/fork_repository
, because all the tools within the server would be uniquely named. @repository
was just a way of grouping a subset, not of identifying a tool at invocation time.
Tool names usually point to functions, which must be uniquely named anyway, so why would they NOT be unique? If the server name / identifier is prepended when presenting it to the LLM to prevent collision with tools in other servers, then within a server, it would be onerous to have to call the tool with the grouping name. It just adds extra tokens to every call, providing no benefit other than allowing non-unique tool names in the server.
Your idea of namespaces being able to share tools so that several namespaces within the server point to the same tool, makes sense. But I don't know a good reason to make tool names NOT be unique across the server, and that complicates things.
It means that a server implementation that uses namespaces can't just use it as a way of narrowing the larger list, but must find a way to allow multiple tools to be named the same thing. You can't do that right now. The SDKs and frameworks must not only support a way of managing lists of tools, but also the way they write tools must be different from other server implementations, to allow non-unique tool names. So namespaces aren't a nice thing you can layer on when your tool list becomes too large, it means refactoring to a different way of creating the tools themselves.
I think this additional complication will greatly impede the adoption of namespaces, which if only used for grouping and narrowing the list, could be a great feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cliffhall been busy, just getting a chance to respond here:
In the opening post of this PR, namespaces is outlined as a feature to prevent name collisions between servers that may be providing tools to a single LLM context:
From the PR Intro:
As MCP servers grow in complexity and number of tools, resources, and prompts, how best to scale a server has become an interesting question. Because of the way LLM context works and is charged, as MCP server size grows, being able to effectively get a constrained and useable set of tools into context can be more difficult. To that extent, the protocol itself it naturally nudging developers to smaller, more feature constrained servers. In the long term, this is a bit of a micro vs macro service debate - no "right" answer, really just developer and architect preference.
So, the intention of this proposal is specifically around how to scale a single MCP server by adding a mechanism for partitioning to which support two distinct, but important notions:
- Preventing tool and prompt name collisions
- Grouping tools, resources, and prompt into targeted collections for better tool / resource selection by LLMs
Now, the fact that we're also getting this benefit of naming collisions across servers you've connected to is really really clever, I hadn't though about that!
Tool names usually point to functions, which must be uniquely named anyway, so why would they NOT be unique? If the server name / identifier is prepended when presenting it to the LLM to prevent collision with tools in other servers, then within a server, it would be onerous to have to call the tool with the grouping name. It just adds extra tokens to every call, providing no benefit other than allowing non-unique tool names in the server.
Ya, I don't honestly have a strong opinion about this, I'll go back to the example of a large company like salesforce or microsoft wanting to expose a single MCP server for their full API rather than thousands of small servers (to put this in perspective, Office Graph is the REST endpoint into office and has 26,000 endpoints!)
So, in that example, it would be much nicer to have some sort of grouping hierarchy on the server itself that makes the names unique. There's an added benefit here I just thought of - I've noticed a lot of servers actually reference other tools by name. In the large server / aggregation scenario, once you're working within a namespace, you actually have a consistency issue between natural language descriptions and tool names if the server has to do a tool renaming to avoid a name collision. So, I would posit as an axiom, in an aggregation / proxy situation, the server must NEVER change the tool name, because that could break references within natural language description
Great feedback all around!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tool names usually point to functions, which must be uniquely named anyway, so why would they NOT be unique? If the server name / identifier is prepended when presenting it to the LLM to prevent collision with tools in other servers, then within a server, it would be onerous to have to call the tool with the grouping name. It just adds extra tokens to every call, providing no benefit other than allowing non-unique tool names in the server.
Ya, I don't honestly have a strong opinion about this, I'll go back to the example of a large company like salesforce or microsoft wanting to expose a single MCP server for their full API rather than thousands of small servers (to put this in perspective, Office Graph is the REST endpoint into office and has 26,000 endpoints!)
An MCP server with 26,000 tools would be insane, but I'm sure someone out there would respond "hold my beer." In such cases I would expect that they already have some grouping that they could apply to the names to make them unique. I wouldn't want the outliers to dictate a cumbersome requirement like "when calling a tool grouped in a namespace, you have to use the namespace and the tool name" to the quotidian servers with 20 or 100 tools.
It actually requires changing the spec for tool names which currently says:
A tool definition includes:
name
: Unique identifier for the tool
...
I don't think there's actually a name collision problem to solve within a server. Within a server, the namespaces promise a powerful way to narrow the list to something manageable for the LLM. If a server supports namespaces, and the client does as well, I would expect that instead of calling tools/list
they'd call namespaces/list
and then fetch the tools from the namespace(s) that seem appropriate, yielding a list of tool names which are then called as per usual.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well if you look at how this is written, it just includes the namespace in the tool name, so it’s totally backwards compatible and protects against name collisions. So, this is as opposed to having namespace be a separate field. But I think we need to solve for this use case, see my comment about the danger of servers changing tool names
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also @cliffhall - this is a totally opt in feature, so smaller servers will stick with no extra tokens, and larger servers would be adding extra tokens for collision prevention anyway
Server-->>Client: Resource Template list | ||
``` | ||
|
||
## Implementation Considerations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should add a brief note on the possibility of namespace conflicts across different connected servers, from a client application or proxy standpoint. Essentially just something to mirror #701, acknowledging that namespaces aren't necessarily be globally-unique. I think we don't need suggestions on how exactly to handle that in the spec, but it's useful to note that it is something to handle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya, thinking through my comment above to cliff, I think it's reasonable to codify that clients can rename namespaces to avoid collisions, but should never rename tools (since that might break different flows)
Should we have |
I think we need it, yes. Because, one of the main uses cases I've come around to thinking about for namespaces is composed hubs of tools, so essentially it's like a mini mcp server, so ya, you'd definitely want it. |
Hi, I added a few steering committee meeting notes to this related discussion: #94 (comment) Topics included other ideas for namespacing/avoiding collisions, plus consensus around namespacing as a documented best practice vs being a mandatory protocol requirement. |
@olaservo I responded in your comment, but worth bringing up here, if you go through the discussion on this PR, a big part of this is scalability of servers, and I guess related, grokability by agents. Just doing namespaces as "guidance" doesn't really help with either of those issues, it just deals with the proxying issue. But, dealing with the proxying issue without dealing with what to do when you get to 100, 200, 300 tools is ignoring a really critical part of proxying. |
@cliffhall @olaservo Is there a world where it would be interesting to get on a call to discuss the scalability vs. naming vs. no-protocol changes concerns here? |
@patwhite I think that's a good point and I mixed these two topics a little too ambiguously when sharing those notes. Since your proposal relates to solving multiple problems, I don't want to confuse things or imply short circuiting any PR discussions. :) Plus I still think its still worth extracting what the community can proactively publish as guidance while these spec solution proposals are being discussed, similar to what Luca opened here
I don't think I'm the best person to represent here since my main goal on this topic is surfacing what might not be totally visible at a community level, but lets talk more on the CWG discord. |
Okay coming back to this. It's been a lengthy discussion. At the last MCP developer summit we brought up the idea of introducing a difference between a tool name and a human readable display name for a tool. This means that it would now be possible to use for example a uri schema for tools or resources such as If we still feel this is valuable, then we should. create a Specification Enhancement Proposal for this and discuss it with @modelcontextprotocol/core-maintainers for a vote. I am incredible sorry for what is a lengthy process but this is a tricky one. @patwhite let me know how you want to proceed, and feel free to ping me in the CWG discord. |
@cliffhall maybe you'd be willing to sponsor? Thanks! |
@patwhite I'd love to. This is a feature I'm excited about and I want to see it move forward.
@dsp-ant do we have an alternative SEP in play or is that still just an idea floating around? I wasn't at the summit, so I wasn't aware of it at all. I would like to understand that alternative before we put more work into the namespaces so that we're not working at cross-purposes. I still think this is important, because it doesn't just give us a way to append a namespace to a tool name, but also to fetch just the tools in the relevant namespaces, in order to reduce tool overload in the LLM context. |
Happy to bring that into this if there isn't, it's very related! |
Moving discussion to SEP-993 |
I'd like to add a few cents on this discusstion.
|
EDITED 5/12/2025
Motivation and Context
As MCP servers grow in complexity and number of tools, resources, and prompts, how best to scale a server has become an interesting question. Because of the way LLM context works and is charged, as MCP server size grows, being able to effectively get a constrained and useable set of tools into context can be more difficult. To that extent, the protocol itself it naturally nudging developers to smaller, more feature constrained servers. In the long term, this is a bit of a micro vs macro service debate - no "right" answer, really just developer and architect preference.
This proposal seeks to introduce a native grouping mechanism (namespaces) which carry their own metadata and natural language description, and can be used to limit the capabilities that need to be added to model context during MCP use.
Along with #322, this is an attempt to update the protocol to no longer take a protocol level stance regarding server size - MCP will be able to support small domain specific servers or large, multi-department, cross functional servers.
This implementation takes guidance from the NPM / Github model of a single, @ denoted hierarchy (@weather). This proposal introduces namespaces as part of names (tools, prompts, etc), so a tool can have a name like @weather/get_weather. This deals with the tricky problem of handling backwards compatible naming collisions.
This is an OPTIONAL capability, small servers have no reason to implement this.
How Has This Been Tested?
Implemented experimentally in Scaled MCP
Breaking Changes
Fully backwards compatible
Types of changes
Checklist
Additional context
Other options that were considered included doing namespaces as a property on a tool, and that's still very much in the discussion! This proposal was slightly more backwards compatible, but I'm open to really any mechanism here.