Skip to content
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3c528be
增加采样功能
walterlv Apr 3, 2026
57c1d0b
简化代码,添加采样功能的单元测试
walterlv Apr 3, 2026
c1f4f2f
添加人工测试的 MCP 采样工具
walterlv Apr 3, 2026
27efe1b
解决采样协议不被客户端认识的问题
walterlv Apr 3, 2026
c432af1
整理采样异常
walterlv Apr 3, 2026
e56fb0a
调整一些代码
walterlv Apr 7, 2026
b069d80
处理审查
walterlv Apr 7, 2026
e2c67fe
处理审查
walterlv Apr 7, 2026
da9028c
整理传输层读取请求或响应的分支
walterlv Apr 7, 2026
3db477f
避免不应该的双语注释
walterlv Apr 7, 2026
694a602
添加更多的调试日志
walterlv Apr 8, 2026
9acc4e6
兼容 MCP Inspector 的采样拒绝
walterlv Apr 8, 2026
3010535
记录客户端错误
walterlv Apr 8, 2026
e2eba44
修复指令中的协议版本
walterlv Apr 8, 2026
8dceafe
AI 增加的屎山代码:修复 SSE 消息流向
walterlv Apr 8, 2026
733ca8c
简化传输层的实现
walterlv Apr 8, 2026
c6292f6
处理遗留的双语问题
walterlv Apr 8, 2026
10002e6
重构以简化传输层的代码
walterlv Apr 8, 2026
128aa76
更新文档记录
walterlv Apr 8, 2026
5963987
处理审查意见
walterlv Apr 8, 2026
52670d8
处理审查意见
walterlv Apr 8, 2026
4b18f12
处理审查意见
walterlv Apr 8, 2026
3933fbe
处理审查意见
walterlv Apr 8, 2026
19a5117
处理审查意见:修复并发竞态、重复请求ID、SSE心跳、以及初始化请求分类等问题
Copilot Apr 8, 2026
c96610f
调整心跳时间
walterlv Apr 8, 2026
9888474
处理审查意见:协议版本运算符比较、SSE并发写互斥、重复请求ID、双语注释、ToArray优化
Copilot Apr 8, 2026
11e92fb
处理审查意见
walterlv Apr 8, 2026
a855395
修复 ServerTransportManager:PipeReader 资源释放和大小写不敏感属性查找
Copilot Apr 9, 2026
00bed63
使用更简单的 JsonElement,不需要 PipeReader
walterlv Apr 9, 2026
71549d1
我觉得没必要为了这个不规范的写法浪费性能
walterlv Apr 9, 2026
52f6e76
处理审查意见
walterlv Apr 9, 2026
0710443
添加辅助传输层日志记录的类(避免日志打太多)
walterlv Apr 9, 2026
9b5cd10
统一使用受管理的传输层原始日志记录,避免日志大幅影响控制台输出
walterlv Apr 9, 2026
bbb20b0
尝试消除竞态条件
walterlv Apr 9, 2026
3ba6c05
为 GET 添加日志
walterlv Apr 9, 2026
6032afa
记录更详细的原始日志
walterlv Apr 10, 2026
b2f9f65
ToString 可以输出文本内容
walterlv Apr 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ src/DotNetCampus.ModelContextProtocol/
- 代码主要以最新版本协议进行编写
- 遇到需要兼容旧协议的部分,用 `Legacy` 命名相关代码并尽量减少代码量
- **协议消息类型规范**:详见 [/docs/knowledge/protocol-messages-guide.md](../docs/knowledge/protocol-messages-guide.md)
- 所有 Protocol 消息类型必须添加中英双语注释
- **仅** `Protocol/` 文件夹下的消息类型必须添加中英双语注释;其他所有代码(接口、实现类、传输层等)一律使用**纯中文注释**(注:当前存在一些遗留非协议代码仍使用双语注释,如果改到了相关代码,请顺手改为纯中文注释)
- 英文注释必须使用 MCP 官方 Schema 原文
- 当前使用协议版本:**2025-11-25**
- Schema 文件:[schema.ts](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2025-11-25/schema.ts)
Expand Down Expand Up @@ -75,8 +75,9 @@ src/DotNetCampus.ModelContextProtocol/

