使用.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
浙公網安備 33010602011771號