From 493cf01179c860b599f56625d76f9a63e160d198 Mon Sep 17 00:00:00 2001 From: Tapan Chugh Date: Wed, 25 Feb 2026 15:00:39 -0800 Subject: [PATCH 1/6] Add grouping extension specification and license --- LICENSE | 190 ++++++++++++++++ specification/draft/grouping.mdx | 368 +++++++++++++++++++++++++++++++ 2 files changed, 558 insertions(+) create mode 100644 LICENSE create mode 100644 specification/draft/grouping.mdx diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d47c0ca --- /dev/null +++ b/LICENSE @@ -0,0 +1,190 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to the Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by the Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding any notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2025 Model Context Protocol + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/specification/draft/grouping.mdx b/specification/draft/grouping.mdx new file mode 100644 index 0000000..2bfd88c --- /dev/null +++ b/specification/draft/grouping.mdx @@ -0,0 +1,368 @@ +--- +title: Grouping Extension +--- + +
+ +**Protocol Revision**: draft + +## Introduction + +### Purpose and Scope + +This extension defines the Grouping capability for the Model Context Protocol, enabling servers to organize tools, prompts, resources, tasks, and other groups into named collections. Groups allow clients to provide richer workflows such as filtering, agentic control, and simplified server instructions. + +This specification covers: + +- The `Group` type definition +- Discovery via the `groups/list` method +- Membership signaling via the reserved `_meta` key `io.modelcontextprotocol/groups` +- Notifications for group list and membership changes +- Nested group semantics + +### Extension Identifier + +The canonical extension identifier is: + +``` +io.modelcontextprotocol/grouping +``` + +### Extension Requirements + +This extension is **OPTIONAL** for MCP implementations. When adopted: + +- Implementations **MUST** conform to all requirements specified in this extension +- Implementations **MUST** also conform to the core MCP specification +- This extension works with all MCP transports + +## Capability Negotiation + +### Server Declaration + +Servers that support groups **MUST** declare support during initialization using the `extensions` field in `ServerCapabilities`: + +```json +{ + "capabilities": { + "extensions": { + "io.modelcontextprotocol/grouping": { + "listChanged": true + } + } + } +} +``` + +The `listChanged` field indicates whether the server supports `notifications/groups/list_changed` notifications. Servers that omit this field or set it to `false` do not send list change notifications. + +### Client Handling + +Clients **SHOULD** check for the `io.modelcontextprotocol/grouping` key in `capabilities.extensions` before issuing `groups/list` requests. Clients that do not recognize the extension **MUST** ignore it — the extension does not alter any core protocol behavior. + +## Group Schema + +A `Group` represents a named collection of MCP primitives. + +### Type Definition + +```typescript +interface Group { + /** + * A unique identifier for the group. Intended for programmatic or logical + * use, but used as a display name as fallback if title is not present. + */ + name: string; + + /** + * Intended for UI and end-user contexts — optimized to be human-readable + * and easily understood. If not provided, clients should use name for display. + */ + title?: string; + + /** + * A human-readable description of the group. + */ + description?: string; + + /** + * Optional set of sized icons that the client can display in a user interface. + * + * Clients that support rendering icons MUST support at least: + * - image/png — PNG images + * - image/jpeg (and image/jpg) — JPEG images + * + * Clients that support rendering icons SHOULD also support: + * - image/svg+xml — SVG images (requires security precautions) + * - image/webp — WebP images + */ + icons?: Icon[]; + + /** + * Optional annotations providing additional group information. + * + * Display name precedence order is: title, annotations.title, then name. + */ + annotations?: Annotations; + + /** + * Optional metadata. May include the reserved key + * "io.modelcontextprotocol/groups" to indicate nested group membership. + */ + _meta?: Record; +} +``` + +### Example: Basic Group + +```json +{ + "name": "user-management", + "title": "User Management Tools", + "description": "Tools used for managing user accounts within the system." +} +``` + +### Example: Group with Icons and Nested Membership + +```json +{ + "name": "email", + "title": "Email Tools", + "description": "Tools for composing and sending emails.", + "icons": [ + { + "src": "https://example.com/email-icon.png", + "mimeType": "image/png", + "sizes": ["48x48"] + } + ], + "_meta": { + "io.modelcontextprotocol/groups": ["productivity"] + } +} +``` + +## Discovery + +### `groups/list` Request + +Clients discover available groups via the `groups/list` method. This method supports cursor-based pagination following the same pattern as other MCP list methods. + +**Request:** + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "groups/list" +} +``` + +With optional cursor for pagination: + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "groups/list", + "params": { + "cursor": "next-page-cursor" + } +} +``` + +### `groups/list` Response + +The response contains an array of `Group` objects and an optional `nextCursor` for pagination: + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "groups": [ + { + "name": "user-management", + "title": "User Management Tools", + "description": "Tools used for managing user accounts." + }, + { + "name": "mapping", + "title": "Geospatial Mapping Tools", + "description": "Tools for map rendering and spatial analysis." + } + ], + "nextCursor": "next-page-cursor" + } +} +``` + +### Type Definitions + +```typescript +interface ListGroupsRequest { + method: "groups/list"; + params?: { + cursor?: string; + _meta?: Record; + }; +} + +interface ListGroupsResult { + groups: Group[]; + nextCursor?: string; + _meta?: Record; +} +``` + +## Membership + +### Reserved `_meta` Key + +Group membership for all primitives (tools, resources, resource templates, prompts, tasks, and groups themselves) is expressed via a reserved `_meta` key: + +``` +io.modelcontextprotocol/groups +``` + +The value is an array of group `name` strings identifying which groups a primitive belongs to. + +### Example: Tool with Group Membership + +A tool listed in the `tools/list` response indicating membership in the `arithmetic` group: + +```json +{ + "name": "calculator", + "title": "Arithmetic Calculator", + "description": "Perform mathematical calculations on arithmetic expressions", + "inputSchema": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "Expression to evaluate (e.g., '2 + 3 * 4')" + } + }, + "required": ["expression"] + }, + "_meta": { + "io.modelcontextprotocol/groups": ["arithmetic"] + } +} +``` + +### Membership Constraints + +1. Primitives **MAY** belong to multiple groups. For example, a `spell_check` tool might appear in both `compose_email` and `compose_document` groups. +2. Primitives **MAY** belong to zero groups. The `io.modelcontextprotocol/groups` key is optional; its absence means the primitive is ungrouped. +3. Clients **MUST** treat group names as opaque identifiers and resolve them against the `groups/list` result. + +### Backward Compatibility + +By using a `_meta` key for membership, this extension ensures backward compatibility. Older clients that do not recognize the `io.modelcontextprotocol/groups` key will simply ignore it — the core primitive data remains unchanged. + +## Notifications + +### Group List Changed + +When the list of available groups changes, servers that declared `listChanged: true` in the capability **SHOULD** send: + +```json +{ + "jsonrpc": "2.0", + "method": "notifications/groups/list_changed" +} +``` + +Upon receiving this notification, clients **SHOULD** re-issue a `groups/list` request to get the updated list. + +### Membership Changed + +If a primitive is added to or removed from a group, the server **SHOULD** send the appropriate list changed notification for that primitive type. For example: + +- If a tool's group membership changes → `notifications/tools/list_changed` +- If a resource's group membership changes → `notifications/resources/list_changed` +- If a group's group membership changes → `notifications/groups/list_changed` + +This reuses existing MCP notification mechanisms and requires no new notification types for membership changes. + +### Type Definition + +```typescript +interface GroupListChangedNotification { + method: "notifications/groups/list_changed"; + params?: Record; +} +``` + +## Nested Groups + +### Groups Belonging to Groups + +Groups **MAY** belong to other groups using the same `_meta` key mechanism. This enables organizing groups into larger categories without introducing a separate hierarchy mechanism. + +### Example + +A server provides three groups: `email`, `calendar`, and `productivity`. The `email` and `calendar` groups belong to `productivity`: + +```json +[ + { + "name": "productivity", + "title": "Productivity Suite", + "description": "All productivity-related tools." + }, + { + "name": "email", + "title": "Email Tools", + "description": "Tools for composing and sending emails.", + "_meta": { + "io.modelcontextprotocol/groups": ["productivity"] + } + }, + { + "name": "calendar", + "title": "Calendar Tools", + "description": "Tools for scheduling and calendar management.", + "_meta": { + "io.modelcontextprotocol/groups": ["productivity"] + } + } +] +``` + +### Transitivity + +Clients **MAY** interpret transitive relationships based on their specific use cases. For example, a client might show all tools in `email` and `calendar` when the user selects the `productivity` group. Other clients might show only direct members. + +This specification does not mandate a particular traversal strategy — clients are free to choose the behavior that best fits their UX. + +### Constraints + +- Servers **MUST NOT** create self-referential groups (a group belonging to itself). +- Servers **MUST NOT** create cyclic membership (e.g., group A belongs to group B, and group B belongs to group A). +- Servers are responsible for ensuring valid group structures. SDKs **MAY** provide validation helpers. + +## Graceful Degradation + +### Server Without Extension + +If a server does not declare `io.modelcontextprotocol/grouping` in `capabilities.extensions`, clients **MUST NOT** send `groups/list` requests. Primitives returned by the server will not contain the `io.modelcontextprotocol/groups` `_meta` key. + +### Client Without Extension Support + +If a client does not support this extension, the server's group declarations are simply ignored. The `_meta` key on primitives is opaque metadata that non-supporting clients will skip. All core MCP functionality remains unaffected. + +### Partial Support + +A server **MAY** support groups for only a subset of its primitives. For example, a server might group its tools but not its resources. Clients **SHOULD** handle the case where some primitives in a `groups/list` result have no corresponding members. + +## Security Considerations + +This extension does not introduce new security implications beyond those already present in the core MCP specification. Specifically: + +- Group information exposed to LLMs presents challenges similar to other primitive metadata. Servers **SHOULD** avoid including sensitive information in group names, titles, or descriptions. +- If servers use groups for access control purposes, the access control logic **MUST** be enforced server-side. Clients **MUST NOT** rely on group membership as a security boundary. +- Groups do not grant any additional capabilities — they are purely organizational metadata. From 03d246f532500cc4599670a07463b296f248166a Mon Sep 17 00:00:00 2001 From: Tapan Chugh Date: Mon, 2 Mar 2026 13:04:32 -0800 Subject: [PATCH 2/6] Update IG charter, add organization approaches, and align grouping spec with SEP-2084 - README: Add Discord link, expand problem statement with scope boundaries, add Goals, Organization Strategies, and IG Principles sections - docs/approaches.md: Populate with four organization strategies (Primitive Grouping, Tool Fusion, Tool Search, Code Mode) with examples, references, and linked GitHub Discussions - specification/draft/grouping.mdx: Align with SEP-2084 text while keeping extension framing (capabilities.extensions instead of capabilities.groups) Co-Authored-By: Claude Opus 4.6 --- README.md | 32 +++- docs/approaches.md | 57 +++++- specification/draft/grouping.mdx | 314 ++++++++----------------------- 3 files changed, 159 insertions(+), 244 deletions(-) diff --git a/README.md b/README.md index 2b30d75..3e1703e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # Primitive Grouping Interest Group +MCP Contributor Discord Channel: [#primitive-grouping-ig](https://discord.com/channels/1358869848138059966/1425903819186770064) +More info on how to join the Discord server [here](https://modelcontextprotocol.io/community/communication#discord) + > ⚠️ **Experimental** — This repository is an incubation space for the Primitive Grouping Interest Group. Contents are exploratory and do not represent official MCP specifications or recommendations. ## Mission @@ -21,14 +24,37 @@ This Interest Group explores how MCP Primitives (Tools, Resources, Prompts, Task ## Problem Statement -Flat lists of MCP primitives can be long and cumbersome to work with. +Flat lists of MCP primitives can be long and cumbersome to work with for several reasons. Many such problems are within the scope of this group, but some are not. + +**Within Scope** - **Context overload** — When loaded into the context of an LLM, a primitive list can overwhelm the model and lead to confusion and poor selection -- **Costly operation** - Long lists can consume many tokens, leading to higher costs for users. -- **Poor developer experience** — Lack of organizational tools for primitives makes them harder to manage and maintain +- **Inefficient operations** — Long lists in the context consume many tokens which increases processing cost and response latency. +- **Poor developer experience** — Lack of organizational tools for primitives makes them harder to manage and maintain. + +**Beyond Scope** + +- **Organization for Security** — Organizing and disclosing primitives to clients based on their privilege level is an important problem but beyond this group's mandate. +- **Organizing MCP Servers** — MCP registry and MCP-and-Skills groups are evaluating how different servers should be organized to improve client experience. See the [Problem Statement](docs/problem-statement.md) for full details. +## Goals + +1. **Documenting Requirements and Experiences** — The goal of this group is to document diverse requirements for different clients, servers, and gateways that implement these extensions. We will **not** try to find consensus early on, but aim to document the trade-offs based on feedback from real-world experience. +2. **Reference Extensions** — While many possible organization mechanisms are emerging—and it might be too early to select "one" canonical pattern—different servers are implementing similar features, but the lack of standardization limits clients capability to leverage them effectively. This group will support reference extensions of varied organization strategies e.g., grouping, tool-search, code-mode. +3. **Evangelizing Standards** — The group will invite feedback from developers and maintainers of large MCP servers and clients to migrate away from specific implementations towards standardized extensions. + +## Organization Strategies + +See [Approaches](docs/approaches.md) for detailed descriptions of each strategy, including prior art, examples, and discussion links. + +## IG Principles + +1. **Document Discussions**: The IG aims to document the trade-offs and discussions, rather than dictate one specific implementation. Prefer GitHub Discussions on the IG repository rather than prolonged Discord threads. Meeting notes from synchronous IG calls will also be uploaded on the GitHub Discussion for future documentation. +2. **Experimental Extensions**: The repository will be useful to house experimental extensions for different approaches. Extensions SHOULD support at least Python and TypeScript implementations and include (1) end-to-end working demonstrations and (2) detailed instructions for how others can integrate with them. +3. **Feedback From Deployments**: The IG will solicit deployment experiences and feedback from users of extensions to prioritize feature development and changes. + ## Repository Contents | Document | Description | diff --git a/docs/approaches.md b/docs/approaches.md index 7511a27..472f9f5 100644 --- a/docs/approaches.md +++ b/docs/approaches.md @@ -5,4 +5,59 @@ Approaches | [Open Questions](open-questions.md) | [Experimental Findings](experimental-findings.md) | [Related Work](related-work.md) | -[Contributing](../CONTRIBUTING.md) +[Contributing](../CONTRIBUTING.md) + +This document lists different primitive organization strategies. Many are specific to MCP tools, while primitive grouping applies to Prompts, Tasks, Resources, etc., as well. + +## Primitive Grouping +[Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/2) + +Large MCP servers e.g, Github, Azure, Workspaces, etc., organize primitives into semantic groups. Clients select the groups to use for a particular request / scenario, and servers only list primitives corresponding to those. + +Currently, even though some servers and gateways implement grouping, they do so in an ad-hoc manner, which prevents clients from engaging with them meaningfully. For all of these, users must manually configure groups in the server configuration, except for GitHub MCP where LLM agents can optionally use special tools to enable / disable groups. + +**Examples:** + +- Servers Grouping Primitives: + 1. Github MCP Server – [ToolSets](https://github.com/github/github-mcp-server?tab=readme-ov-file#tools) + 2. Azure Dev Ops – [Domains](https://github.com/github/github-mcp-server?tab=readme-ov-file#tools) + 3. Workspace MCP – [Services](https://github.com/taylorwilsdon/google_workspace_mcp?tab=readme-ov-file#-available-tools) +- Gateways / Middleware: + 1. MCPJungle – [Groups](https://github.com/mcpjungle/MCPJungle?tab=readme-ov-file#tool-groups) +- Clients + 1. ?? + +**References:** + +1. [SEP-2084](https://github.com/chughtapan/modelcontextprotocol/blob/e15be3979999a3fdf64a61681558358d4c8c958c/docs/community/seps/2084-primitive-groups.mdx): Rejected by [core maintainers](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/2204) to avoid locking into one approach too early +2. [SEP: Primitive Groups](https://docs.google.com/document/d/1e7CkEz_8HEC3EARIDZ8Zkl1s3i_u7Oe2cxS36FphEkA/edit?tab=t.0#heading=h.pumr9ld3el7i): Alternative specifications for primitive grouping discussed in #primitive-group-wg. + +## Tool Fusion (mcp-fusion) +[Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/3) + +Instead of including many individual tools with similar schemas in the prompt, fusion creates a "grouped" tool which uses a discriminator field to specify the "opcode" and annotates what parameters are needed for each op. + +**References:** + +1. [mcp-fusion](https://github.com/vinkius-labs/mcp-fusion) – Reference implementation of this technique in Typescript. + +## Tool Search +[Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/4) + +Clients like Claude Code enable "lazy" tool loading — the system prompt includes stubs for each tool, while detailed schemas and docs are added into the context using a common "ToolSearch" tool provided by the client. + +**Examples:** + +- Clients: + 1. Claude / Claude Code – API [reference](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool) + +## Code Mode +[Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/5) + +Instead of calling tools individually, copying data fields across turns, etc., clients treat MCP tools as library functions and write scripts which can execute complex chains of tools in a single turn. Requires structuredOutputs setup correctly. + +**Examples:** + +- Clients: + 1. Claude – API [reference](https://platform.claude.com/cookbook/tool-use-programmatic-tool-calling-ptc) + 2. Cloudflare Workers – [announcement](https://blog.cloudflare.com/code-mode/) diff --git a/specification/draft/grouping.mdx b/specification/draft/grouping.mdx index 2bfd88c..8150748 100644 --- a/specification/draft/grouping.mdx +++ b/specification/draft/grouping.mdx @@ -6,19 +6,7 @@ title: Grouping Extension **Protocol Revision**: draft -## Introduction - -### Purpose and Scope - -This extension defines the Grouping capability for the Model Context Protocol, enabling servers to organize tools, prompts, resources, tasks, and other groups into named collections. Groups allow clients to provide richer workflows such as filtering, agentic control, and simplified server instructions. - -This specification covers: - -- The `Group` type definition -- Discovery via the `groups/list` method -- Membership signaling via the reserved `_meta` key `io.modelcontextprotocol/groups` -- Notifications for group list and membership changes -- Nested group semantics +This extension proposes Groups, a new server capability and primitive, to organize tools, prompts, resources, tasks, and groups themselves, into named collections. ### Extension Identifier @@ -36,11 +24,9 @@ This extension is **OPTIONAL** for MCP implementations. When adopted: - Implementations **MUST** also conform to the core MCP specification - This extension works with all MCP transports -## Capability Negotiation - -### Server Declaration +## Capability -Servers that support groups **MUST** declare support during initialization using the `extensions` field in `ServerCapabilities`: +Servers that support groups MUST declare the capability during initialization, including whether list change notifications are supported. Group lists can change at runtime, and so support for listChanged notifications for each is included. ```json { @@ -54,183 +40,114 @@ Servers that support groups **MUST** declare support during initialization using } ``` -The `listChanged` field indicates whether the server supports `notifications/groups/list_changed` notifications. Servers that omit this field or set it to `false` do not send list change notifications. - -### Client Handling - Clients **SHOULD** check for the `io.modelcontextprotocol/grouping` key in `capabilities.extensions` before issuing `groups/list` requests. Clients that do not recognize the extension **MUST** ignore it — the extension does not alter any core protocol behavior. -## Group Schema - -A `Group` represents a named collection of MCP primitives. - -### Type Definition - -```typescript -interface Group { - /** - * A unique identifier for the group. Intended for programmatic or logical - * use, but used as a display name as fallback if title is not present. - */ - name: string; - - /** - * Intended for UI and end-user contexts — optimized to be human-readable - * and easily understood. If not provided, clients should use name for display. - */ - title?: string; - - /** - * A human-readable description of the group. - */ - description?: string; - - /** - * Optional set of sized icons that the client can display in a user interface. - * - * Clients that support rendering icons MUST support at least: - * - image/png — PNG images - * - image/jpeg (and image/jpg) — JPEG images - * - * Clients that support rendering icons SHOULD also support: - * - image/svg+xml — SVG images (requires security precautions) - * - image/webp — WebP images - */ - icons?: Icon[]; - - /** - * Optional annotations providing additional group information. - * - * Display name precedence order is: title, annotations.title, then name. - */ - annotations?: Annotations; - - /** - * Optional metadata. May include the reserved key - * "io.modelcontextprotocol/groups" to indicate nested group membership. - */ - _meta?: Record; -} -``` - -### Example: Basic Group +## Schema ```json -{ - "name": "user-management", - "title": "User Management Tools", - "description": "Tools used for managing user accounts within the system." -} -``` - -### Example: Group with Icons and Nested Membership - -```json -{ - "name": "email", - "title": "Email Tools", - "description": "Tools for composing and sending emails.", - "icons": [ - { - "src": "https://example.com/email-icon.png", - "mimeType": "image/png", - "sizes": ["48x48"] - } - ], - "_meta": { - "io.modelcontextprotocol/groups": ["productivity"] - } +"Group": { + "properties": { + "name": { + "description": "Intended for programmatic or logical use, but used as a display name in past specs or fallback (if title isn't present). Must be unique.", + "type": "string" + }, + "title": { + "description": "Intended for UI and end-user contexts — optimized to be human-readable and easily understood.", + "type": "string" + }, + "description": { + "description": "A full, human-readable description of the group.", + "type": "string" + }, + "_meta": { + "additionalProperties": {}, + "description": "See [General fields: `_meta`](/specification/2025-11-25/basic/index#meta) for notes on `_meta` usage.", + "io.modelcontextprotocol/groups": { + "description": "A list of group names containing this group.", + "items": { + "type": "string" + }, + "type": "array" + }, + "type": "object", + }, + "annotations": { + "$ref": "#/$defs/Annotation", + "description": "Optional additional group information.\n\nDisplay name precedence order is: title, annotations.title, then name." + }, + "icons": { + "description": "Optional set of sized icons that the client can display in a user interface.\n\nClients that support rendering icons MUST support at least the following MIME types:\n- `image/png` - PNG images (safe, universal compatibility)\n- `image/jpeg` (and `image/jpg`) - JPEG images (safe, universal compatibility)\n\nClients that support rendering icons SHOULD also support:\n- `image/svg+xml` - SVG images (scalable but requires security precautions)\n- `image/webp` - WebP images (modern, efficient format)", + "items": { + "$ref": "#/$defs/Icon" + }, + "type": "array" + } + }, + "required": [ + "name" + ], + "type": "object" } ``` -## Discovery +## Reserved `_meta` Property for All Primitives -### `groups/list` Request +Grouping of all primitives is handled in the same way, including groups themselves. -Clients discover available groups via the `groups/list` method. This method supports cursor-based pagination following the same pattern as other MCP list methods. +For groups, tools, resources, prompts, and tasks, an optional reserved `_meta` key is used to present the list of group names to which the primitive instance belongs. -**Request:** +By listing a primitive's group memberships in a reserved `_meta` property, we ensure backward compatibility. ```json -{ - "jsonrpc": "2.0", - "id": 1, - "method": "groups/list" -} + "io.modelcontextprotocol/groups": { + "description": "A list of group names containing this [primitive name].", + "items": { + "type": "string" + }, + "type": "array" + }, ``` -With optional cursor for pagination: +## Groups Discovery Method: `groups/list` + +Request: ```json { "jsonrpc": "2.0", - "id": 1, - "method": "groups/list", - "params": { - "cursor": "next-page-cursor" - } + "id": 2, + "method": "groups/list" } ``` -### `groups/list` Response - -The response contains an array of `Group` objects and an optional `nextCursor` for pagination: +Response: ```json { "jsonrpc": "2.0", - "id": 1, + "id": 2, "result": { "groups": [ { - "name": "user-management", + "name": "user", "title": "User Management Tools", - "description": "Tools used for managing user accounts." + "description": "Tools used for managing user accounts within the system." }, { "name": "mapping", "title": "Geospatial Mapping Tools", - "description": "Tools for map rendering and spatial analysis." + "description": "Tools used for map rendering, geocoding, and spatial analysis." } - ], - "nextCursor": "next-page-cursor" + ] } } ``` -### Type Definitions - -```typescript -interface ListGroupsRequest { - method: "groups/list"; - params?: { - cursor?: string; - _meta?: Record; - }; -} - -interface ListGroupsResult { - groups: Group[]; - nextCursor?: string; - _meta?: Record; -} -``` - -## Membership - -### Reserved `_meta` Key - -Group membership for all primitives (tools, resources, resource templates, prompts, tasks, and groups themselves) is expressed via a reserved `_meta` key: - -``` -io.modelcontextprotocol/groups -``` - -The value is an array of group `name` strings identifying which groups a primitive belongs to. +## Changes to Response Formats -### Example: Tool with Group Membership +As mentioned above, all primitives have a new property that appears in their list result. This includes responses from `groups/list`, `prompts/list`, `resources/list`, `resources/templates/list`, `tasks/list`, and `tools/list`, -A tool listed in the `tools/list` response indicating membership in the `arithmetic` group: +Here is an example tool definition from `tools/list` response with new property in its `_meta` field: ```json { @@ -253,21 +170,11 @@ A tool listed in the `tools/list` response indicating membership in the `arithme } ``` -### Membership Constraints - -1. Primitives **MAY** belong to multiple groups. For example, a `spell_check` tool might appear in both `compose_email` and `compose_document` groups. -2. Primitives **MAY** belong to zero groups. The `io.modelcontextprotocol/groups` key is optional; its absence means the primitive is ungrouped. -3. Clients **MUST** treat group names as opaque identifiers and resolve them against the `groups/list` result. - -### Backward Compatibility - -By using a `_meta` key for membership, this extension ensures backward compatibility. Older clients that do not recognize the `io.modelcontextprotocol/groups` key will simply ignore it — the core primitive data remains unchanged. - ## Notifications -### Group List Changed +### List Changed -When the list of available groups changes, servers that declared `listChanged: true` in the capability **SHOULD** send: +When the list of available groups changes, servers that declared the `listChanged` capability SHOULD send a notification: ```json { @@ -276,74 +183,9 @@ When the list of available groups changes, servers that declared `listChanged: t } ``` -Upon receiving this notification, clients **SHOULD** re-issue a `groups/list` request to get the updated list. - ### Membership Changed -If a primitive is added to or removed from a group, the server **SHOULD** send the appropriate list changed notification for that primitive type. For example: - -- If a tool's group membership changes → `notifications/tools/list_changed` -- If a resource's group membership changes → `notifications/resources/list_changed` -- If a group's group membership changes → `notifications/groups/list_changed` - -This reuses existing MCP notification mechanisms and requires no new notification types for membership changes. - -### Type Definition - -```typescript -interface GroupListChangedNotification { - method: "notifications/groups/list_changed"; - params?: Record; -} -``` - -## Nested Groups - -### Groups Belonging to Groups - -Groups **MAY** belong to other groups using the same `_meta` key mechanism. This enables organizing groups into larger categories without introducing a separate hierarchy mechanism. - -### Example - -A server provides three groups: `email`, `calendar`, and `productivity`. The `email` and `calendar` groups belong to `productivity`: - -```json -[ - { - "name": "productivity", - "title": "Productivity Suite", - "description": "All productivity-related tools." - }, - { - "name": "email", - "title": "Email Tools", - "description": "Tools for composing and sending emails.", - "_meta": { - "io.modelcontextprotocol/groups": ["productivity"] - } - }, - { - "name": "calendar", - "title": "Calendar Tools", - "description": "Tools for scheduling and calendar management.", - "_meta": { - "io.modelcontextprotocol/groups": ["productivity"] - } - } -] -``` - -### Transitivity - -Clients **MAY** interpret transitive relationships based on their specific use cases. For example, a client might show all tools in `email` and `calendar` when the user selects the `productivity` group. Other clients might show only direct members. - -This specification does not mandate a particular traversal strategy — clients are free to choose the behavior that best fits their UX. - -### Constraints - -- Servers **MUST NOT** create self-referential groups (a group belonging to itself). -- Servers **MUST NOT** create cyclic membership (e.g., group A belongs to group B, and group B belongs to group A). -- Servers are responsible for ensuring valid group structures. SDKs **MAY** provide validation helpers. +If a primitive is added (or removed) from a group, the server SHOULD send the `list_changed` notification appropriate for that primitive. ## Graceful Degradation @@ -358,11 +200,3 @@ If a client does not support this extension, the server's group declarations are ### Partial Support A server **MAY** support groups for only a subset of its primitives. For example, a server might group its tools but not its resources. Clients **SHOULD** handle the case where some primitives in a `groups/list` result have no corresponding members. - -## Security Considerations - -This extension does not introduce new security implications beyond those already present in the core MCP specification. Specifically: - -- Group information exposed to LLMs presents challenges similar to other primitive metadata. Servers **SHOULD** avoid including sensitive information in group names, titles, or descriptions. -- If servers use groups for access control purposes, the access control logic **MUST** be enforced server-side. Clients **MUST NOT** rely on group membership as a security boundary. -- Groups do not grant any additional capabilities — they are purely organizational metadata. From 01d2305f57920f883a1b18740a0ed19e2d846f93 Mon Sep 17 00:00:00 2001 From: Tapan Chugh Date: Mon, 2 Mar 2026 13:20:59 -0800 Subject: [PATCH 3/6] Update docs/approaches.md Co-authored-by: Cliff Hall --- docs/approaches.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/approaches.md b/docs/approaches.md index 472f9f5..3f6dc8e 100644 --- a/docs/approaches.md +++ b/docs/approaches.md @@ -31,7 +31,7 @@ Currently, even though some servers and gateways implement grouping, they do so 1. [SEP-2084](https://github.com/chughtapan/modelcontextprotocol/blob/e15be3979999a3fdf64a61681558358d4c8c958c/docs/community/seps/2084-primitive-groups.mdx): Rejected by [core maintainers](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/2204) to avoid locking into one approach too early 2. [SEP: Primitive Groups](https://docs.google.com/document/d/1e7CkEz_8HEC3EARIDZ8Zkl1s3i_u7Oe2cxS36FphEkA/edit?tab=t.0#heading=h.pumr9ld3el7i): Alternative specifications for primitive grouping discussed in #primitive-group-wg. - +3. [SEP-993: Namespaces](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/993): Inserts a namespace parameter prior to primitive list methods, e.g., `/tools/list` as a method for grouping. Also rejected by core maintainers with less clear feedback. ## Tool Fusion (mcp-fusion) [Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/3) From f49415f3775b2030cbabe449c50a84fb23bdc07f Mon Sep 17 00:00:00 2001 From: Tapan Chugh Date: Mon, 2 Mar 2026 13:21:25 -0800 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Cliff Hall --- docs/approaches.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/approaches.md b/docs/approaches.md index 3f6dc8e..3b1a633 100644 --- a/docs/approaches.md +++ b/docs/approaches.md @@ -29,8 +29,8 @@ Currently, even though some servers and gateways implement grouping, they do so **References:** -1. [SEP-2084](https://github.com/chughtapan/modelcontextprotocol/blob/e15be3979999a3fdf64a61681558358d4c8c958c/docs/community/seps/2084-primitive-groups.mdx): Rejected by [core maintainers](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/2204) to avoid locking into one approach too early -2. [SEP: Primitive Groups](https://docs.google.com/document/d/1e7CkEz_8HEC3EARIDZ8Zkl1s3i_u7Oe2cxS36FphEkA/edit?tab=t.0#heading=h.pumr9ld3el7i): Alternative specifications for primitive grouping discussed in #primitive-group-wg. +1. [SEP-2084: Primitive Groups](https://github.com/chughtapan/modelcontextprotocol/blob/e15be3979999a3fdf64a61681558358d4c8c958c/docs/community/seps/2084-primitive-groups.mdx): Rejected by [core maintainers](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/2204) to avoid locking into one approach too early +2. [SEP-2084: Primitive Groups - Alternative drafts](https://docs.google.com/document/d/1e7CkEz_8HEC3EARIDZ8Zkl1s3i_u7Oe2cxS36FphEkA/edit?tab=t.0#heading=h.pumr9ld3el7i): Alternative specifications for primitive grouping discussed in #primitive-group-wg. 3. [SEP-993: Namespaces](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/993): Inserts a namespace parameter prior to primitive list methods, e.g., `/tools/list` as a method for grouping. Also rejected by core maintainers with less clear feedback. ## Tool Fusion (mcp-fusion) [Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/3) From b4bdba6e86cd525a93338d449765f68824d6990e Mon Sep 17 00:00:00 2001 From: Tapan Chugh Date: Mon, 2 Mar 2026 13:29:28 -0800 Subject: [PATCH 5/6] Add Server Variants (SEP-2053) to organization approaches Co-Authored-By: Claude Opus 4.6 --- docs/approaches.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/approaches.md b/docs/approaches.md index 3b1a633..9af5ffe 100644 --- a/docs/approaches.md +++ b/docs/approaches.md @@ -32,6 +32,15 @@ Currently, even though some servers and gateways implement grouping, they do so 1. [SEP-2084: Primitive Groups](https://github.com/chughtapan/modelcontextprotocol/blob/e15be3979999a3fdf64a61681558358d4c8c958c/docs/community/seps/2084-primitive-groups.mdx): Rejected by [core maintainers](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/2204) to avoid locking into one approach too early 2. [SEP-2084: Primitive Groups - Alternative drafts](https://docs.google.com/document/d/1e7CkEz_8HEC3EARIDZ8Zkl1s3i_u7Oe2cxS36FphEkA/edit?tab=t.0#heading=h.pumr9ld3el7i): Alternative specifications for primitive grouping discussed in #primitive-group-wg. 3. [SEP-993: Namespaces](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/993): Inserts a namespace parameter prior to primitive list methods, e.g., `/tools/list` as a method for grouping. Also rejected by core maintainers with less clear feedback. + +## Server Variants +[Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/8) + +Server variants allow MCP servers to expose multiple parallel configurations (e.g., `claude-optimized`, `compact`, `coding-assistant`) that clients can intelligently select based on their context. Each variant includes a unique identifier, human-readable description, and key-value hints. + +**References:** + +1. [SEP-2053: Server Variants](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2053) ## Tool Fusion (mcp-fusion) [Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/3) From 7fc5ee9369407bdde5eaaabd4918a82582c14eb0 Mon Sep 17 00:00:00 2001 From: Tapan Chugh Date: Tue, 3 Mar 2026 22:43:54 -0800 Subject: [PATCH 6/6] Address PR review feedback on approaches doc Restructure into Primitive Organization Strategies and Alternatives sections, add annotations context, VS Code Copilot client examples, and open question about client adoption of grouping. Co-Authored-By: Claude Opus 4.6 --- docs/approaches.md | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/docs/approaches.md b/docs/approaches.md index 9af5ffe..cb23a99 100644 --- a/docs/approaches.md +++ b/docs/approaches.md @@ -7,9 +7,13 @@ Approaches | [Related Work](related-work.md) | [Contributing](../CONTRIBUTING.md) -This document lists different primitive organization strategies. Many are specific to MCP tools, while primitive grouping applies to Prompts, Tasks, Resources, etc., as well. +This document lists approaches to the problem of flat primitive lists being insufficient at scale. We consider both direct organization strategies, and other complementary techniques that mitigate context overload without explicitly organizing primitives. -## Primitive Grouping +## Primitive Organization Strategies + +MCP [Annotations](https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/annotations) provide a common vocabulary for organizing tools (e.g., `readOnly`, `destructive`, etc.). Here, we consider organization strategies that individual servers can customize flexibly. + +### Primitive Grouping [Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/2) Large MCP servers e.g, Github, Azure, Workspaces, etc., organize primitives into semantic groups. Clients select the groups to use for a particular request / scenario, and servers only list primitives corresponding to those. @@ -24,8 +28,9 @@ Currently, even though some servers and gateways implement grouping, they do so 3. Workspace MCP – [Services](https://github.com/taylorwilsdon/google_workspace_mcp?tab=readme-ov-file#-available-tools) - Gateways / Middleware: 1. MCPJungle – [Groups](https://github.com/mcpjungle/MCPJungle?tab=readme-ov-file#tool-groups) -- Clients - 1. ?? +- Clients: + 1. VS Code Copilot – [Automatic grouping](https://github.blog/ai-and-ml/github-copilot/how-were-making-github-copilot-smarter-with-fewer-tools/) for context reduction + 2. VS Code Copilot – [Tool Sets](https://code.visualstudio.com/docs/copilot/agents/agent-tools#_group-tools-with-tool-sets) for user-defined grouping **References:** @@ -33,7 +38,9 @@ Currently, even though some servers and gateways implement grouping, they do so 2. [SEP-2084: Primitive Groups - Alternative drafts](https://docs.google.com/document/d/1e7CkEz_8HEC3EARIDZ8Zkl1s3i_u7Oe2cxS36FphEkA/edit?tab=t.0#heading=h.pumr9ld3el7i): Alternative specifications for primitive grouping discussed in #primitive-group-wg. 3. [SEP-993: Namespaces](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/993): Inserts a namespace parameter prior to primitive list methods, e.g., `/tools/list` as a method for grouping. Also rejected by core maintainers with less clear feedback. -## Server Variants +Given that clients don't seem to have leveraged existing logical groupings using annotations (in spite of a lot of end users leveraging them via config), it's an open question as to whether or not there is any desire to support groupings at all in popular clients. + +### Server Variants [Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/8) Server variants allow MCP servers to expose multiple parallel configurations (e.g., `claude-optimized`, `compact`, `coding-assistant`) that clients can intelligently select based on their context. Each variant includes a unique identifier, human-readable description, and key-value hints. @@ -41,7 +48,10 @@ Server variants allow MCP servers to expose multiple parallel configurations (e. **References:** 1. [SEP-2053: Server Variants](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2053) -## Tool Fusion (mcp-fusion) + +## Alternatives + +### Tool Fusion (mcp-fusion) [Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/3) Instead of including many individual tools with similar schemas in the prompt, fusion creates a "grouped" tool which uses a discriminator field to specify the "opcode" and annotates what parameters are needed for each op. @@ -50,7 +60,7 @@ Instead of including many individual tools with similar schemas in the prompt, f 1. [mcp-fusion](https://github.com/vinkius-labs/mcp-fusion) – Reference implementation of this technique in Typescript. -## Tool Search +### Tool Search [Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/4) Clients like Claude Code enable "lazy" tool loading — the system prompt includes stubs for each tool, while detailed schemas and docs are added into the context using a common "ToolSearch" tool provided by the client. @@ -60,7 +70,7 @@ Clients like Claude Code enable "lazy" tool loading — the system prompt includ - Clients: 1. Claude / Claude Code – API [reference](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool) -## Code Mode +### Code Mode [Discussion](https://github.com/modelcontextprotocol/experimental-ext-grouping/discussions/5) Instead of calling tools individually, copying data fields across turns, etc., clients treat MCP tools as library functions and write scripts which can execute complex chains of tools in a single turn. Requires structuredOutputs setup correctly.