Self-hostable MCP server

Owl Task Scheduler MCP

Schedule, chain, and cancel recurring tasks straight from your LLM client. A persistent HTTP service backed by Postgres + SQS — it keeps firing jobs long after the chat window is closed.

  • 5tools
  • 6actions
  • 4resources
  • 2prompts

Who & where

Built for developers who run their own jobs

Automate your GitHub, Slack, and Gmail workflows on a schedule, in plain language, with an audit trail that outlives the chat session. Connect any MCP-speaking client over a stable HTTP endpoint.

Works with Claude Desktop Claude Code Codex CLI Cursor MCP Inspector

Not ChatGPT — Custom GPT Actions aren't the MCP protocol.

Quickstart

Hosted path — try it in two minutes

Zero install. Point your MCP client at the hosted endpoint and sign in. Prefer to run it yourself? Self-host over HTTP or stdio — the README has the full guide.

  1. 1

    Add the server to your MCP client config

    claude_desktop_config.json{ "mcpServers": { "owl-scheduler": {
      "url": "https://scheduler.paynepew.dev/mcp",
      "transport": "streamable-http"
    }}}
  2. 2

    Restart the client and sign in

    The first tool call opens a WorkOS sign-in flow. Approve it once and your client is authenticated.

  3. 3

    Connect the providers you need

    Open the connections dashboard and link GitHub, Slack, or Google so actions can act on your behalf.

    Open connections
  4. 4

    Ask your LLM to create a task

    For example: “Every weekday at 9am, post a GitHub digest of my repo to #standup on Slack.” The scheduler persists the job and fires it on time — every time.

    Tip: if Claude reaches for its own built-in scheduler, start with “use owl-scheduler to …” — a collision-free handle that routes straight here.

Try these

Prompts that show what it does

Connect GitHub, Slack and Google first, then paste these into your client. Replace <owner>/<repo> and the channel / email with your own. If Claude reaches for its built-in scheduler, start with “use owl-scheduler to …”.

  1. 1

    Immediate

    “Right now, pull the open issues and stale PRs for <owner>/<repo> and summarize them for me.”

  2. 2

    LLM polish → Slack

    “Right now, rewrite this rough release note — ‘fixed the login bug, added dark mode, the api is faster now’ — into a professional announcement and post it to Slack #announcements.”

    Operator-funded LLM — no API key needed. The rewrite flows to Slack through the chain.

  3. 3

    One-shot chain · GitHub → Slack → Email (flagship)

    “In 3 minutes, pull the open issues for <owner>/<repo>, post the summary to Slack #eng-updates, and once that succeeds, email the same summary to me.”

  4. 4

    Fan-out · one digest, two sinks

    “In 2 minutes, digest <owner>/<repo> and both post it to Slack #eng-updates and email it to me.”

  5. 5

    Recurring · daily standup

    “Every weekday at 9:00 AM Taipei time, post a digest of <owner>/<repo>’s open issues and stale PRs to Slack #standup.”

Live-demo tip: run 1 → 2 → 3 → 5, then on a recurring job say “every 2 minutes” to watch it fire live and “cancel that task”. Steps 1–2 need no GitHub, so they always work. Failure-only alerts (trigger on FAILED), weekly email reports, and list / status / cancel are in the README’s full ladder.

How it works

A persistent pipeline, not a chat subprocess

Your client only creates and queries jobs over MCP. The server schedules on wall-clock time with its own Postgres and worker pool, so jobs fire whether or not a chat window is open.

MCP client mcp-server Postgres · outbox Watcher Queue Worker GitHub · Slack · Gmail

Follow-ups react to an append-only event outbox: one continuation consumer creates the next recurring run and every chained downstream the moment an upstream finishes — exactly-once via a database unique index. A worker crash can't wedge a job: a heartbeat lease lets the reconciler recover orphaned runs, and email_send is effectively-once, so a redelivered send never doubles. OAuth 2.1 login, per-user KMS-encrypted tokens, and strict tenant isolation — nobody reads or chains another user's runs — plus quotas and load-shedding keep a single $5 box safe. Full diagrams and ADRs in the README.

What it does

Five tools, six actions

Tools

The MCP verbs your LLM calls.

  • task.create
  • task.list
  • task.status
  • task.cancel
  • task.list_actions

Plus 4 resources & 2 prompts: a recent-results briefing and ready-made review prompts.

Actions

What a task actually does when it fires.

  • github_digestSummarize a repo's issues & PRs.
  • slack_postPost a message to a Slack channel.
  • email_sendSend email via your connected Gmail — effectively-once, so a retry never doubles.
  • llm_summarizeSummarize text or an upstream result — chain to Slack or email to receive the output.
  • llm_polishRewrite text more cleanly (tone & language) — chain to Slack or email to receive the output.
  • echoEcho a message back — smoke test.
Built in Cron recurrence Job chaining Cancel semantics Crash recovery OAuth connections Rate limiting
Built with Python 3.12 MCP SDK Starlette PostgreSQL SQLAlchemy SQS WorkOS AWS KMS Docker · Caddy