Skip to content

Conversation

@cliffhall
Copy link
Member

@cliffhall cliffhall commented Jan 16, 2026

Implemented the new groups primitive across the MCP TypeScript SDK, allowing servers to organize primitives (tools, prompts, tasks, resources, and groups themselves) into logical groups. This change includes updates to the core protocol schemas, high-level server and client APIs, and comprehensive testing.

PR Description: Implementation of Groups Primitive

This PR introduces the groups primitive to the Model Context Protocol TypeScript SDK, enabling servers to categorize and organize their offerings.

Core Changes (@modelcontextprotocol/core)

src/types/types.ts

  • Added GROUPS_META_KEY constant (io.modelcontextprotocol/groups).
  • Updated BaseMetadataSchema to include name and optional title.
  • Introduced GroupSchema and Group type for defining group objects.
  • Added ServerCapabilitiesSchema.groups to allow servers to advertise group support and listChanged notifications.
  • Added ListGroupsRequestSchema, ListGroupsResultSchema, and GroupListChangedNotificationSchema for protocol-level group management.
  • Updated ToolSchema, PromptSchema, ResourceSchema, and TaskSchema to support the groups key in their _meta objects.
  • Added ListChangedHandlers support for groups in client-side configuration.

src/shared/protocol.ts

  • Added listGroups method to the base Protocol class to handle groups/list requests.

Server Changes (@modelcontextprotocol/server)

src/server/server.ts

  • Added sendGroupListChanged() method to the Server class to emit notifications/groups/list_changed to connected clients.

src/server/mcp.ts

  • Added registerGroup() to the high-level McpServer API.
  • Implemented automatic handling of groups/list requests.
  • Updated registerTool, registerPrompt, and registerResource to correctly propagate _meta information (including group memberships) to the client.
  • Modified registration logic to be "connection-aware": capabilities and request handlers are registered before connection, while list_changed notifications are sent if changes occur post-connection.
  • Improved update() methods for registered primitives to handle dynamic name changes and metadata updates.

Client Changes (@modelcontextprotocol/client)

src/client/client.ts

  • Added listGroups() method to fetch the list of groups from a server.
  • Integrated groups into the listChanged notification handling system, allowing clients to automatically refresh group lists when the server notifies of changes.

Examples (@modelcontextprotocol/examples)

src/examples/server/src/groupsExample.ts (New)

  • implement a server with
    • two parent groups (communications and work)
    • several child groups (email, calendar, spreadsheets, documents, todos).
    • prompts, resources, and tools organized into groups

src/examples/server/README.md

  • document the example server groupsExample.ts

src/examples/client/src/groupsExampleClient.ts (New)

  • implement a command line REPL with commands
    • all/a - list all groups, tools, resources, and prompts
    • groups/g/enter - list available groups
    • help/h - for a list of commands
    • quit/q - to exit the program
  • enter a command name or a list of groups to filter by

src/examples/client/README.md

  • document the example client groupsExampleClient.ts

Testing

packages/server/test/server/groups.test.ts (New)

  • Verified group registration and listing.
  • Verified mixed membership: tools, prompts, resources, and task-tools assigned to the same group.
  • Verified nested groups (groups within groups).
  • Verified that _meta.groups is only present in listed primitives when they are actually assigned to a group.

test/integration/test/client/client.test.ts

  • Added integration tests for groups/list and notifications/groups/list_changed.
  • Ensured proper synchronization between server registration and client-side auto-refresh logic.

Motivation and Context

Reference implementation for SEP-2084: Primitive Grouping.

How Has This Been Tested?

  • Unit tests for client and server included in PR.
  • Client and server examples included in PR.

Run the example client

  • It automatically starts the example server via STDIO.
pnpm --filter @modelcontextprotocol/examples-client exec tsx src/groupsExampleClient.ts

The Menu

=======================
Groups filtering client
=======================
Starting stdio server: pnpm tsx /Users/cliffhall/Projects/mcp-typescript-sdk/examples/server/src/groupsExample.ts
Groups example MCP server running on stdio.

Fetched: 7 groups, 10 tools, 5 resources, 5 prompts.
Available groups: calendar, communications, documents, email, spreadsheets, todos, work

Commands:
 all (a)                 List all groups, tools, resources, and prompts
 groups (g/enter)        List available groups 
 help (h)                Show this help
 exit (e)                Quit
 <groups...>             Filter by one or more groups (comma or space-separated)

Enter a command or a list of groups to filter by: 

List All Primitives

Enter a command or a list of groups to filter by: all

Groups:
- calendar — Scheduling operations and event management.
- communications — Tools, resources, and prompts related to messaging and scheduling.
- documents — Document drafting, editing, and summarization workflows.
- email — Email composition and inbox-oriented operations.
- spreadsheets — Spreadsheet-like operations: create sheets, add rows, and do quick calculations.
- todos — Task capture and lightweight task management.
- work — Tools, resources, and prompts related to day-to-day work.

Tools:
- calendar_create_event — Create a calendar event.
- calendar_list_upcoming — List upcoming calendar events (demo).
- documents_create — Create a document draft.
- documents_summarize — Summarize a document (demo).
- email_search_inbox — Search the inbox by query string.
- email_send — Send an email message.
- spreadsheets_add_row — Add a row to a spreadsheet.
- spreadsheets_create — Create a new spreadsheet.
- todos_add — Add a todo item.
- todos_complete — Mark a todo item complete.

