Proposal: Concern-Based Filtering #1936
duwenji
started this conversation in
Ideas - General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Abstract
The MCP protocol currently provides primitives (Tools, Prompts, Resources, Tasks) that enable servers to expose capabilities to clients. However, as the number of available primitives grows, clients face "Context Overflow" – an overwhelming number of options that makes it difficult to select the most appropriate tools for a given task.
While technical organization mechanisms like grouping can help developers structure primitives, they do not address the fundamental need for user‑centric filtering. Users and MCP Hosts need to express their requirements in natural, domain‑oriented terms (e.g., "high security", "low cost", "production‑ready") rather than navigating technical categories.
This proposal introduces a Concern‑Based Filtering that allows:
This approach complements existing technical‑organization proposals (e.g., Group primitive) by providing a higher‑level, user‑oriented filtering layer that is intuitive for end‑users while remaining flexible and extensible for server implementers.
Motivation
The Context Overflow Problem
As MCP ecosystems grow, a single server may expose dozens or hundreds of primitives. Clients (especially AI agents) must sift through this large set to choose the right tool for a given context. Without a filtering mechanism that aligns with user intent, the cognitive load increases, leading to suboptimal tool selection or inefficient use of context window.
User‑Centric vs. Developer‑Centric Organization
Existing proposals focus on developer‑centric organization – grouping primitives by technical categories, namespace hierarchies, or functional similarity. While valuable for server‑side structure, these groupings do not directly translate to user needs. For example, a user who cares about "security" and "cost" should not need to understand which internal groups correspond to those concerns.
Minimal Protocol Impact
A key design goal is to keep protocol changes minimal and backward‑compatible. The Concern‑Based Filtering integrates with the existing MCP lifecycle through optional extensions:
initializerequest/response flow, avoiding additional round‑trips.This approach ensures that the filtering system enhances the protocol without disrupting established workflows or requiring immediate ecosystem‑wide upgrades.
Specification
Overview
The Concern‑Based Filtering operates in three phases:
Concern Declaration
Concerns can be declared through the MCP lifecycle's Initialization phase, integrating seamlessly with the existing protocol flow.
Option A: Initialization Extension
During the
initializerequest/response exchange, the server may include an optionalconcernsfield within thecapabilitiesobject:Option B: Dedicated
listConcernsMethod (Fallback)For servers that prefer dynamic concern discovery or need to update Concerns after initialization, an optional
listConcerns()method can be provided. This method returns the same Concern definitions as above.Concern Definition
Each Concern is defined as:
{ "name": "security", "description": "Security level required for the operation", "values": ["high", "medium", "low"], "default": "medium" }name: A unique identifier for the Concern (e.g., "security", "cost", "performance").description: Human‑readable explanation of what this Concern represents.values: An array of possible values/levels for this Concern. May be an enumerated set or a range.default: The default value if the host does not explicitly configure this Concern.Servers may declare multiple Concerns. The set of Concerns is static for a given server version but may change across versions. The Initialization‑based approach (Option A) is preferred as it aligns with the MCP lifecycle and reduces round‑trips.
Concern Configuration
Concern preferences can be communicated through multiple channels, with the post‑initialization phase being the primary recommended approach.
Option A: Initialized Notification Extension
After receiving the server's
initializeresponse (which contains the server's declared Concerns), the host includes an optionalconcernsfield in theinitializednotification:This timing ensures the host knows which Concerns the server supports before providing its preferences.
Option B: Dynamic Update via
updateConcernsAfter the session is established, the host can update its Concern configuration at any time using the optional
updateConcerns(config)method (see "New Protocol Methods" below).Option C: Initialization Request with Pre‑known Concerns
If the host already knows the server's Concerns (e.g., from a previous session, documentation, or discovery), it may include
concernsin theinitializerequest. This is an advanced use case and not the default recommendation.Option D: Host‑Side Preference Storage
The host may store Concern preferences per‑user or per‑session and apply them transparently when communicating with the server. This is an implementation detail outside the protocol.
Configuration Format
The configuration is a simple object mapping Concern names to desired values:
{ "security": "high", "cost": "minimal", "performance": "balanced" }Any Concern not explicitly configured uses the server‑declared default value. If the host configures a Concern that the server does not declare, that entry is ignored (or may trigger a warning).
Timing and Precedence
This design ensures Concerns can be configured with full knowledge of server capabilities, while maintaining flexibility for runtime adjustments.
Filtering Mechanism
When the host issues a request for primitives (e.g.,
listTools,listResources,listPrompts,listTasks), the server uses the current Concern configuration to filter the returned set. The filtering applies to all primitives that support Concerns, including Tools, Resources, Prompts, and Tasks.The server maintains an internal mapping that associates each primitive with Concern values. This mapping is an implementation detail of the server and is not exposed in the protocol. For example, a server might have a configuration file or code that maps primitive names to Concern values:
{ "encryptData": {"security": "high", "cost": "minimal"}, "logData": {"security": "medium"}, "validateData": {} }When the host provides a Concern configuration, the server filters its primitives based on this internal mapping. If a primitive has no mapping for a given Concern, it is assumed to match all values of that Concern (i.e., it is Concern‑agnostic). If a primitive has a mapping for a Concern, it is included only when the host’s configured value matches.
Filtering rule: A primitive is included if for every Concern configured by the host, the primitive’s mapped Concern value (if any) matches the host’s configured value. Concerns not configured by the host are ignored.
Implementation Flexibility
The server may choose how to associate Concern values with primitives. Two common approaches are:
Internal Mapping: The server maintains a separate mapping (e.g., configuration file, code map) that links primitive names to Concern values. This approach does not modify the primitive schemas and is entirely internal to the server.
Optional Field in
_meta: For servers that prefer to embed Concern information directly in primitive schemas, an optionalconcernsfield can be placed inside the existing_metaproperty:{ "name": "encryptData", "_meta": { "concerns": { "security": "high", "cost": "minimal" } } }This allows Concern‑aware clients to inspect the field for debugging or UI purposes, while non‑aware clients ignore it.
The first approach (internal mapping) is recommended as it keeps the protocol unchanged and delegates filtering logic entirely to the server. The second approach provides additional transparency but requires modifying primitive schemas.
New Protocol Methods (Optional)
For richer interaction, two optional methods can be added:
listConcerns()Returns the server’s declared Concerns and their possible values, identical to the
concernsarray that may be provided during initialization. This method allows hosts to discover Concerns dynamically if they were not provided during initialization.updateConcerns(config)Dynamically updates the host’s Concern configuration. This method enables runtime adjustment of filtering preferences without re‑initializing the session.
Request:
{ "concerns": { "security": "high", "cost": "moderate" } }Response: The server acknowledges the update with a success response. The new configuration takes effect immediately for all subsequent primitive listings (e.g.,
listTools,listResources,listPrompts,listTasks).Behavior:
Error Handling:
valuesrange, the server may either clamp to the nearest valid value, ignore the entry, or return an error.If these methods are not implemented, the Concern configuration can be communicated via existing extension mechanisms (e.g., initialization options or host‑to‑server messages).
Rationale
Why Concerns Instead of Just Groups?
Groups provide a technical, server‑side organization mechanism. Concerns provide a user‑intent‑based filtering layer. The two are complementary:
A server may implement Groups internally to manage its primitives, then map those Groups to Concerns for user‑friendly filtering. This separation of concerns (pun intended) keeps the protocol flexible.
Minimal Protocol Changes
The proposal requires only:
concernsdeclaration in the server's initialization response (within thecapabilitiesobject).No changes are required to existing RPC messages, and clients that ignore the
concernsfield continue to work as before.Extensibility
New Concerns can be added over time without breaking existing clients or servers. Servers can adopt Concerns incrementally – starting with a few well‑known Concerns (security, cost) and adding more as needed.
Concerns can also be combined with other filtering mechanisms (tags, groups, search keywords) to create a powerful, multi‑layered filtering.
Example Workflow
This example demonstrates the complete flow using the Initialization‑phase integration with proper timing:
Server declares Concerns during initialization:
Host configures Concerns in initialized notification (after receiving server's Concerns):
Server filters Tools when listing (using its internal mapping):
{"security": "high", "cost": "minimal"}→ included.{"security": "medium"}→ excluded (security mismatch).Host receives filtered
listToolsresponse containing only tools that match high security and minimal cost requirements.Dynamic update scenario:
updateConcerns({"security": "high", "cost": "moderate"}).listToolscalls include tools with"cost": "moderate"(or no cost concern).This workflow shows how Concerns integrate naturally with the MCP lifecycle while ensuring the host has full knowledge of server capabilities before providing preferences.
Backward Compatibility
Clients
concernsfields and receive the full set of primitives (current behavior).Servers
concernsfields; everything works as today.Protocol
No existing RPC methods are changed or removed. New optional methods (
listConcerns,updateConcerns) are introduced only if needed. The primary mechanism is adding an optionalconcernsfield within thecapabilitiesobject during initialization, which is already designed for optional, backward‑compatible enhancements.Security Implications
Information Disclosure
Declaring Concerns may reveal information about server capabilities (e.g., that the server has tools with different security levels). This is similar to existing metadata (tool descriptions) and is not considered a new risk.
Filtering Bypass
A malicious client could ignore Concern filtering and attempt to access primitives that do not match its configured Concerns. This is no different from today’s behavior, where clients can call any tool they discover. Concern filtering is a recommendation/optimization layer, not an access‑control mechanism. Proper access control should be implemented separately (e.g., via authentication and authorization).
Server‑Side Implementation
Servers must ensure that Concern filtering is implemented correctly and does not introduce bugs that inadvertently hide critical primitives. Testing and validation are required, as with any new feature.
Reference Implementation
A reference implementation will be provided in a separate repository. The implementation will demonstrate:
listToolsandlistTasksresponses based on host‑provided Concern configuration.The implementation will showcase both the internal‑mapping approach and the optional
_meta.concernsfield for transparency.Next Steps
Acknowledgements
Thanks to the MCP community for the ongoing discussion about tool filtering and context management. Special thanks to Scott Lewis for the Group primitive proposal that sparked this complementary idea.
Beta Was this translation helpful? Give feedback.
All reactions