## 参考资源

- [MCP 官方规范 (2025-06-18)](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports) - **当前使用版本**
- [MCP Schema (2025-06-18)](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2025-06-18/schema.ts) - **官方消息类型定义**
- [MCP 官方规范 (2025-11-25)](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports) - **当前使用版本**
- [MCP Schema (2025-11-25)](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2025-11-25/schema.ts) - **官方消息类型定义**
- [MCP 官方规范 (2025-06-18)](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports) - 旧版本(兼容支持)
- [MCP 官方规范 (2024-11-05)](https://modelcontextprotocol.io/specification/2024-11-05/basic/transports) - 旧版本(兼容支持)
- [JSON-RPC 2.0 规范](https://www.jsonrpc.org/specification)
- [SSE 标准](https://html.spec.whatwg.org/multipage/server-sent-events.html)
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ internal class Program
.WithTool(() => new SampleTools2())
)
// Use Streamable HTTP transport, listening on http://localhost:5943/mcp
// Also compatible with SSE, listening on http://localhost:5943/mcp/sse
.WithLocalHostHttp(5943, "mcp")
// You can also use stdio (standard input/output) transport, which is recommended by the MCP protocol for all MCP servers
// However, it's generally not recommended to enable both http and stdio simultaneously,
Expand Down
1 change: 0 additions & 1 deletion docs/en/QuickStart.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ internal class Program
.WithTool(() => new SampleTools2())
)
// Use Streamable HTTP transport, listening on http://localhost:5943/mcp
// Also compatible with SSE, listening on http://localhost:5943/mcp/sse
.WithLocalHostHttp(5943, "mcp")
// You can also use stdio (standard input/output) transport, which is recommended by the MCP protocol for all MCP servers
// However, it's generally not recommended to enable both http and stdio simultaneously,
Expand Down
56 changes: 28 additions & 28 deletions docs/knowledge/http-server-transport-implementation-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,20 @@
* 反序列化 Body 为 `JsonRpcMessage`。
* 将消息通过 `OnMessageReceived` 传递给上层 MCP Server 处理。
6. **响应写入**:
* **情况 1:上层有直接同步返回 (Response)**:
* **`initialize` 请求**:
* 设置 `Content-Type: application/json`。
* 写入响应 JSON。
* 返回 `200 OK`。
* **情况 2:上层无直接返回 (Notification) 或 异步处理**:
* 返回 `202 Accepted`。
* 无 Body。
* *高级情况:SSE 升级*(如果 POST 请求 accept SSE 且 Server 决定用 SSE 回复):
* 设置 `Content-Type: text/event-stream`。
* 保持连接并在稍后推送 SSE Event。
* *建议:简单起见,POST 尽量使用 application/json 回复,推送信道留给 GET SSE。*
* **`JsonRpcResponse`(客户端回弹采样结果)**:
* 返回 `202 Accepted`,无 Body。
* **`JsonRpcNotification`(客户端发送的通知)**:
* 返回 `202 Accepted`,无 Body。
* **所有其他 `JsonRpcRequest`(工具调用等)**:
* 设置 `Content-Type: text/event-stream`,建立本次请求的专属 SSE 流。
* 先发送一个空注释事件(prime event)保活。
* 将此 SSE 流绑定到当前 Session(供采样等服务端主动请求使用)。
* 调用 `HandleRequestAsync` 处理请求(期间采样请求将写入此 SSE 流)。
* 将最终响应写入 SSE 流,关闭流。

### C. 处理 GET 请求 (SSE Subscription)

Expand All @@ -84,17 +87,11 @@
* 设置响应 Header `Content-Type: text/event-stream`。
* 设置 `Cache-Control: no-cache`。
* 返回 `200 OK`(此时不要关闭 Response 流)。
4. **注册发送通道**:
* 将当前 HTTP Response 流包装为一个 `IAsyncWriter` 或类似接口。
* 注册到 Session 对象中,作为服务端向客户端推送消息的通道(Server-to-Client Messenger)。
* **多连接共存策略**:MCP 协议规范 §2.3.1 明确指出 *“The client MAY remain connected to multiple SSE streams simultaneously.”*。因此,服务端**应支持**每个 Session 维护一个活跃连接列表,并将消息广播到所有连接(或仅主连接)。
* *实现简化建议*:遵循协议精神,服务端应允许新连接加入而不强制断开旧连接。
5. **发送 Prime Event**:
* 立即发送一个空事件 `event: message\ndata: \n\n` 或仅 `:\n\n` (Comment) 以保活。
* 根据 SSE 规范,发送 `id` 字段以支持重连。
6. **保持循环**:
* 进入 `await Task.Delay(-1)` 或等待 Session 关闭信号。
* 在循环中捕获异常,如果连接断开,从 Session 中注销此通道。
4. **发送 Prime Event**:
* 立即发送一个空注释 `:\n\n` 以保活连接。
5. **保持循环**:
* 进入 `await Task.Delay(-1)` 等待,保持 SSE 连接存活(此通路用于未来扩展服务端主动推送,当前暂不发送任何业务消息)。
* 在循环中捕获异常,如果连接断开则正常退出。

### D. 处理 DELETE 请求 (Session Termination)

Expand Down Expand Up @@ -125,22 +122,25 @@

## 4. 关键数据结构:Session Store

需要一个线程安全的 `ConcurrentDictionary<string, HttpServerSession>`。
需要一个线程安全的 `ConcurrentDictionary<string, HttpServerTransportSession>`。

**`HttpServerSession` 类职责**:
**`HttpServerTransportSession` 类职责**:
* 存储 Session ID。
* 管理 SSE 发送通道(也就是当前挂着的那个 GET Response 流)。
* 提供 `SendMessageAsync(JsonRpcMessage)` 方法:将消息序列化为 SSE 格式 (`event: message\ndata: {...}\n\n`) 并写入流。
* 和待决服务端请求的 TCS 字典(继承自 `ServerTransportSession` 基类)。
* 管理当前 POST 请求的专属 SSE 输出流(`_currentRequestSseStream`),这是采样等服务端主动请求的通道。
* 提供 `WriteSseMessageAsync(Stream, JsonRpcMessage)` 方法:将消息序列化为 SSE 格式 (`event: message\ndata: {...}\n\n`) 并写入流。

## 5. 错误处理

* **JSON 序列化错误**:返回 400。
* **内部异常**:返回 500,并在 Body 中包含(或不包含)JSON-RPC Error。

## 6. 待办事项 (Checklist)
## 6. 实现状态 (Checklist)

* [ ] 移除旧版兼容代码 (`/mcp/sse`, `/mcp/messages` 路径处理)。
* [ ] 确保 POST/GET/DELETE 共用同一个 Endpoint URL。
* [ ] 实现 Session ID 的生成(初始化时)和校验(后续请求)。
* [ ] 实现 SSE 的心跳或 Keep-Alive(如果底层不自动处理)。
* [x] POST/GET/DELETE 共用同一个 Endpoint URL `/mcp`。
* [x] Session ID 的生成(initialize 时)和校验(后续请求)。
* [x] 非 initialize 的 POST 请求返回 `text/event-stream`,套接 sampling 等服务端主动请求通道。
* [x] 初始化请求返回 `application/json`。
* [x] SSE prime event 保活连接。
* [ ] 旧版协议兼容 (`/mcp/sse`, `/mcp/messages`)(目前未实现)。

40 changes: 22 additions & 18 deletions docs/knowledge/http-transport-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
| **最新** | 2025-11-25 | Streamable HTTP | `/mcp` | `Mcp-Session-Id` header | ✅ 已支持 |
| | 2025-06-18 | Streamable HTTP | `/mcp` | `Mcp-Session-Id` header | ✅ 已支持 |
| **变更** | 2025-03-26 | Streamable HTTP | `/mcp` | `Mcp-Session-Id` header | ✅ 已支持 |
| **旧协议** | 2024-11-05 | HTTP+SSE | `/mcp/sse`, `/mcp/messages` | query string `sessionId` | ✅ 兼容 |
| **旧协议** | 2024-11-05 | HTTP+SSE | `/mcp/sse`, `/mcp/messages` | query string `sessionId` | ❌ 未实现 |

> **说明**: 2025-11-25、2025-06-18 和 2025-03-26 在传输层上完全兼容,我们的实现同时支持这些版本。
> **说明**: 2025-11-25、2025-06-18 和 2025-03-26 在传输层上完全兼容,我们的实现同时支持这些版本。旧版 HTTP+SSE 协议(2024-11-05)目前未实现,如有需要请提 issue。

## 🔑 关键区别

Expand Down Expand Up @@ -70,26 +70,30 @@ endpoint.Equals(EndPoint, StringComparison.OrdinalIgnoreCase)

## 📁 代码组织

```csharp
#region 新协议实现 (Streamable HTTP - 2025-03-26+)
// HandleSseConnectionAsync()
// HandleJsonRpcRequestAsync()
// HandleDeleteSessionAsync()
#endregion

#region 旧协议兼容 (HTTP+SSE - 2024-11-05)
// HandleLegacySseConnectionAsync() // 带 Legacy 前缀
// HandleLegacyMessageRequestAsync()
#endregion
POST 处理逻辑被拆分为职责单一的方法(LocalHost 和 TouchSocket 两版结构完全对称):

```
HandlePostRequestAsync(入口)
├── HandleClientResponseAsync // 客户端响应服务端采样请求(JsonRpcResponse)
├── HandleNotificationAsync // 通知消息,返回 202 Accepted
└── HandleRpcRequestAsync // JSON-RPC 请求
├── GetOrCreateSessionAsync // Session 查找/创建
├── HandleInitializeAsync // initialize:返回 application/json
└── HandleSseRequestAsync // 其他请求:返回 text/event-stream SSE
```

> **POST 响应规则**:
> - `initialize` 请求 → `Content-Type: application/json`,直接返回
> - 所有其他 JSON-RPC 请求 → `Content-Type: text/event-stream`,
> 采样等服务端发起的消息在此流上推送,最终响应也写入此流后关闭

## ✅ 测试清单

- [ ] 新协议:POST `/mcp` 返回 `Mcp-Session-Id`
- [ ] 新协议:GET `/mcp` 建立 Streamable HTTP 连接
- [ ] 新协议:DELETE `/mcp` 成功终止会话
- [ ] 旧协议:GET `/mcp/sse` 发送 endpoint 事件
- [ ] 旧协议:POST `/mcp/messages?sessionId=xxx` 正常工作
- [x] 新协议:POST `/mcp` initialize 返回 `Mcp-Session-Id`(`application/json`)
- [x] 新协议:POST `/mcp` 工具调用返回 `text/event-stream` SSE 流
- [x] 新协议:GET `/mcp` 建立 SSE 保活连接
- [x] 新协议:DELETE `/mcp` 成功终止会话
- [x] 采样(Sampling):服务端通过 POST 响应 SSE 流发起采样请求,客户端 POST 回采样结果
- [ ] 路径大小写不敏感
- [ ] 会话不存在时 DELETE 返回 200 OK(幂等性)

Expand Down
44 changes: 31 additions & 13 deletions docs/knowledge/test-cases.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,24 @@
| 状态 | 方法名 | 场景描述 | 预期行为 |
| :---: | :--- | :--- | :--- |
| ✅ | `Delete_TerminateSession` | `LocalHost`, `TouchSocket` | DELETE 请求成功终止会话,IsConnected 为 false |
| ⏳ | `Post_NoSessionId` | 不带 `sessionId` query 发送消息 | 返回 400 Bad Request 或相应错误 |
| ⏳ | `Sse_EndpointEvent` | 建立旧协议 SSE 连接 | 首先收到 `event: endpoint` 消息 |
| ⏳ | `Post_NoSessionId` | 不带 `Mcp-Session-Id` header 发送消息 | 返回 400/404 错误 |
| ⏳ | `Sse_EndpointEvent` | GET SSE 连接 | SSE 流成功建立并保活 |

---

## 3. 官方兼容性测试 (Compliance)
## 3.5 采样功能测试 (Sampling)

**文件路径**: `tests/DotNetCampus.ModelContextProtocol.Tests/Servers/SamplingTests.cs`
**目标**: 验证服务器向客户端发起 `sampling/createMessage` 请求的完整流程。

| 状态 | 方法名 | DataRow / 参数 | 预期行为 |
| :---: | :--- | :--- | :--- |
| ✅ | `ServerToolCanRequestSampling` | `LocalHost`, `TouchSocket` | 工具内调用 Sampling,客户端处理器被执行,返回结果正确 |
| ✅ | `IsSupportedIsFalseWhenClientHasNoCapability` | `LocalHost`, `TouchSocket` | 客户端未声明 Sampling 能力时 IsSupported 为 false |

---

## 4. 官方兼容性测试 (Compliance)

**文件路径**: `tests/DotNetCampus.ModelContextProtocol.Tests/Compliance/OfficialServerTests.cs`
**目标**: 启动真正的 Node.js MCP Server 验证本库 Client。
Expand All @@ -109,9 +121,9 @@

---

## 4. 已实现的辅助工具
## 5. 已实现的辅助工具

### 4.1 测试工具 (Test Tools)
### 5.1 测试工具 (Test Tools)
**文件路径**: `tests/DotNetCampus.ModelContextProtocol.Tests/McpTools/`

| 文件 | 类名 | 工具方法 | 用途 |
Expand All @@ -121,32 +133,37 @@
| `ExceptionTool.cs` | `ExceptionTool` | `ThrowError(string? message)`, `ThrowNested()` | 异常处理测试 |
| `LongTextTool.cs` | `LongTextTool` | `Generate(int length)` | 大数据量测试 |
| `SimpleTool.cs` | `SimpleTool` | `SayHello()` | 最简单的工具 |
| `StatefulCounterTool.cs` | `StatefulCounterTool` | `Increment()`, `GetCount()` | 有状态工具实例语义测试 |
| `InjectedConstructorTool.cs` | `InjectedConstructorTool` | 注入构造函数工具 | 依赖注入测试 |
| `SamplingTool.cs` | `SamplingTool` | `AskLlm(string message, ...)`, `CheckSamplingCapability(...)` | 服务端发起采样请求测试 |

### 4.2 测试资源 (Test Resources)
### 5.2 测试资源 (Test Resources)
**文件路径**: `tests/DotNetCampus.ModelContextProtocol.Tests/McpResources/`

| 文件 | 类名 | 资源方法 | 用途 |
| :--- | :--- | :--- | :--- |
| `SimpleResource.cs` | `SimpleResource` | `TextFile()`, `BinaryImage()`, `UserProfile(int userId)` | 基本资源访问测试 |

### 4.3 测试工厂 (Integration Factory)
### 5.3 测试工厂 (Integration Factory)
**文件路径**: `tests/DotNetCampus.ModelContextProtocol.Tests/TestMcpFactory.cs`

| 方法 | 用途 |
| :--- | :--- |
| `CreateSimpleHttpAsync(HttpTransportType)` | 创建仅包含 SimpleTool 的测试包 |
| `CreateFullHttpAsync(HttpTransportType)` | 创建包含所有测试工具的测试包 |
| `CreateFullHttpWithResourcesAsync(HttpTransportType)` | 创建包含工具和资源的完整测试包 |
| `CreateHttpCoreAsync(HttpTransportType, Action<McpServerBuilder>)` | 完全自定义的测试包创建 |
| `CreateTransientCounterHttpAsync(HttpTransportType)` | 创建仅包含 Transient 计数工具的测试包 |
| `CreateHttpAsync(HttpTransportType, Action<...>)` | 自定义工具的测试包 |
| `CreateHttpCoreAsync(HttpTransportType, Action<McpServerBuilder>, Action<McpClientBuilder>?)` | 完全自定义,支持同时配置服务端和客户端(如配置 Sampling Handler) |

### 4.4 JSON 序列化上下文
### 5.4 JSON 序列化上下文
**文件路径**: `tests/DotNetCampus.ModelContextProtocol.Tests/McpTools/TestToolJsonContext.cs`

用于 AOT 兼容的复杂对象序列化,包含 `EchoUserInfo` 等类型的注册。

---

## 5. 待开发的辅助工具
## 6. 待开发的辅助工具

1. **Mock Transport**
* `InProcessServerTransport` / `InProcessClientTransport`
Expand All @@ -157,11 +174,12 @@

---

## 6. 测试统计
## 7. 测试统计

| 类别 | 通过 | 跳过 | 规划 |
| :--- | :---: | :---: | :---: |
| 核心功能测试 | 28 | 2 | 2 |
| 传输层测试 | 6 | 3 | 4 |
| 传输层测试 | 6 | 2 | 2 |
| 采样功能测试 | 4 | 0 | 0 |
| 官方兼容性测试 | 0 | 3 | 0 |
| **总计** | **34** | **8** | **6** |
| **总计** | **38** | **7** | **4** |
3 changes: 1 addition & 2 deletions docs/zh-hans/QuickStart.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ internal class Program
.WithTool(() => new SampleTools())
.WithTool(() => new SampleTools2())
)
// 传输层使用 Streamable HTTP,监听 http://localhost:5943/mcp,
// 传输层同时兼容 SSE,监听地址为 http://localhost:5943/mcp/sse
// 传输层使用 Streamable HTTP,监听 http://localhost:5943/mcp
.WithLocalHostHttp(5943, "mcp")
// 传输层也可使用 stdio(标准输入输出),这是 MCP 协议建议所有 MCP 服务器都支持的传输层
// 不过通常不建议同时启用 http 和 stdio,因为前者通常要求单例运行,后者则必须支持多实例运行
Expand Down
53 changes: 53 additions & 0 deletions samples/DotNetCampus.SampleMcpServer/McpTools/SamplingTool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using DotNetCampus.ModelContextProtocol.CompilerServices;
using DotNetCampus.ModelContextProtocol.Exceptions;
using DotNetCampus.ModelContextProtocol.Protocol.Messages;
using DotNetCampus.ModelContextProtocol.Servers;

namespace DotNetCampus.SampleMcpServer.McpTools;

public class SamplingTool
{
/// <summary>
/// 通过客户端的 LLM 进行采样,将 prompt 发送给客户端,获取 LLM 响应并返回。
/// 用于人工验证 sampling/createMessage 协议流程是否正常。
/// </summary>
/// <param name="context">MCP 工具上下文</param>
/// <param name="prompt">发送给 LLM 的提示词</param>
/// <param name="maxTokens">最大生成令牌数</param>
/// <param name="systemPrompt">可选的系统提示词</param>
[McpServerTool]
public async Task<string> AskLlm(
IMcpServerCallToolContext context,
string prompt,
int maxTokens = 1024,
string? systemPrompt = null)
{
if (!context.Sampling.IsSupported)
{
throw new McpToolException("当前客户端未声明 Sampling 能力。请确保客户端支持 sampling/createMessage 请求。");
}

try
{
var result = await context.Sampling.CreateMessageAsync(prompt, maxTokens, systemPrompt, context.CancellationToken);

var responseText = result.Content switch
{
TextContentBlock text => text.Text,
_ => $"[Non-text content: {result.Content?.GetType().Name}]",
};

return $"""
Model: {result.Model}
StopReason: {result.StopReason ?? "unknown"}
Role: {result.Role}
---
{responseText}
""";
}
catch (McpSamplingRejectedException ex)
{
throw new McpToolException($"采样请求被用户拒绝。Sampling request was rejected by the user. Code: {ex.ErrorCode}, Message: {ex.RejectionMessage}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace DotNetCampus.SampleMcpServer.McpTools;

public class SampleTool
public class SimpleTool
{
/// <summary>
/// 用于给 AI 调试使用的工具,原样返回一些信息
Expand Down
3 changes: 2 additions & 1 deletion samples/DotNetCampus.SampleMcpServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ private static async Task Main(string[] args)
.WithRequestHandlers(s => new CustomRequestHandlers(s))
.WithJsonSerializer(McpToolJsonContext.Default)
.WithTools(t => t
.WithTool(() => new SampleTool())
.WithTool(() => new SimpleTool())
.WithTool(() => new InputTool())
.WithTool(() => new OutputTool())
.WithTool(() => new PolymorphicTool())
.WithTool(() => new ResourceTool())
.WithTool(() => new SamplingTool())
)
.WithResources(r => r
.WithResource(() => new SampleResource())
Expand Down
Loading
Loading