-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: Add custom context support for MCP transports #819
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
base: main
Are you sure you want to change the base?
feat: Add custom context support for MCP transports #819
Conversation
- Add customContext field to MessageExtraInfo interface - Pass customContext through RequestHandlerExtra to handlers - Update InMemoryTransport to support custom context - Add unit test to verify custom context propagation - Enable transport implementations to inject arbitrary context data This allows MCP server implementations to access custom context (e.g., tenant ID, user info, feature flags) passed from the transport layer to tool/resource/prompt handlers.
One thing I had also addressed in a similar way was dependency injection. Is this PR intending to limit the context to data or support request locals generally that can be used for db connections etc...? |
@dr3s The current implementation passes an optional JS object with a Record<string, unknown> type as the custom context, allowing it to be used as a data context or for other JS objects (as property value), such as a DB connection object. |
@grimmerk the reason I asked is because I had tried using RequestHandlerExtra in this way but switched back to closures because it seems some code expected it to just be data. Do you think there's any concern using it for request scoped dependencies? I tried using a generics approach to improve typesafe access to dependencies but was challenged by support in the sdk and |
@dr3s I do not have any specific concerns for the case of request-scoped dependencies yet. I think it should work well. Yes, adding |
We can consider adding a generic in this PR (or new PRs) if more people think it would help. cc @ihrpr @pcarleton
|
@grimmerk I like smaller PRs too. More of a question of whether this should be considered in the design. |
Hi @cliffhall, @domdomegg , @ihrpr, this PR adds custom context support for MCP transports, enabling passing additional context (e.g., user info) to tool handlers - a very common need that currently requires workarounds like closures. Would appreciate a review when you have time. Thanks! |
@grimmerk I do like the looks of this, but I'd also like to see it running in an actual server. Could you add an example server in If it is merged, people will need to see how it works, and seeing how it works would be a big help in deciding if it's a good feature to add. |
f7ae331
to
81982cd
Compare
@cliffhall, thanks for the kind review and feedback. I've added feat: Add custom context example implementation to demonstrate what you suggest. Please let me know if it works. |
- Add server demonstrating API key authentication and context injection - Add interactive client for testing custom context features - Add comprehensive documentation with walkthrough - Update examples README to reference new examples The example demonstrates all three MCP handler types with context: - Tool (get_user) accesses context via extra.customContext - Prompt (user-dashboard) personalizes content via extra.customContext - Resource (user-profile) returns user data via extra.customContext Shows how to build secure, multi-tenant MCP applications with user authentication and permission-based access control.
…tom-context-support
e918ac9
to
8e53179
Compare
Remove unused ListResourcesResultSchema import from customContextClient.ts
… keys - Updated documentation to explicitly mention MCP access tokens (OAuth flow) - Simplified examples to focus on API keys and MCP tokens only - Removed mentions of other auth methods to avoid confusion - Emphasized that the pattern works for both API keys and MCP OAuth tokens
Hi @cliffhall, @ihrpr, I've enhanced the example with clearer documentation on applying custom context to both API keys and MCP access tokens. I've also updated the PR description to better clarify the use cases. Also wanted to mention that the Python SDK seems to have the same limitation. If this TypeScript implementation goes well, I'd be happy to contribute a similar solution for Python in the future. Please take a look when you have time. Thanks! |
This PR adds support for passing custom context data from transport implementations to MCP handlers (tools, resources, prompts). This enables server implementations to inject application-specific context like tenant ID, user info, feature flags, etc. without relying on closures or global state.
Motivation and Context
Currently, MCP server implementations have no standard way to pass request-specific context (e.g., authentication/tenant data from MCP access tokens or API keys, service objects) from the transport layer to tool/resource/prompt handlers.. This limitation forces developers to use workarounds like closures or session-based context maps.
This PR solves this problem by:
customContext
field toMessageExtraInfo
RequestHandlerExtra
to all handlerssetCustomContext()
method on all transport implementationsImplementation Details
Core Changes:
customContext?: Record<string, unknown>
toMessageExtraInfo
customContext
toRequestHandlerExtra
, passed through in_onrequest
setCustomContext()
method to Transport interfaceTransport Implementations:
handleMessage()
onmessage()
callsUsage Example:
How Has This Been Tested?
Breaking Changes
None. All changes are backwards compatible:
customContext
is an optional fieldsetCustomContext()
is an optional methodTypes of changes
Checklist
Additional context
This feature was developed to address the need for multi-tenant MCP server implementations where request-specific context needs to be available throughout the handler chain. The implementation follows existing patterns in the codebase (similar to how
authInfo
andrequestInfo
are handled) and maintains full backwards compatibility.Implementation Notes:
Future Enhancements: