Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Claude Runner MCPschedule a daily job to summarize my git commits every morning at 9am"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Claude Runner - MCP Server with Job Scheduling
A single-file MCP server that schedules and executes Claude Code CLI tasks via cron expressions. Features a web dashboard, webhook support, dynamic MCP server creation, and token/cost tracking.

Prerequisites
Python 3.11+ (required for
asyncio.timeout())Claude Agent SDK (
pip install claude-agent-sdk)SQLite3 (usually pre-installed on macOS/Linux)
Quick Start
On first run, the server will:
Create
jobs.dbSQLite database with all tablesAuto-generate OAuth credentials (printed to stderr - save these!)
Start the scheduler loop (checks every 60 seconds)
Running
Local (stdio transport - for Claude Desktop)
Add to Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
Important: Use the full path to the Python interpreter inside your .venv to ensure dependencies are available.
Remote (SSE transport - for web dashboard)
Both Transports
Environment Variables
Variable | Required | Default | Description |
| No |
| Transport mode: |
| No | auto-generated | OAuth client ID |
| No | auto-generated | OAuth client secret |
| No | auto-generated | Secret key for signing JWT tokens |
| No | - | Basic auth username for dashboard |
| No | - | Basic auth password for dashboard |
| No | - | ngrok auth token for remote tunneling |
| No | - | Override base URL for OAuth callbacks (e.g., |
Create a .env file to persist these:
Authentication (OAuth 2.1)
SSE transport requires OAuth 2.1 authentication. On first startup, the server auto-generates credentials and prints them to stderr:
Important: Save these credentials immediately. The secret is only shown once and cannot be recovered.
OAuth Endpoints
Endpoint | Description |
| Server metadata |
| Protected resource metadata |
| Authorization endpoint |
| Token endpoint |
Regenerating Credentials
If you lose your credentials, delete the client from the database:
Then restart the server to generate new credentials.
Directory Structure
Database
SQLite database at ./jobs.db with the following tables:
Tables
Table | Description |
| Scheduled tasks with cron expressions |
| Execution history with output, tokens, cost |
| Configuration (allowed tools, MCP servers, credentials) |
| HTTP endpoints that trigger prompts |
| OAuth client credentials |
| OAuth authorization codes |
| OAuth refresh tokens |
Default Settings
On first run, these defaults are created:
Key | Default Value |
|
|
|
|
|
|
|
|
|
|
Clean Reset
To completely reset the database:
MCP Tools Available
Job Management
Tool | Description |
| List all scheduled jobs |
| Get a specific job |
| Create a new scheduled job |
| Update an existing job |
| Delete a job and its runs |
| Manually trigger a job now |
Run Management
Tool | Description |
| List recent runs |
| Get full run details including output |
| Cancel a pending/running run |
Webhooks
Tool | Description |
| Create a webhook endpoint |
| List all webhooks |
| Get webhook details |
| Update a webhook |
| Delete a webhook |
Dynamic MCP Servers
Tool | Description |
| Create a custom MCP server |
| List user-created servers |
| Get server details |
| Update a dynamic server's code/description |
| Delete a dynamic server |
| Enable a dynamic MCP server |
| Disable a dynamic MCP server |
Fixed MCP Servers
Tool | Description |
| List built-in servers |
| Enable a fixed server |
| Disable a fixed server |
Internal MCP Tools
Tool | Description |
| Invoke a tool on an internal MCP server |
Credentials
Tool | Description |
| Set a credential |
| View credentials (masked) |
| See required credentials |
| Find servers missing credentials |
| Delete a credential |
Usage via claude.ai
Once connected, you interact with the server entirely through natural language. Claude translates your requests into the appropriate MCP tool calls behind the scenes.
Important: Jobs are executed via the Claude Agent SDK, which runs the local Claude Code CLI under the hood. You need Claude Code installed and authenticated (claude must be available on the system PATH and logged in) on the machine running the server.
Below are the main workflows.
Creating Custom Tools
You can ask Claude to build new MCP tool servers on the fly. The server code is saved to dynamic_servers/<name>/ and each server gets a DATA_DIR path variable for local file storage. Environment variables referenced via os.environ.get() or os.getenv() in the code are auto-detected and marked as required credentials.
Scheduling Recurring Jobs
Jobs run on cron schedules using the Claude Agent SDK. You can specify which tools the job is allowed to use (empty array [] means all tools).
Setting Up Webhooks
Webhooks let external services trigger a prompt via HTTP POST. The prompt_template supports {{payload}} for the full body or {{payload.field.subfield}} for nested values.
Invoking Tools Directly
Use invoke_internal_mcp_tool to call a tool on any enabled MCP server immediately, without creating a job.
Managing Servers & Credentials
You can enable, disable, and update both built-in (fixed) and user-created (dynamic) servers, and manage their credentials.
Ad-hoc Prompts
For one-off tasks, use the Quick Run feature in the web dashboard (SSE mode) to execute a prompt immediately without creating a job. From claude.ai, you can also manually trigger any existing job:
Cron Examples
Expression | Description |
| Weekdays at 9:00 AM |
| Every 2 hours |
| Mondays at 9:00 AM |
| Every 30 minutes |
| First day of month at midnight |
Troubleshooting
ModuleNotFoundError: No module named 'dotenv'
Claude Desktop is using system Python instead of your venv. Update your config to use the full venv path:
OAuth credentials lost
Delete the auto-generated client and restart:
Jobs not running
Check the scheduler is running (look for "Scheduler loop started" in logs)
Verify job is enabled:
sqlite3 jobs.db "SELECT enabled FROM jobs"Check cron expression is valid
Look for errors in runs:
sqlite3 jobs.db "SELECT error FROM runs ORDER BY started_at DESC LIMIT 1"
MCP tools not available in jobs
If a job reports "I don't have access to [MCP server] tools", check the tool name format:
Correct format: mcp__<server>__<tool> (double underscores)
Example:
mcp__email__send_emailExample:
mcp__playwright__navigate
Auto-normalized formats: These are automatically converted:
email:send_email→mcp__email__send_emailemail.send_email→mcp__email__send_email
Tip: Use an empty tools array [] to allow all available tools, or check the response for tool_warnings to see if any tools were normalized.
Server disconnects immediately
Check stderr output for errors. Common causes:
Missing dependencies (run
pip install -r requirements.txt)Python version < 3.11
Database locked by another process
Git "dubious ownership" error
If auto-deploy fails with "fatal: detected dubious ownership in repository":
This happens when the repository is owned by a different user than the one running the deploy script.
Playwright browser not found
If Playwright fails with browser not found errors, install Chromium manually:
Verify it works:
Architecture
The server runs three concurrent async components:
MCP Server - Exposes 25+ tools via FastMCP
Scheduler Loop - Checks every 60 seconds for jobs due based on cron
Run Processor Loop - Picks up pending runs and executes them
Key Dependencies
fastmcp- MCP protocol implementationclaude-agent-sdk- Core execution engine for running jobscroniter- Cron expression parsingsendgrid,requests- Email provider integrationsuvicorn- ASGI server for SSE transportpyngrok- ngrok tunnel for remote access from claude.aipython-dotenv-.envfile loadingPyJWT- JWT token handling for OAuthbeautifulsoup4- Web scrapingboto3- AWS integrationplaywright- Browser automation