Resources:
- calendar_overview — A short overview of calendar-related concepts and workflows.
- documents_overview — A short overview of document workflows.
- email_overview — A short overview of email etiquette and structure.
- spreadsheets_overview — A short overview of spreadsheet structure and best practices.
- todos_overview — A short overview of task management basics.

Prompts:
- calendar_meeting_agenda — Draft a short agenda for an upcoming meeting.
- documents_write_outline — Create an outline for a document on a topic.
- email_thank_contributor — Compose an email thanking someone for their recent contributions.
- spreadsheets_quick_analysis — Suggest a simple spreadsheet layout for tracking a metric.
- todos_plan_day — Turn a list of tasks into a simple day plan.

Filter all by a parent group

Enter a command or a list of groups to filter by: communications

Groups:
- calendar — Scheduling operations and event management.
- email — Email composition and inbox-oriented operations.

Tools:
- calendar_create_event — Create a calendar event.
- calendar_list_upcoming — List upcoming calendar events (demo).
- email_search_inbox — Search the inbox by query string.
- email_send — Send an email message.

Resources:
- calendar_overview — A short overview of calendar-related concepts and workflows.
- email_overview — A short overview of email etiquette and structure.

Prompts:
- calendar_meeting_agenda — Draft a short agenda for an upcoming meeting.
- email_thank_contributor — Compose an email thanking someone for their recent contributions.

Filter all by a leaf group

Enter a command or a list of groups to filter by: todos

Groups:
(none)

Tools:
- todos_add — Add a todo item.
- todos_complete — Mark a todo item complete.

Resources:
- todos_overview — A short overview of task management basics.

Prompts:
- todos_plan_day — Turn a list of tasks into a simple day plan.

Breaking Changes

None.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

… allowing servers to organize primitives (tools, prompts, tasks, resources, and groups themselves) into logical groups. This change includes updates to the core protocol schemas, high-level server and client APIs, and comprehensive testing.

### PR Description: Implementation of Groups Primitive

This PR introduces the `groups` primitive to the Model Context Protocol TypeScript SDK, enabling servers to categorize and organize their offerings.

#### Core Changes (`@modelcontextprotocol/core`)

**`src/types/types.ts`**
- Added `GROUPS_META_KEY` constant (`io.modelcontextprotocol/groups`).
- Updated `BaseMetadataSchema` to include `name` and optional `title`.
- Introduced `GroupSchema` and `Group` type for defining group objects.
- Added `ServerCapabilitiesSchema.groups` to allow servers to advertise group support and `listChanged` notifications.
- Added `ListGroupsRequestSchema`, `ListGroupsResultSchema`, and `GroupListChangedNotificationSchema` for protocol-level group management.
- Updated `ToolSchema`, `PromptSchema`, `ResourceSchema`, and `TaskSchema` to support the `groups` key in their `_meta` objects.
- Added `ListChangedHandlers` support for groups in client-side configuration.

**`src/shared/protocol.ts`**
- Added `listGroups` method to the base `Protocol` class to handle `groups/list` requests.

#### Server Changes (`@modelcontextprotocol/server`)

**`src/server/server.ts`**
- Added `sendGroupListChanged()` method to the `Server` class to emit `notifications/groups/list_changed` to connected clients.

**`src/server/mcp.ts`**
- Added `registerGroup()` to the high-level `McpServer` API.
- Implemented automatic handling of `groups/list` requests.
- Updated `registerTool`, `registerPrompt`, and `registerResource` to correctly propagate `_meta` information (including group memberships) to the client.
- Modified registration logic to be "connection-aware": capabilities and request handlers are registered before connection, while `list_changed` notifications are sent if changes occur post-connection.
- Improved `update()` methods for registered primitives to handle dynamic name changes and metadata updates.

#### Client Changes (`@modelcontextprotocol/client`)

**`src/client/client.ts`**
- Added `listGroups()` method to fetch the list of groups from a server.
- Integrated `groups` into the `listChanged` notification handling system, allowing clients to automatically refresh group lists when the server notifies of changes.

#### Testing

**`packages/server/test/server/groups.test.ts` (New)**
- Verified group registration and listing.
- Verified mixed membership: tools, prompts, resources, and task-tools assigned to the same group.
- Verified nested groups (groups within groups).
- Verified that `_meta.groups` is only present in listed primitives when they are actually assigned to a group.

**`test/integration/test/client/client.test.ts`**
- Added integration tests for `groups/list` and `notifications/groups/list_changed`.
- Ensured proper synchronization between server registration and client-side auto-refresh logic.
@changeset-bot
Copy link

changeset-bot bot commented Jan 16, 2026

⚠️ No Changeset found

Latest commit: 96ab61c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 16, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@1399

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@1399

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@1399

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@1399

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@1399

commit: 96ab61c

* In groupsExample.ts
  - implement a server with
    - two parent groups (communications and work)
    - several child groups (email, calendar, spreadsheets, documents, todos).
    - prompts, resources, and tools organized into groups

* In groupsExampleClient.ts
  - implement a command line REPL with commands
    - all/a - list all groups, tools, resources, and prompts
    - groups/g/enter - list available groups
    - help/h - for a list of commands
    - quit/q - to exit the program
  - enter a command name or a list of groups to filter by

* In examples/client/README.md
  - document the example client groupsExampleClient.ts

* In examples/server/README.md
  - document the example server groupsExample.ts
  - simplify command prompt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant