Repository navigation
Conversation
Add the draft SEP for the io.modelcontextprotocol/groups extension (progressive disclosure via activatable groups) and link it from the documentation table.
OR13
left a comment
There was a problem hiding this comment.
Isn't this challenge solved by agents and teams today?
So you don't progressively keep adding skills to the same agent, but instead, when you start hitting the limits of what separates a "specialist" from a "generalist", you make specialist teams, and make the generalist aware of how to invoke them?
Does this proposal align with giving specialist agents groups?
I guess my question is really, is there any aspect of this that interacts with agents or skills over mcp, seems like those paths could also address some of this.
|
I think this is a great start. Some quick questions I think we should make sure are discussed or covered more clearly: Design questions
Protocol correctness
Naming and API semantics
|
|
I've been working on the problem this proposal describes from a different direction, and I think it's a useful data point. ai-vision exposes an app's object model to agents as a tree. The agent navigates it by path, like It is "nested groups" taken to the extreme, with its own trade-offs. I wrote it up here, with a recorded agent session: Smaller models handle it too. Here Claude Haiku 5.5 and GPT-6 Luna play chess against each other through Persephone's object model: I'm also interested in a standard along these lines for the web. Persephone's built-in browser already mounts a page's WebMCP tools into its object model under that page, I'm happy to share more details. |
These are orthogonal. I'd consider agents/teams host-side orchestration — splitting work across agents and routing between them — whereas Groups is a server-side protocol mechanism: how one server discloses its own capabilities over a single connection. They operate at different layers and compose rather than compete.
TL;DR they're complementary: skills disclose instructions and files, groups disclose the typed, invokable tools those instructions drive. A skill can name a tool but can't carry its schema or make it callable; groups fills exactly that gap. Here's the more detailed explanation of how the two connect, both using existing surface:
|
Replied in #19 (comment) but at the same time I will bring the following open question for discussion in WG: do we need a skill-specific identifier in the groups primitive as a way for a group to explicitly declare "this resource is the skill I implement". Or do we leave it as an ordinary resource the host recognizes via the skills extension itself? Adding a marker makes the link explicit but introduces a dependency between the two optional extensions and the complexity that comes with it. I'd lean toward not adding one for now, but worth discussing.
I am leaning towards to weaken the claim on "returns the same result" --
Will do a bike shedding discussion for naming:
|
|
Data point: two ways of shrinking a catalog without Groups, and what they didn't fix I maintain mcp-ticket-demo and a few other MCP servers (portfolio). I presented this at MCP Dev Summit Toronto (session 1282401). This isn't a competing proposal. It's what we shipped before Groups existed, and where it fell short of what this draft is trying to do. The problem we hit: near-duplicate tools. Every name was accurate, and the model still picked the wrong one. Two different collapses:
Results relevant to this draft:
A grouping axis that falls out of this: by kind of operation, like SQL.
The draft already lets Not measured: selection accuracy before and after either collapse. "The model stopped picking wrong" is an operator observation, not a benchmark. Hints are also only as good as the server: we shipped If it would help, I can run two things next to this draft on mcp-ticket-demo: Questions:
|
Thanks! this data points are very helpful! Q1: On collapsing near-duplicate tools before grouping -- I take this as orthogonal. The SEP's positioning on grouping is about what shows up in */list versus what the client fetches on demand. Q2: OA group can be a workflow, a plain toolset, a knowledge bundle, or the operation/scope split you described. The thing I would like to highlight is that a group isn't an access boundary. The server still checks scope on every call, so grouping by scope helps discovery but doesn't enforce anything on access boundary. Q3: yes, will update the draft to reflect this. Same idea as tools/list and your describe_server: a client should be able to see what's there and work out what it needs to authenticate for. What comes back still depends on the caller's view, and leaving a group off the list is about discovery, not access. Also I will try to include some sample prototypes and it would be great to see how groups can help address the issues you have described. |
Change-notification rationale now points to SEP-3371 as the reason push notification should not extend the core subscriptions/listen filter.
|
Thanks @helloeve — the answers help, and thanks for taking the unauthenticated Treating tool collapse and groups as orthogonal matches what we saw: collapsing near-duplicate tools made selection clearer, and it did not shrink Once a sample prototype is up, I’m happy to try it against mcp-ticket-demo and report how a scope split (read / write / admin) behaves, including the case where a group is hidden from |
|
Follow-up on the two measurements I offered. Local prototype of this extension, one server, 19 tools, 5 groups. Still a data point, not a change to the draft. Tokens. tiktoken o200k_base on the compact JSON of the result, not a provider tool prompt. A read that loads the top-level tools, groups/list, and one groups/get was 2,388 tokens, 23% of the flat tools/list (10,398). The groups envelope added 58 tokens. Fetching every group was 10,948, about 5% more than the flat list. The saving is stopping after the one group the task needs. Does the model call groups/get? Local 8B and 14B only, 14 tasks, 5 seeds, temperature 0.2. No frontier model. While a catalog call still listed every tool name, group picks were 0. Both models called the tool. After that call listed only the top-level tools and pointed at groups/get, the 14B model took the group path on 65 of 70 trials and the 8B on 47 of 70. With every schema visible, selection was already 70 of 70 and 68 of 70. Groups keep unread schemas out of context. They do not beat a flat list the model can already read. Anything the model reads before groups/get should not name a scoped tool, and the group sentence has to be the only place those task words appear. A scope that lives only in _meta was ignored. Leaving a group out of groups/list did not block tools/call. On the three questions: collapse and groups do different jobs, and groups do nothing if an earlier call still lists every tool. Grouping by operation worked when the group sentence carried the task. The same constraint applies to a workflow group. groups/list answered with no credential. Turning groups off should restore the full catalog. An empty group list leaves a client that already negotiated with only the top-level tools. |
Adds the draft SEP for the io.modelcontextprotocol/groups extension (and links it from the README contents table).
It defines progressive disclosure of tools and other primitives: a Group is a named, lightweight bundle a server advertises once both sides negotiate the extension, with groups/list keeping listing cheap and groups/get returning a group's scoped tools, prompts, resources, and nested groups as typed, invokable definitions in a single stateless round-trip.
Scoped primitives stay out of tools/list/prompts/list/resources/list so servers can ship rich per-workflow capability without bloating every session, while scoped actions still run through ordinary tools/call (no client filesystem or shell needed).