使用.NET实现自带思考的Tool 并且提供mcp streamable http服务
使用.NET实现自带思考的Tool 并且提供MCP服务
下面我们将使用.net实现自带思考的Tool并且提供mcp streamable http供其他AI客户端使用
创建项目
创建WebAPI项目并且命名MarkAgent.Host名称,然后安装下面的包
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.6" />
<PackageReference Include="ModelContextProtocol" Version="0.3.0-preview.3" />
<PackageReference Include="ModelContextProtocol.AspNetCore" Version="0.3.0-preview.3" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.6" />
<PackageReference Include="Scalar.AspNetCore" Version="1.1.0" />
</ItemGroup>
创建Prompts.cs文件,这里我们会提供系统需要的所有提示词:
namespace MarkAgent.Host;
public class Prompts
{
public const string DeepThinkingPrompt =
"""
Use this tool to engage in deep, structured thinking about complex problems, user requirements, or challenging decisions. This tool helps you process information systematically and provides your thought process back to enhance understanding and decision-making.
## When to Use This Tool
Use this tool proactively in these scenarios:
1. **Complex Problem Analysis** - When facing multi-faceted problems that require careful consideration
2. **Requirement Clarification** - When user requests are ambiguous and need deeper exploration
3. **Decision Points** - When multiple approaches exist and you need to evaluate trade-offs
4. **Architecture Planning** - When designing systems or making technical decisions
5. **Risk Assessment** - When considering potential issues or complications
6. **Learning from Context** - When analyzing existing code or systems to understand patterns
## Core Thinking Principles
1. **Question Assumptions** - Challenge initial interpretations and explore alternatives
2. **Break Down Complexity** - Decompose complex problems into manageable components
3. **Consider Multiple Perspectives** - Look at problems from different angles
4. **Evaluate Trade-offs** - Weigh pros and cons of different approaches
5. **Anticipate Consequences** - Think through potential implications and side effects
6. **Build on Context** - Use existing knowledge and patterns to inform decisions
## Thinking Process Structure
Your thought process should follow this pattern:
1. **Initial Understanding** - What is the core problem or requirement?
2. **Context Analysis** - What relevant information do we have?
3. **Assumption Identification** - What assumptions am I making?
4. **Alternative Exploration** - What other approaches could work?
5. **Trade-off Evaluation** - What are the pros and cons of each option?
6. **Decision Rationale** - Why is this the best approach?
7. **Implementation Considerations** - What practical factors matter?
8. **Risk Assessment** - What could go wrong and how to mitigate?
## Examples of Deep Thinking Scenarios
<example>
User: "I want to add real-time notifications to my app"
Thought Process:
- Initial Understanding: User wants real-time notifications, but what type? Push notifications, in-app notifications, or both?
- Context Analysis: Need to examine existing tech stack, user base size, notification frequency
- Assumptions: Assuming they want both types, but should clarify the specific use cases
- Alternatives: WebSockets, Server-Sent Events, Push API, third-party services
- Trade-offs: WebSockets offer full duplex but require more infrastructure; SSE is simpler but one-way
- Decision: Recommend starting with requirements clarification, then suggest appropriate technology based on their specific needs
- Implementation: Consider scalability, reliability, user preferences
- Risks: Notification fatigue, performance impact, complexity overhead
</example>
<example>
User: "This code is running slowly, can you help optimize it?"
Thought Process:
- Initial Understanding: Performance issue exists, but need to identify bottlenecks
- Context Analysis: Need to examine the code, understand data volumes, usage patterns
- Assumptions: Assuming it's algorithmic complexity, but could be I/O, memory, or network
- Alternatives: Algorithm optimization, caching, database indexing, parallel processing
- Trade-offs: Code complexity vs performance gains, memory usage vs speed
- Decision: Profile first to identify actual bottlenecks before optimizing
- Implementation: Measure performance, implement targeted optimizations
- Risks: Premature optimization, breaking existing functionality, over-engineering
</example>
## Guidelines for Effective Thinking
1. **Be Thorough** - Don't rush to conclusions; explore the problem space fully
2. **Stay Objective** - Consider evidence and logic over preferences
3. **Embrace Uncertainty** - It's okay to acknowledge when you need more information
4. **Think Practically** - Consider real-world constraints and limitations
5. **Document Reasoning** - Clearly explain your thought process and rationale
6. **Iterate and Refine** - Be prepared to revise your thinking as new information emerges
The goal is to provide well-reasoned, thoughtful analysis that leads to better outcomes and helps others understand complex problems more clearly.
""";
public const string SequentialThinkingPrompt =
"""
A detailed tool for dynamic and reflective problem-solving through thoughts.
This tool helps analyze problems through a flexible thinking process that can adapt and evolve.
Each thought can build on, question, or revise previous insights as understanding deepens.
When to use this tool:
- Breaking down complex problems into steps
- Planning and design with room for revision
- Analysis that might need course correction
- Problems where the full scope might not be clear initially
- Problems that require a multi-step solution
- Tasks that need to maintain context over multiple steps
- Situations where irrelevant information needs to be filtered out
You should:
1. Start with an initial estimate of needed thoughts, but be ready to adjust
2. Feel free to question or revise previous thoughts
3. Don't hesitate to add more thoughts if needed, even at the "end"
4. Express uncertainty when present
5. Mark thoughts that revise previous thinking or branch into new paths
6. Ignore information that is irrelevant to the current step
7. Generate a solution hypothesis when appropriate
8. Verify the hypothesis based on the Chain of Thought steps
9. Repeat the process until satisfied with the solution
10. Provide a single, ideally correct answer as the final output
11. Only set next_thought_needed to false when truly done and a satisfactory answer is reached
""";
public const string MentalModelPrompt =
"""
A tool for applying structured mental models to problem-solving.
Supports various mental models including:
- First Principles Thinking
- Opportunity Cost Analysis
- Error Propagation Understanding
- Rubber Duck Debugging
- Pareto Principle
- Occam's Razor
Each model provides a systematic approach to breaking down and solving problems.
""";
}
注意,上面的提示词非常的重要,它会影响Tool的输入效果
然后我们继续,创建ThoughtData.cs
public class ThoughtData
{
public string thought { get; set; } = string.Empty;
public int thoughtNumber { get; set; }
public int totalThoughts { get; set; }
public bool isRevision { get; set; } = false;
public int? revisesThought { get; set; }
public int? branchFromThought { get; set; }
public string? branchId { get; set; }
public bool needsMoreThoughts { get; set; } = false;
public bool nextThoughtNeeded { get; set; } = true;
}
创建MentalModelData.cs
public class MentalModelData
{
public MentalModelName ModelName { get; set; }
public string Problem { get; set; } = string.Empty;
public string[] Steps { get; set; } = [];
public string Reasoning { get; set; } = string.Empty;
public string Conclusion { get; set; } = string.Empty;
}
public enum MentalModelName
{
FirstPrinciples,
OpportunityCost,
ErrorPropagation,
RubberDuck,
ParetoPrinciple,
OccamsRazor,
}
现在我们可以创建AgentTool.cs核心的MCP Tool代码了,这个代码会整合AI入的内容然后反馈给AI。
using System.ComponentModel;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using MarkAgent.Host.Domain.Entities;
using MarkAgent.Host.Domain.Events;
using MarkAgent.Host.Domain.Services;
using MarkAgent.Host.Tools.Models;
using ModelContextProtocol.Server;
namespace MarkAgent.Host.Tools;
[McpServerToolType]
public class AgentTools(IStatisticsChannelService statisticsChannel)
{
[McpServerTool, Description(Prompts.MentalModelPrompt)]
public MentalModelData MentalModel(MentalModelName model, string problem, string[] steps,
string reasoning, string conclusion)
{
// 验证必需字段
if (string.IsNullOrEmpty(problem))
{
throw new ArgumentException("Invalid problem: must be a string", nameof(problem));
}
// 处理可选字段并应用默认值
var processedSteps = steps ?? [];
var processedReasoning = !string.IsNullOrEmpty(reasoning) ? reasoning : "";
var processedConclusion = !string.IsNullOrEmpty(conclusion) ? conclusion : "";
// 创建并返回 MentalModelData 对象
return new MentalModelData
{
ModelName = model,
Problem = problem,
Steps = processedSteps,
Reasoning = processedReasoning,
Conclusion = processedConclusion
};
}
[McpServerTool, Description(Prompts.SequentialThinkingPrompt)]
public ThoughtData SequentialThinking(
string thought,
int thoughtNumber,
int totalThoughts,
bool nextThoughtNeeded,
bool isRevision,
int revisesThought,
int branchFromThought,
string branchId,
bool needsMoreThoughts)
{
// 验证必需字段
if (string.IsNullOrEmpty(thought))
{
throw new ArgumentException("Invalid thought: must be a string", nameof(thought));
}
if (thoughtNumber <= 0)
{
throw new ArgumentException("Invalid thoughtNumber: must be a positive number", nameof(thoughtNumber));
}
if (totalThoughts <= 0)
{
throw new ArgumentException("Invalid totalThoughts: must be a positive number", nameof(totalThoughts));
}
// 处理可选字段 - 在 C# 中这些已经是参数,但我们可以添加额外的验证逻辑
var processedIsRevision = isRevision;
var processedRevisesThought = revisesThought > 0 ? (int?)revisesThought : null;
var processedBranchFromThought = branchFromThought > 0 ? (int?)branchFromThought : null;
var processedBranchId = !string.IsNullOrEmpty(branchId) ? branchId : null;
var processedNeedsMoreThoughts = needsMoreThoughts;
// 创建并返回 ThoughtData 对象
return new ThoughtData
{
thought = thought,
thoughtNumber = thoughtNumber,
totalThoughts = totalThoughts,
nextThoughtNeeded = nextThoughtNeeded,
isRevision = processedIsRevision,
revisesThought = processedRevisesThought,
branchFromThought = processedBranchFromThought,
branchId = processedBranchId,
needsMoreThoughts = processedNeedsMoreThoughts
};
}
[McpServerTool, Description(Prompts.DeepThinkingPrompt)]
public string DeepThinking(
IMcpServer mcpServer,
[Description(
"Your structured thought process about the problem, following the thinking framework provided in the tool description. This should be a detailed analysis that explores the problem from multiple angles.")]
string thought)
{
var startTime = DateTime.UtcNow;
string? errorMessage = null;
bool isSuccess = true;
try
{
// 设置控制台编码支持UTF-8
Console.OutputEncoding = Encoding.UTF8;
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.ResetColor();
Console.WriteLine("─".PadRight(50, '─'));
Console.WriteLine(thought);
Console.WriteLine("─".PadRight(50, '─'));
Console.WriteLine();
// 构建返回给大模型的消息
var responseMessage = BuildThoughtResponseMessage(thought);
return responseMessage;
}
catch (Exception ex)
{
isSuccess = false;
errorMessage = ex.Message;
throw;
}
finally
{
// 记录工具使用统计
var endTime = DateTime.UtcNow;
var inputJson = JsonSerializer.Serialize(new { thought });
var sessionId = mcpServer.SessionId;
// 异步记录统计,不阻塞主流程
_ = Task.Run(async () =>
{
try
{
var toolUsageEvent = new ToolUsageEvent
{
ToolName = "DeepThinking",
SessionId = sessionId ?? string.Empty,
StartTime = startTime,
EndTime = endTime,
IsSuccess = isSuccess,
ErrorMessage = errorMessage,
InputSize = Encoding.UTF8.GetByteCount(inputJson),
OutputSize = 0, // 输出大小在返回时计算
ParametersJson = inputJson
};
await statisticsChannel.WriteToolUsageEventAsync(toolUsageEvent);
}
catch
{
// 忽略统计记录错误,不影响主功能
}
});
}
}
private string BuildThoughtResponseMessage(string thought)
{
var sb = new StringBuilder();
sb.AppendLine(
"Deep thinking process completed successfully. Your structured analysis has been recorded and will inform future decision-making.");
sb.AppendLine();
sb.AppendLine("<system-reminder>");
sb.AppendLine(
"The AI has engaged in deep thinking about the current problem/requirement. Key insights from this analysis:");
sb.AppendLine();
sb.AppendLine($"Thought Process: {thought}");
sb.AppendLine();
sb.AppendLine(
"Use these insights to make more informed decisions and provide better solutions. The thinking process should guide your approach to the problem.");
sb.AppendLine("</system-reminder>");
return sb.ToString();
}
}
在这里我们提供了三个Tool,三个不同的Tool,面向思考方式思考处理都不太一样,然后我们现在对外提供MCP服务,打开我们的Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddMcpServer((options =>
{
options.ServerInfo = new Implementation
{
Name = "MarkAgent",
Version = typeof(Program).Assembly.GetName().Version?.ToString() ?? "1.0.0",
Title = "MarkAgent MCP Server",
};
}))
.WithHttpTransport(options =>
{
options.RunSessionHandler += async (context, serverOptions, arg3) =>
{
try
{
// 获取客户端信息
var ipAddress = context.Connection.RemoteIpAddress?.ToString();
var userAgent = context.Request.Headers.UserAgent.ToString();
// 获取请求客户端信息
var clientName = userAgent;
var clientVersion = serverOptions?.ClientInfo?.Version ?? "0.0.0";
var clientTitle = userAgent;
// 生成会话ID
var sessionId = serverOptions.SessionId;
Console.WriteLine($"Client connected: {clientName} v{clientVersion} (Session: {sessionId[..8]}...)");
await serverOptions.RunAsync();
}
catch (Exception ex)
{
// 记录错误但不影响连接
Console.WriteLine($" Error recording client connection: {ex.Message}");
}
};
})
.WithTools<AgentTools>();
var app = builder.Build();
app.MapMcp("/mcp");
await app.RunAsync();
上面的代码就将我们的Tool加入到了MCP Server当中了,现在我们只需要启动服务即可,然后打开cherry Studio进行测试。
进行链接测试
打开软件以后找到设置,然后点击MCP设置

