任务调度MCP服务器

一个支持通过cron表达式调度和执行Claude Code CLI任务的单文件MCP服务器,提供Web仪表盘、Webhook支持、动态MCP服务器创建及令牌/成本追踪功能。

  • by floriansmeyers
  • Python
  • 本地部署
  • 24 星标
  • 更新于
在 GitHub 查看 floriansmeyers/SFLOW-AIRunner-MCP-PRD

使用说明

Claude Runner-带作业调度的MCP服务器

一个单文件MCP服务器,通过cron表达式调度和执行Claude Code CLI任务。具有web仪表板、webhook支持、动态MCP服务器创建和令牌/成本跟踪功能。

先决条件

  • Python 3.11+ (需要 asyncio.timeout())
  • Claude代理SDK (pip install claude-agent-sdk)
  • SQLite3 (通常预装在macOS/Linux上)
  • 无烟煤API键 -作业通过Claude Agent SDK执行,这需要 ANTHROPIC_API_KEY. 不要依赖个人Max/Pro订阅 -SDK需要来自的API密钥 console.anthropic.com。将其设置在您的环境中或 .env 文件:
    export ANTHROPIC_API_KEY=sk-ant-...
    

快速开始

# Clone the repository
git clone https://github.com/floriansmeyers/SFLOW-AIRunner-MCP-PRD.git
cd SFLOW-AIRunner-MCP-PRD

# Create and activate virtual environment
python3 -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Run the server (stdio transport for Claude Desktop)
python server.py

首次运行时,服务器将:

  1. 创建 jobs.db 带所有表的SQLite数据库
  2. 自动生成OAuth凭据(打印到stderr-保存这些!)
  3. 启动调度程序循环(每60秒检查一次)

跑步

本地(stdio传输-适用于Claude Desktop)

python server.py

添加到Claude桌面配置(~/Library/Application Support/Claude/claude_desktop_config.json 在macOS上):

{
  "mcpServers": {
    "claude-runner": {
      "command": "/path/to/SFLOW-AIagents-MCP-Spinner/.venv/bin/python",
      "args": ["/path/to/SFLOW-AIagents-MCP-Spinner/server.py"]
    }
  }
}

重要提示: 使用Python解释器的完整路径 .venv 以确保依赖关系可用。

远程(SSE传输-用于web仪表板)

MCP_TRANSPORT=sse python server.py
# Server accessible at http://localhost:8080
# Web dashboard at http://localhost:8080/

两种运输方式

MCP_TRANSPORT=both python server.py
# stdio for Claude Desktop + SSE for web dashboard

环境变量

