使用.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 ...
随机推荐
- TVM Pass优化 -- 算子融合(FuseOps)
定义 算子融合 就是将多个计算单元合并到一个计算单元里完成计算,减少中间数据读写内存的操作,从而节省计算时间. TVM中将算子融合分为四种: kElemWise:两个tensor之间按照元素逐个操作的 ...
- 会用 AI 的工程师,效率已经拉开差距了 - “ 我们曾经引以为傲的编码能力,正在被改写。”
最近尝试用Cursor做了几个内部业务系统,发现一个越来越明显的趋势 真正会用 AI 的工程师,效率已经拉开差距了. 做了十几年 Java, 这波 AI 编程浪潮来得快,一开始我也没太当回事,以为这波 ...
- 我的Vue之旅(2)
2020-10-22 仿照教程动手搞了一个Vue的组件化构建应用的Demo, 嗯,对,就是仿照,我一点都不觉得可耻.关于Vue组件化给我的感觉就是自己写一些 类似于HTML中的 h1, a, p这样的 ...
- [2025五一lyyz集训] 数论+练习赛
一如既往地在 \(lyyz\) 集训. 5.1 今天是练习赛,但感觉今天不适合打比赛,交几道挂几道,被教练一顿凶. 练习赛结果:\(100+26+62+22\) 其中有道 \(DP\) 不错: C密码 ...
- Spring Boot中使用注解实现简单工厂模式
前言 从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫静态工厂模式(Simple Factory Pattern),但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出接 ...
- Spring注解之@Autowired:装配构造函数和属性
在User类中创建一个构造函数,传入参数student: import org.springframework.beans.factory.annotation.Autowired; import o ...
- Java 生成随机字符串的六种方法
目录 前言 生成随机字符串 结束语 Reference 一套优秀的随机字符串生成机制不仅需要确保全局唯一性,还需要考虑到性能等问题.翻看了之前写过的一篇生成三位整数随机数的博文<Java 生成三 ...
- Lecture 1 NN,KNN
INT305 Machine Learning Lecture 1 Outline of this course ·Suprevised Learning Nearest Neighbors 近邻 D ...
- 谷歌浏览器 与 C# 4种嵌入浏览器 从 兼容性、性能、高级特性 方面的表现比对
CS架构 Web具有非常强大且友好的开发生态,在CS架构的窗口程序中嵌入浏览器,有哪些好处呢? 1,能够极大丰富程序的表现形式 2,能够充分地利用web的跨平台特性 3,能够使用web更现代更丰富 ...
- Windows 下安装RabbitMQ
下载并安装erlang原因:RabbitMQ服务端代码是使用并发式语言Erlang编写的,安装Rabbit MQ的前提是安装Erlang.下载地址:http://www.erlang.org/down ...