然后填充json配置

案例:
{
"mcpServers": {
"agent": {
"url": "http://localhost:5157/mcp",
"type":"streamableHttp"
}
}
}
然后点击确定,然后进入MCP并且打开工具我们可以看到下面几个Function

然后现在回到对话界面,并且选择我们添加的MCP

然后我们进行测试发送下面内容,然后测试效果如图
帮我写一篇c#入门教程,请深入思考

当然如果您觉得麻烦我们提供了在线的MCP服务下面是接入的教程:
Trae接入MarkAgent
打开Trae,然后点击功能管理,在右上角

然后点击MCP,在点击手动添加

然后将下面的内容粘贴进去然后点击确认:
{
"mcpServers": {
"agent": {
"url": "http://localhost:5157/mcp",
"type":"streamableHttp"
}
}
}

添加完成以后一共提供了四个Tool,前面三个是用于优化思考,最后面的是Todo 跟Claude Code中的Todo功能是完全一样的,提示词是直接使用了Claude Code的提示词,通过这些Tool,您可以体验非一般的AI!

Copilot接入MarkAgent
先打开您的项目根目录,然后在根目录创建.vscode目录,然后在目录下在创建mcp.json文件,并且填充下面的内容,然后我们现在打开VSCode。
{
"servers": {
"todo": {
"url": "https://agent.mark-chat.chat/mcp",
"type": "http"
}
}
}
点击输入框下面的工具

