使用Hangfire MCP服务器将后台任务入队。
通过使用Hangfire MCP Server与Hangfire进行交互,可以从支持MCP协议的任何客户端入队任务。 例如,您可以在VS Code的代理模式下直接使用Hangfire MCP,并入队任务。这使得无需编写额外代码即可执行任何类型的代码成为可能。
<video src="https://github.com/user-attachments/assets/e6abc036-b1f9-4691-a829-65292db5b5e6" controls="controls"></video>
这是VS Code中的MCP服务器配置:
{
"servers": {
"hangfire-mcp": {
"url": "http://localhost:3001"
}
}
}
这是其工作原理:
sequenceDiagram
participant 用户 as 用户
participant MCPHangfire as MCP Hangfire
participant IBackgroundJobClient as IBackgroundJobClient
participant 数据库 as 数据库
participant HangfireServer as Hangfire 服务器
用户->>MCPHangfire: 入队任务
MCPHangfire->>IBackgroundJobClient: 发送任务消息
IBackgroundJobClient->>数据库: 存储任务消息
HangfireServer->>数据库: 获取任务消息
HangfireServer->>HangfireServer: 处理任务
这是一个作为.NET全局工具打包的常规MCP。这是如何在VSCode中将其设置为MCP服务器的方法。
dotnet tool install --global --add-source Nall.HangfireMCP
配置:
{
"servers": {
"hangfire-mcp-standalone": {
"type": "stdio",
"command": "HangfireMCP",
"args": [
"--stdio"
],
"env": {
"HANGFIRE_JOBS_ASSEMBLY": "path/to/Jobs.dll",
"HANGFIRE_JOBS_MATCH_EXPRESSION": "[?IsInterface && contains(Name, 'Job')]",
"HANGFIRE_CONNECTION_STRING": "Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=hangfire"
}
}
}
}
var builder = DistributedApplication.CreateBuilder(args);
var postgresServer = builder
.AddPostgres("postgres-server")
.WithDataVolume()
.WithLifetime(ContainerLifetime.Persistent);
var postgresDatabase = postgresServer.AddDatabase("hangfire");
builder.AddProject<Projects.Web>("server")
.WithReference(postgresDatabase)
.WaitFor(postgresDatabase);
var mcp = builder
.AddProject<Projects.HangfireMCP_Standalone>("hangfire-mcp")
.WithEnvironment("HANGFIRE_JOBS_ASSEMBLY", "path/to/Jobs.dll")
.WithEnvironment("HANGFIRE_JOBS_MATCH_EXPRESSION", "[?IsInterface && contains(Name, 'Job')]")
.WithReference(postgresDatabase)
.WaitFor(postgresDatabase);
builder
.AddMCPInspector()
.WithSSE(mcp)
.WaitFor(mcp);
builder.Build().Run();
结果是,任务从指定的程序集中动态加载,并可以通过MCP协议入队。可以使用HANGFIRE_JOBS_MATCH_EXPRESSION环境变量来指定匹配任务名称的规则。例如,表达式[?IsInterface && contains(Name, 'Job')]将匹配所有名称中包含“Job”的接口。这是一个JMESPath表达式,因此您可以根据需要定义如何匹配任务名称。
您可以创建自己的MCP服务器,并将此项目作为起点。您可以扩展它以添加自己的工具和功能。这是如何在自定义项目中设置Hangfire MCP服务器的一个示例。
var builder = DistributedApplication.CreateBuilder(args);
var postgresServer = builder
.AddPostgres("postgres-server")
.WithDataVolume()
.WithLifetime(ContainerLifetime.Persistent);
var postgresDatabase = postgresServer.AddDatabase("hangfire");
builder.AddProject<Projects.Web>("server")
.WithReference(postgresDatabase)
.WaitFor(postgresDatabase);
var mcp = builder
.AddProject<Projects.HangfireMCP>("hangfire-mcp")
.WithReference(postgresDatabase)
.WaitFor(postgresDatabase);
builder
.AddMCPInspector()
.WithSSE(mcp)
.WaitFor(mcp);
builder.Build().Run();

var builder = WebApplication.CreateBuilder(args);
builder.WithMcpServer(args).WithToolsFromAssembly();
builder.Services.AddHangfire(cfg => cfg.UsePostgreSqlStorage(options =>
options.UseNpgsqlConnection(builder.Configuration.GetConnectionString("hangfire")))
);
builder.Services.AddHangfireMcp();
builder.Services.AddTransient<HangfireTool>();
var app = builder.Build();
app.MapMcpServer(args);
app.Run();
这是一个Hangfire工具的示例:
[McpServerToolType]
public class HangfireTool(IHangfireDynamicScheduler scheduler)
{
[McpServerTool(Name = "RunJob")]
public string Run(
[Required] string jobName,
[Required] string methodName,
Dictionary<string, object>? parameters = null
)
{
var descriptor = new JobDescriptor(jobName, methodName, parameters);
return scheduler.Enqueue(descriptor, typeof(ITimeJob).Assembly);
}
}
