当前位置: 首页 > news >正文

使用.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 Principles1. **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 StructureYour 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 Thinking1. **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 emergesThe 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 outYou 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 RazorEach 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-8Console.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;// 生成会话IDvar 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设置
image

然后填充json配置
image

案例:

{"mcpServers": {"agent": {"url": "http://localhost:5157/mcp","type":"streamableHttp"}}
}

然后点击确定,然后进入MCP并且打开工具我们可以看到下面几个Function
image

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

然后我们进行测试发送下面内容,然后测试效果如图

帮我写一篇c#入门教程,请深入思考

image

当然如果您觉得麻烦我们提供了在线的MCP服务下面是接入的教程:

Trae接入MarkAgent

打开Trae,然后点击功能管理,在右上角
image

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

然后将下面的内容粘贴进去然后点击确认:

{"mcpServers": {"agent": {"url": "http://localhost:5157/mcp","type":"streamableHttp"}}
}

image

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

Copilot接入MarkAgent

先打开您的项目根目录,然后在根目录创建.vscode目录,然后在目录下在创建mcp.json文件,并且填充下面的内容,然后我们现在打开VSCode。

{"servers": {"todo": {"url": "https://agent.mark-chat.chat/mcp","type": "http"}}
}

点击输入框下面的工具

image

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

我们只需要对话即可,在需要的时候AI会自行调用Tool,下面开始您的AI之旅。

Rider接入MarkAgent

打开Rider,然后打开Github Copilot

然后点击输入框左边的工具
image

然后点击Add MCP Tools
image

然后填充下面的配置:

{"servers": {"todo": {"url": "https://agent.mark-chat.chat/mcp","type": "http"}}
}

然后关闭文件,然后我们就可以看到输入框左边显示如图效果:

image

技术交流群

.NET AI学习交流群 加我备注.NET AI

qq:961090189

http://www.sczhlp.com/news/1401/

相关文章:

  • aaPanel 设置加 ThinkPHP 伪静态代码
  • 5. Warp and Bank
  • WiFiManager 项目
  • 5. Coalesced and Uncoalesced
  • 第八天
  • 【AI语音-小智】xiaozhi-esp32实现源码分析
  • 【笔记】Visual Studio 2022 入门指南
  • Visual Studio 2022 入门指南
  • 20250729 之所思 - 人生如梦
  • 2025牛客暑期多校训练营5
  • 【esp32-s3】如何进行WiFi配网
  • 【ESP8266】小电视项目进展记录
  • 【LeetCode 138】力扣算法:随机链表的复制
  • Rocky Linux使用nginx时启用图片压缩
  • 7.29随笔
  • kali安装maven-cnblog
  • 【ESP8266】模组对比(ESP-12F)以及拆盖图
  • log4j2 远程代码执行漏洞复现(CVE-2021-44228)-cnblog
  • 第四天
  • Luogu-P3455 [POI 2007] ZAP-Queries
  • PDF转Word免费工具!批量处理PDF压缩,合并, OCR识别, 去水印, 签名等全功能详解
  • npm构建公共组件库
  • 空间复杂度 O(1) 解决力扣的困难算法:k个一组翻转链表
  • HotSpot虚拟机对象探秘
  • 6
  • 【设计模式】创建者模式——1.简单工厂模式
  • 智谱 GLM-4.5 也支持了Claude Code
  • 做题记录
  • 若依
  • Rust 性能优化秘籍:write! 宏让字符串构建提速 75%