然后下面提供了我们的Tool了

我们只需要对话即可,在需要的时候AI会自行调用Tool,下面开始您的AI之旅。
Rider接入MarkAgent
打开Rider,然后打开Github Copilot
然后点击输入框左边的工具

然后点击Add MCP Tools

然后填充下面的配置:
{
"servers": {
"todo": {
"url": "https://agent.mark-chat.chat/mcp",
"type": "http"
}
}
}
然后关闭文件,然后我们就可以看到输入框左边显示如图效果:

技术交流群
.NET AI学习交流群 加我备注.NET AI
qq:961090189
使用.NET实现自带思考的Tool 并且提供mcp streamable http服务的更多相关文章
- 带你十天轻松搞定 Go 微服务系列(二)
上篇文章开始,我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分(本文) 用户服务 产品服务 订单服务 支付服务 RPC 服务 ...
- 带你十天轻松搞定 Go 微服务系列(一)
本文开始,我们会出一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建(本文) 服务拆分 用户服务 产品服务 订单服务 支付服务 RPC 服务 Au ...
- 带你十天轻松搞定 Go 微服务系列(三)
序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务(本文) 产品服务 订单服务 支付服务 RPC 服务 Auth ...
- 带你十天轻松搞定 Go 微服务系列(五)
序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务 产品服务 订单服务(本文) 支付服务 RPC 服务 Auth ...
- 带你十天轻松搞定 Go 微服务系列(六)
序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务 产品服务 订单服务 支付服务(本文) RPC 服务 Auth ...
- 带你十天轻松搞定 Go 微服务系列(七)
序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务 产品服务 订单服务 支付服务 RPC 服务 Auth 验证( ...
- 带你十天轻松搞定 Go 微服务系列(八、服务监控)
序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务 产品服务 订单服务 支付服务 RPC 服务 Auth 验证 ...
- 带你十天轻松搞定 Go 微服务系列(九、链路追踪)
序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务 产品服务 订单服务 支付服务 RPC 服务 Auth 验证 ...
- 带你十天轻松搞定 Go 微服务之大结局(分布式事务)
序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务 产品服务 订单服务 支付服务 RPC 服务 Auth 验证 ...
- 使用Eclipse自带Web Service插件(Axis1.4)生成Web Service服务端/客户端
创建一个名字为math的Java web工程,并将WSDL文件拷入该工程中 将Axis所需的jar包拷贝至WebRoot\WEB-INF\lib目录下,这些jar包会自动导入math工程中 一,生成W ...
随机推荐
- SQL 日常练习 (十九)
趁热打铁, 一波 SQL 继续带走 ~~ 虽然是假期, 但我也不想出去逛, 宅着也不想看书和思考人生, 除了做饭, 就更多对着电脑发呆. 时而看了下微信群, 初中小伙伴结合, 祝福寄语 和 随份子 都 ...
- 网络编程:阻塞I/O和线程模型
线程 进程模型在处理用户请求的过程中,进程切换上下文的代价比较高,而,一种轻量级的模型可以处理多用户连接请求,那就是线程模型. 线程(thread)是运行在进程中的一个"逻辑流", ...
- Vue-lazyload实现图片懒加载
前端多半是和页面打交道,我们在进行页面的展示的时候,对于图片过多的页面,为了加速页面加载速度,所以很多时候我们需要将页面内未出现在可视区域内的图片先不做加载,等到滚动到可视区域后再去加载.即需要使用到 ...
- 从零开发Vim-like编辑器(01)起步
前言 Vim和Neovim因其独特的模态编辑和高度可定制化,被列为程序员常用的文本编辑器选项之一,与Sublime Text.VS Code.Emacs等编辑器共同丰富了开发者工具生态.就目前而言,网 ...
- Mybatis - 精巧的持久层框架 - 注解开发深刻理解
Mybaits的注解开发是现代Java项目(特别是Spring Boot项目)中非常主流的开发方式.它能让你摆脱繁琐的XML文件,以一种更"Java-Native"的方式编写数据访 ...
- Linux百度网盘优化三板斧
解决Linux百度网盘CPU占用过高,下载进度卡住,频繁崩溃退出问题. 解决Linux百度网盘CPU占用过高问题 夏天到了,百度网盘下载时conky显示CPU温度飙升到99摄氏度,风扇嗷嗷叫,但CPU ...
- Golang基础笔记九之方法与接口
本文首发于公众号:Hunter后端 原文链接:Golang基础笔记九之方法与接口 本篇笔记介绍 Golang 里方法和接口,以下是本篇笔记目录: 方法 接口 用结构体实现类的功能 1.方法 首先介绍一 ...
- 长安车机安装三方APP
前言 长安车机目前为基于安卓自研的系统. 目前 默认这个车机系统,不允许安装三方软件,具体表现为:插入u盘识别不出里边的apk文件. 自带的软件版本都特别低,且不支持升级,只能等待整个车机系统连带升级 ...
- react发布一个组件库 系列篇(一)
前言 经常使用别人写好的组件库,然后安装引入使用即可.比如: npm install beautiful-table import BeautifulTable from 'beautiful-tab ...
- 前端开发系列089-Node篇之os
一.OS模块介绍 Node中的OS模块提供了和当前系统相关的一系列实用方法.在代码中可以直接用os = require("os")的方式来引入.OS模块本身非常的简单,本文将简单对 ...