modelcontextprotocol / modelcontextprotocol/java-sdk

Allow subclasses to be used to customize server behavior

未关闭
#872 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

waiting for triage
主要语言
Java
星标
3.7k
派生
1.1k
平均合并
1 天 15 小时
30 天内合并 PR
9

描述

What I say below is (mostly) appropriate to the other types of server classes (i.e. McpSyncServer, McpStateless*), but I'm going to focus specifically on McpAsyncServer current impl for clarity.

Currently the McpAsyncServer constructors are package private...e.g.

	/**
	 * Create a new McpAsyncServer with the given transport provider and capabilities.
	 * @param mcpTransportProvider The transport layer implementation for MCP
	 * communication.
	 * @param features The MCP server supported features.
	 * @param jsonMapper The JsonMapper to use for JSON serialization/deserialization
	 */
	McpAsyncServer(McpServerTransportProvider mcpTransportProvider, McpJsonMapper jsonMapper,
			McpServerFeatures.Async features, Duration requestTimeout,
			McpUriTemplateManagerFactory uriTemplateManagerFactory, JsonSchemaValidator jsonSchemaValidator) {
		this.mcpTransportProvider = mcpTransportProvider;
		this.jsonMapper = jsonMapper;
		this.serverInfo = features.serverInfo();
		this.serverCapabilities = features.serverCapabilities().mutate().logging().build();
		this.instructions = features.instructions();
		this.tools.addAll(withStructuredOutputHandling(jsonSchemaValidator, features.tools()));
		this.resources.putAll(features.resources());
		this.resourceTemplates.putAll(features.resourceTemplates());
		this.prompts.putAll(features.prompts());
		this.completions.putAll(features.completions());
		this.uriTemplateManagerFactory = uriTemplateManagerFactory;
		this.jsonSchemaValidator = jsonSchemaValidator;

		Map<String, McpRequestHandler<?>> requestHandlers = prepareRequestHandlers();
		Map<String, McpNotificationHandler> notificationHandlers = prepareNotificationHandlers(features);

		this.protocolVersions = mcpTransportProvider.protocolVersions();

		mcpTransportProvider.setSessionFactory(transport -> {
			String sessionId = UUID.randomUUID().toString();
			return new McpServerSession(sessionId, requestTimeout, transport, this::asyncInitializeRequestHandler,
					requestHandlers, notificationHandlers, () -> this.cleanupForSession(sessionId));
		});
	}

Among other things, this means that users of the sdk cannot customize the server runtime behavior, as they are essentially forced to use not only the static factory methods, but also cannot provide custom features on construction nor customize the server initialization via the methods called in the constructor: prepareRequestHandlers, prepareNotificationHandlers, and importantly: setSessionFactory (which also means that the sessionid creation cannot be altered, nor the type of the McpServerSession.

In some servers the calling of setSessionFactory wants to be delayed, so that construction/initialization of members (feature contents, prepare method), can be separated from putting the server online by setting the session factory.

Use Case - Extensions

To implement some extensions, such as grouping and primitive update it's necessary to customize the feature set, initialization, factory setting session type and in some cases optionally override methods of McpAsyncServer (e.g. notification sending and contents) (which further need to access currently private members...e.g. list of tools, resources, primitives. With the current permissions, to do this customization would mean having to re-implement McpAsyncServer...outside of it's existing package, which seems like an unnecessary burden on sdk developers.

Also, there have been several unrelated community requests for sdk server extensibility here:

https://github.com/modelcontextprotocol/java-sdk/issues/525

I request that the McpAsyncServer (and other server root classes) be made more extensible by sdk consumers.

I understand that composition might be preferable architecturally, but to allow such composition would currently require a major refactoring and generalization of the server classes, so it seems that making members, constructors, and methods protected might be better in the short term.

Another option for implementing...that would retain binary backward compatibility...would be to introduce abstract super class(es) (for McpAsyncServer) and expose the relevant constructors, members, initialization methods in the abstract super class(es).

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先阅读 McpAsyncServer,尤其是 issue 中提到的 package-private 构造函数以及 prepareRequestHandlers、prepareNotificationHandlers 和 setSessionFactory 入口点。对比其他根服务器类,包括 McpSyncServer 和 McpStateless*,并查看 issue #525 中相关的可扩展性请求。当 SDK 使用者无需重新实现服务器,就可以自定义功能、初始化、会话创建和会话类型,以及相关服务器行为时,即视为完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
java
领域
backend-api-design
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
停滞
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。