npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sleep-arbitrage-mcp

v0.4.0

Published

Queue work before you sleep, get results in the morning. MCP server + worker.

Readme

Queue work before you sleep. Get results in the morning.

npm license MCP

An MCP server for async task handoff. Built by NULL.


The idea

You stop working at 11pm. Your agents don't. The gap between when you sleep and when you need results is the arbitrage.

This is the intake layer for that.


How it works

  YOU (11pm)                    AGENT (3am)                   YOU (7am)
  ┌─────────────┐              ┌─────────────┐              ┌─────────────┐
  │ "Queue this │  queue_task  │ claim_next  │  update_task │ "What       │
  │  for        │ ──────────►  │ do the work │ ──────────►  │  finished?" │
  │  tonight"   │              │ attach      │              │             │
  │             │              │ results     │              │  list_tasks │
  └─────────────┘              └─────────────┘              └─────────────┘

No dashboard. No email. No extra app. You're already in Claude. That's the interface.


Install

npm install -g sleep-arbitrage-mcp

Setup (Claude Desktop)

{
  "mcpServers": {
    "sleep-arbitrage": {
      "command": "sleep-arbitrage-mcp",
      "env": {
        "SLEEP_ARBITRAGE_DATA_FILE": "/path/to/tasks.json"
      }
    }
  }
}

From source

git clone https://github.com/nullbuilds-ai/sleep-arbitrage-mcp
cd sleep-arbitrage-mcp
npm install && npm run build

Tools

| Tool | Description | |:-----|:------------| | queue_task | Submit work with priority, expiry, and optional delivery config | | claim_next | Grab the next task. Highest priority, oldest first. Atomic. | | list_tasks | View queue. Filter by status. | | get_task | Full details by ID | | update_task | Mark done, attach results. Auto-delivers if configured. |


Agent pickup loop

claim_next is how agents work through the queue overnight. It's atomic: claims a task and sets it to in_progress in one operation.

claim_next ─► do the work ─► update_task ─► claim_next ─► ...
                                                    └─► "No tasks in the queue."

Priority order: urgent > normal > low, then oldest first.

Expiry: Pass expires_in_hours when queuing. Stale tasks get skipped automatically.


Task lifecycle

                            ┌──── completed ──── [delivery]
                            │
queued ──── claim_next ──── in_progress
                            │
                            └──── cancelled

queued ──── [time elapsed] ──── expired

Delivery (optional)

Most users won't need this. But if you want results pushed outside of Claude:

Email -- Formatted HTML via Resend. Set RESEND_API_KEY.

Webhook -- POST to any URL with the full task payload.

Pass delivery_email or delivery_webhook when queuing. Both optional, both independent.


Worker (agent side)

The worker is bundled in the same package. No separate install.

Quick start

# Check the queue
sleep-arbitrage-worker status

# Process all queued tasks
ANTHROPIC_API_KEY=sk-... sleep-arbitrage-worker drain

# Process one task and exit
ANTHROPIC_API_KEY=sk-... sleep-arbitrage-worker once

How it works

  1. Reads the same tasks.json the MCP server uses
  2. Claims the highest-priority queued task (file lock prevents concurrent workers)
  3. Sends task + context to Claude API
  4. Writes the result back to tasks.json
  5. Delivers via email (Resend) or webhook if configured
  6. Repeats until the queue is empty (drain mode)

Environment variables

| Variable | Required | Default | Description | |:---------|:---------|:--------|:------------| | ANTHROPIC_API_KEY | Yes | -- | Your Anthropic API key | | SLEEP_ARBITRAGE_DATA_FILE | No | ./tasks.json | Path to the shared task store | | SLEEP_ARBITRAGE_MODEL | No | claude-sonnet-4-6-20250514 | Model for task execution | | SLEEP_ARBITRAGE_MAX_TOKENS | No | 4096 | Max response tokens | | RESEND_API_KEY | No | -- | For email delivery via Resend | | SLEEP_ARBITRAGE_FROM_EMAIL | No | [email protected] | Sender address |

Scheduling

cron (Linux/macOS):

# Every 30 minutes from 11pm to 7am
*/30 23,0-7 * * * ANTHROPIC_API_KEY=sk-... sleep-arbitrage-worker drain

launchd (macOS): See examples/launchd.plist for a ready-to-use template.

systemd (Linux):

# /etc/systemd/system/sleep-worker.timer
[Timer]
OnCalendar=*-*-* 23,00,01,02,03,04,05,06,07:00,30:00

[Install]
WantedBy=timers.target

Customization

The worker uses a simple system prompt for general research/analysis tasks. To specialize it:

  • Swap the model: Set SLEEP_ARBITRAGE_MODEL to any Anthropic model
  • Change the prompt: Edit SYSTEM_PROMPT in src/worker.ts
  • Add tools: Extend executeTask() with MCP clients, web search, file access, etc.
  • Use your own LLM: Replace the Anthropic client with any API

Python worker

A standalone Python worker (worker.py) is also included for environments where Node.js isn't available or you prefer Python. Same logic, same task store.


Roadmap

| Phase | Status | What | |:------|:-------|:-----| | 1. Intake | ✅ Shipped | Task queue, 5 MCP tools, JSON storage | | 2. Delivery | ✅ Shipped | Email + webhook on completion | | 3. Agent Pickup | ✅ Shipped | claim_next, priority, expiry | | 4. Worker | ✅ Shipped | Bundled TypeScript worker + Python fallback, scheduling templates | | 5. Hosted Service | Next | Web dashboard, agent fleet, SLA tiers | | 6. Orchestration | Future | Task chains, agent-to-agent handoff, SDK |

The self-hosted version stays free and open source forever. The hosted version is where the service lives.


Agents don't sleep. You do.

Built by NULL on Model Context Protocol