变量 必填 默认 描述
ANTHROPIC_API_KEY 是 - 来自的API密钥 console.anthropic.com --通过Claude Agent SDK执行作业所需。不要使用个人Max/Pro订阅。
MCP_TRANSPORT 没有 both 运输方式: stdio, sse,或 both
OAUTH_CLIENT_ID 否 自动生成 OAuth客户端ID
OAUTH_CLIENT_SECRET 否 自动生成 OAuth客户端密钥
OAUTH_SECRET_KEY 无 自动生成 用于签名JWT令牌的密钥
DASHBOARD_USERNAME 否 - 仪表板的基本身份验证用户名
DASHBOARD_PASSWORD 否 - 仪表板的基本身份验证密码
NGROK_AUTHTOKEN 没有用于远程隧道的 - ngrok身份验证令牌
PUBLIC_URL 否 - 覆盖OAuth回调的基本URL(例如。, https://your-domain.com)

创建 .env 文件以持久化这些内容:

ANTHROPIC_API_KEY=sk-ant-...
OAUTH_CLIENT_ID=your_client_id
OAUTH_CLIENT_SECRET=your_client_secret
OAUTH_SECRET_KEY=your_secret_key
DASHBOARD_USERNAME=admin
DASHBOARD_PASSWORD=secure_password
NGROK_AUTHTOKEN=your_ngrok_token

身份验证(OAuth 2.1)

SSE传输需要OAuth 2.1身份验证。首次启动时,服务器会自动生成凭据并将其打印到stderr:

============================================================
OAUTH CREDENTIALS FOR CLAUDE CONNECTOR
============================================================
Client ID:     abc123...
Client Secret: xyz789...

Save these to your .env file:
  OAUTH_CLIENT_ID=abc123...
  OAUTH_CLIENT_SECRET=xyz789...
============================================================

重要提示: 立即保存这些凭据。秘密只显示一次,无法恢复。

OAuth端点

端点 描述
/.well-known/oauth-authorization-server 服务器元数据
/.well-known/oauth-protected-resource 受保护的资源元数据
/oauth/authorize 授权端点
/oauth/token 令牌端点

正在重新生成凭据

如果您丢失了凭据,请从数据库中删除客户端:

sqlite3 jobs.db "DELETE FROM oauth_clients WHERE client_name = 'Claude (auto)'"

然后重新启动服务器以生成新凭据。

目录结构

SFLOW-AIRunner-MCP-PRD/
├── server.py              # Main MCP server
├── requirements.txt       # Python dependencies
├── jobs.db               # SQLite database (auto-created)
├── .env                  # Environment variables (optional)
├── fixed-servers/        # Built-in MCP servers
│   └── email/
│       ├── server.py
│       └── metadata.json
├── dynamic_servers/      # User-created MCP servers (auto-created)
│   ├── cat-facts/
│   └── r2-images/
├── deploy/               # Deployment configs (systemd, nginx, deploy script)
│   ├── deploy.sh
│   ├── mcpserver.service
│   ├── nginx.conf
│   └── README-HETZNER.md
└── claude_playground/    # Working directory for job execution (auto-created)

数据库

SQLite数据库位于 ./jobs.db 如下表所示:

表格

表 说明
jobs 带有cron表达式的计划任务
runs 包含输出、令牌和成本的执行历史记录
settings 配置(允许的工具、MCP服务器、凭据)
webhooks 触发提示的HTTP端点
oauth_clients OAuth客户端凭据
oauth_codes OAuth授权码
oauth_refresh_tokens OAuth刷新令牌

默认设置

首次运行时,会创建以下默认值:

键 默认值
allowed_tools ["WebSearch", "WebFetch", "Read", "Write", "Edit", "Bash"]
mcp_servers []
mcp_env_vars {}
webhook_base_url "http://localhost:8080"
sandbox_mode true

清除重置

要完全重置数据库,请执行以下操作:

rm jobs.db
python server.py  # Creates fresh database

MCP工具可用

作业管理

工具 说明
list_jobs 列出所有计划作业
get_job(job_id) 找一份特定的工作
create_job(name, cron, prompt, ...) 创建新的计划作业
update_job(job_id, ...) 更新现有作业
delete_job(job_id) 删除作业及其运行
trigger_job(job_id) 立即手动触发作业

运行管理

工具 说明
list_runs(job_id?, limit?) 列出最近的跑步记录
get_run(run_id) 获取完整的运行详细信息,包括输出
kill_run(run_id) 取消挂起/正在运行的运行

网络钩子

工具 说明
create_webhook(name, prompt_template) 创建webhook端点
list_webhooks 列出所有Webhook
get_webhook(webhook_id) 获取webhook详细信息
update_webhook(webhook_id, ...) 更新webhook
delete_webhook(webhook_id) 删除webhook

动态MCP服务器

工具 说明
create_mcp_server(name, code, ...) 创建自定义MCP服务器
list_dynamic_mcp_servers 列出用户创建的服务器
get_dynamic_mcp_server(name) 获取服务器详细信息
update_mcp_server(name, code, ...) 更新动态服务器的代码/描述
delete_mcp_server(name) 删除动态服务器
enable_mcp_server(name) 启用动态MCP服务器
disable_mcp_server(name) 禁用动态MCP服务器

固定MCP服务器

工具 说明
list_fixed_mcp_servers 列出内置服务器
enable_fixed_server(name) 启用固定服务器
disable_fixed_server(name) 禁用固定服务器

内部MCP工具

工具 说明
invoke_internal_mcp_tool(tool, payload) 调用内部MCP服务器上的工具

凭证

工具 说明
set_server_credential(server, key, value) 设置凭据
get_server_credentials(server) 查看凭据(已屏蔽)
list_required_credentials(server) 查看所需凭据
get_unconfigured_servers 查找缺少凭据的服务器
delete_server_credential(server, key) 删除凭据

通过claude.ai使用

连接后,您将完全通过自然语言与服务器交互。Claude在幕后将您的请求转换为适当的MCP工具调用。

重要提示: 作业通过Claude Agent SDK执行,该SDK在后台运行本地Claude Code CLI。你需要 克劳德代码 已安装并验证(claude 必须在系统PATH上可用并已登录)。

以下是主要工作流程。

创建自定义工具

您可以要求Claude动态构建新的MCP工具服务器。服务器代码保存到 dynamic_servers/<name>/ 每个服务器都会得到一个 DATA_DIR 本地文件存储的路径变量。通过引用的环境变量 os.environ.get() 或 os.getenv() 在代码中,会自动检测并标记为所需的凭据。

You: Create a tool that fetches the current weather for a given city using the
     OpenWeatherMap API.

Claude: [calls create_mcp_server — saves server to dynamic_servers/weather/,
         detects OPENWEATHERMAP_API_KEY from code]
  Done! I created the "weather" server with a get_weather(city) tool.
  It needs an API key — want me to store yours now?

You: Yes, the key is abc123

Claude: [calls set_server_credential("weather", "OPENWEATHERMAP_API_KEY", "abc123")]
  Credential saved. The weather server is ready to use.

安排重复作业

作业使用Claude Agent SDK按cron计划运行。您可以指定作业允许使用的工具(空数组 [] 指所有工具)。

You: Create a job that runs every weekday at 9am to summarize our Azure DevOps sprint

Claude: [calls create_job with:]
  name: "Daily Sprint Summary"
  cron: "0 9 * * 1-5"
  prompt: "Connect to Azure DevOps and summarize the current sprint..."
  tools: ["mcp__azure-devops__wit_my_work_items", "mcp__email__send_email"]
  Job created (id: a1b2c3d4). Next run: tomorrow at 9:00 AM.

You: Show me the last 5 runs

Claude: [calls list_runs with limit=5]
  Here are the recent runs — 4 completed successfully, 1 errored out...

设置Webhooks

Webhooks允许外部服务通过HTTP POST触发提示。这 prompt_template 支持 {{payload}} 全身或 {{payload.field.subfield}} 对于嵌套值。

You: Create a webhook that sends a Slack summary whenever a new Azure DevOps
     work item is created. The POST body will have the item title at
     resource.fields.System.Title.

Claude: [calls create_webhook with:]
  name: "New Work Item Notifier"
  prompt_template: "A new work item was created: {{payload.resource.fields.System.Title}}.
                    Summarize it and post to Slack."
  Webhook created! POST to this URL to trigger it:
  https://your-server.com/webhook/abc123def456...

You: Test it — trigger the webhook manually

Claude: I can't trigger webhooks via MCP, but you can test with curl:
  curl -X POST https://your-server.com/webhook/abc123def456... \
    -H "Content-Type: application/json" \
    -d '{"resource":{"fields":{"System":{"Title":"Bug: login broken"}}}}'

直接调用工具

使用 invoke_internal_mcp_tool 立即调用任何启用的MCP服务器上的工具,而无需创建作业。

You: Use the weather tool to check the forecast in Berlin

Claude: [calls invoke_internal_mcp_tool with:]
  tool: "mcp__weather__get_weather"
  payload: {"city": "Berlin"}
  Currently 12°C and cloudy in Berlin, with rain expected this afternoon.

管理服务器和凭据

您可以启用、禁用和更新内置(固定)和用户创建(动态)服务器,并管理它们的凭据。

You: What servers are available?

Claude: [calls list_fixed_mcp_servers and list_dynamic_mcp_servers]
  Fixed servers: email (enabled), playwright (disabled)
  Dynamic servers: weather (enabled), url-shortener (disabled)

You: Enable playwright and disable the weather server

Claude: [calls enable_fixed_server("playwright") and disable_mcp_server("weather")]
  Done — playwright is now enabled and weather is disabled.

You: Which servers are missing credentials?

Claude: [calls get_unconfigured_servers]
  The email server needs SENDGRID_API_KEY and SENDER_EMAIL.

特别提示

对于一次性任务,请使用 快速运行 web仪表板(SSE模式)中的功能,无需创建作业即可立即执行提示。从claude.ai,您还可以手动触发任何现有作业:

You: Run the "Daily Sprint Summary" job right now

Claude: [calls trigger_job("a1b2c3d4")]
  Run queued (run_id: e5f6g7h8). I'll check back for results.

Cron示例

表达式 描述
0 9 * * 1-5 工作日上午9:00
0 */2 * * * 每2小时
0 9 * * 1 周一上午9:00
*/30 * * * * 每30分钟
0 0 1 * * 每月的第一天午夜

故障排除

ModuleNotFoundation错误:没有名为“dotenv”的模块

Claude Desktop正在使用Python系统,而不是您的venv。更新配置以使用完整的venv路径:

{
  "command": "/full/path/to/.venv/bin/python",
  "args": ["/full/path/to/server.py"]
}

OAuth凭据丢失

删除自动生成的客户端并重新启动:

sqlite3 jobs.db "DELETE FROM oauth_clients WHERE client_name = 'Claude (auto)'"
python server.py  # New credentials printed to stderr

作业未运行

  1. 检查调度程序是否正在运行(在日志中查找“调度程序循环已启动”)
  2. 验证作业是否已启用: sqlite3 jobs.db "SELECT enabled FROM jobs"
  3. 检查cron表达式是否有效
  4. 查找运行中的错误: sqlite3 jobs.db "SELECT error FROM runs ORDER BY started_at DESC LIMIT 1"

MCP工具在作业中不可用

如果作业报告“我无法访问[MCP服务器]工具”,请检查工具名称格式:

正确格式: mcp__<server>__<tool> (双下划线)

  • 例子: mcp__email__send_email
  • 例子: mcp__playwright__navigate

自动标准化格式: 这些将自动转换:

  • email:send_email → mcp__email__send_email
  • email.send_email → mcp__email__send_email

提示: 使用空的工具数组 [] 允许所有可用工具,或检查响应 tool_warnings 查看是否有任何工具被规范化。

服务器立即断开连接

检查stderr输出是否有错误。常见原因:

  • 缺少依赖项(运行 pip install -r requirements.txt)
  • Python版本<3.11
  • 数据库被其他进程锁定

Git“所有权可疑”错误

如果自动部署失败,并显示“致命:在存储库中检测到可疑的所有权”:

git config --system --add safe.directory /opt/mcpserver/app

当存储库由与运行部署脚本的用户不同的用户拥有时,就会发生这种情况。

找不到Playwright浏览器

如果Playwright因浏览器未找到错误而失败,请手动安装Chromium:

# Install system dependencies first (as root) - Ubuntu 24.04
apt install -y libnss3 libnspr4 libatk1.0-0t64 libatk-bridge2.0-0t64 libcups2t64 \
  libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 \
  libpango-1.0-0 libcairo2 libasound2t64

# Then install browser (as application user)
su - mcpuser
cd /opt/mcpserver/app
source venv/bin/activate
playwright install chromium

验证它是否有效:

python -c "from playwright.sync_api import sync_playwright; p = sync_playwright().start(); b = p.chromium.launch(); print('OK'); b.close(); p.stop()"

建筑

┌─────────────────────────────────────────────────────────────┐
│                       MCP Server                            │
│  ┌───────────┐  ┌───────────────┐  ┌───────────────────┐   │
│  │ Job CRUD  │  │   Scheduler   │  │   Run Processor   │   │
│  │  Tools    │  │  (60s loop)   │  │     (async)       │   │
│  └─────┬─────┘  └───────┬───────┘  └─────────┬─────────┘   │
│        │                │                    │             │
│        └────────────────┼────────────────────┘             │
│                         ▼                                  │
│                ┌────────────────┐                          │
│                │    SQLite      │                          │
│                │   (jobs.db)    │                          │
│                └────────────────┘                          │
│                         │                                  │
│                         ▼                                  │
│                ┌────────────────┐                          │
│                │ Claude Agent   │                          │
│                │     SDK        │                          │
│                └────────────────┘                          │
└─────────────────────────────────────────────────────────────┘

服务器运行三个并发异步组件:

  1. MCP服务器 -通过FastMCP显示25+个工具
  2. 调度器循环 -每60秒检查一次根据cron到期的作业
  3. 运行处理器循环 -拾取挂起的运行并执行它们

关键依赖

  • fastmcp -MCP协议实现
  • claude-agent-sdk -运行作业的核心执行引擎
  • croniter -Cron表达式解析
  • sendgrid, requests -电子邮件提供商集成
  • uvicorn -用于SSE传输的ASGI服务器
  • pyngrok -从claude.ai远程进入ngrok隧道
  • python-dotenv - .env 文件加载
  • PyJWT -OAuth的JWT令牌处理
  • beautifulsoup4 -网络抓取
  • boto3 -AWS集成
  • playwright -浏览器自动化