{
  "version": "2",
  "generatedAt": "2026-11-03T22:49:39.280Z",
  "listing": {
    "slug": "ridafkih--keeper.sh",
    "name": "Keeper.sh",
    "tagline": "Calendar sync across Google, Outlook, iCloud, Fastmail and CalDAV, with an MCP server and REST API from the Builder.",
    "shortTagline": "Calendar sync across providers",
    "description": "Keeper.sh pulls events from any connected calendar and pushes them to one or many destinations so busy slots line up, with per-source privacy templates and a combined iCal feed. It ships an MCP server (OAuth 2.1) and a /api/v1 REST API that share handlers with the dashboard: list calendars, read and create events, RSVP, find free time, trigger or pause sync. Self-hosting unlocks Pro features; the hosted edition has a free plan and a USD 5 Pro plan.",
    "capabilities": [
      "adaptable",
      "operable"
    ],
    "vertical": "scheduling-staffing",
    "alternativeTo": [
      "OneCal",
      "CalendarBridge"
    ],
    "shape": "product",
    "formFactor": "web-app",
    "executionModel": "deterministic",
    "provenance": "unknown",
    "codeStack": {
      "languages": [
        "TypeScript"
      ],
      "frameworks": [
        "Bun",
        "Vite SSR",
        "BullMQ",
        "better-auth",
        "Caddy"
      ],
      "packageManager": "bun",
      "database": [
        "PostgreSQL",
        "Redis"
      ],
      "hostingTarget": [
        "docker"
      ]
    },
    "modelStack": {
      "providers": [
        "any MCP client"
      ],
      "models": [],
      "requiredKeys": [],
      "promptLocations": [],
      "tools": [
        "list_calendars",
        "list_accounts",
        "get_events",
        "get_event",
        "get_event_count",
        "create_event",
        "update_event",
        "delete_event",
        "rsvp_event",
        "get_pending_invites",
        "find_free_time",
        "trigger_sync",
        "pause_sync",
        "get_ical_feed"
      ]
    },
    "repos": [
      {
        "url": "https://github.com/ridafkih/keeper.sh",
        "owner": "ridafkih",
        "name": "keeper.sh",
        "license": "AGPL-3.0",
        "stars": 1272,
        "lastCommit": "2026-09-02"
      }
    ],
    "interface": {
      "kind": "mcp",
      "url": "https://github.com/ridafkih/keeper.sh#mcp-model-context-protocol",
      "official": true,
      "hosted": "both"
    },
    "operability": "official",
    "recommendedWrapper": null,
    "reach": [
      {
        "job": "List connected accounts and calendars",
        "reachable": true,
        "evidence": "services/mcp/src/toolset.ts: list_accounts, list_calendars"
      },
      {
        "job": "Read events and counts in a date range",
        "reachable": true,
        "evidence": "toolset.ts: get_events, get_event, get_event_count"
      },
      {
        "job": "Create, update and delete events",
        "reachable": true,
        "evidence": "toolset.ts: create_event, update_event, delete_event"
      },
      {
        "job": "Respond to invitations",
        "reachable": true,
        "evidence": "toolset.ts: rsvp_event, get_pending_invites"
      },
      {
        "job": "Find free time with working hours",
        "reachable": true,
        "evidence": "toolset.ts: find_free_time; REST GET /api/v1/events/free-time"
      },
      {
        "job": "Trigger or pause sync",
        "reachable": true,
        "evidence": "toolset.ts: trigger_sync, pause_sync; throttled to one run per minute"
      },
      {
        "job": "Get the combined iCal feed URL",
        "reachable": true,
        "evidence": "toolset.ts: get_ical_feed"
      },
      {
        "job": "Connect a new Google or Outlook account",
        "reachable": false,
        "evidence": "OAuth consent runs in the web dashboard; token management at /api/tokens needs a browser session"
      },
      {
        "job": "Create or edit sync mappings and privacy templates",
        "reachable": false,
        "evidence": "no mapping tool in toolset.ts or the /api/v1 route table"
      },
      {
        "job": "Configure event filters",
        "reachable": false,
        "evidence": "Pro feature set in the dashboard; not in the tool list"
      }
    ],
    "editions": [
      {
        "name": "Self-hosted",
        "price": null,
        "open": true,
        "distributions": [
          {
            "kind": "source",
            "url": "https://github.com/ridafkih/keeper.sh"
          },
          {
            "kind": "container",
            "url": "https://github.com/ridafkih/keeper.sh#standalone-container",
            "command": "docker run -d -p 80:80 -v keeper-data:/var/lib/postgresql/data --env-file .env ghcr.io/ridafkih/keeper-standalone:2"
          }
        ]
      },
      {
        "name": "Cloud Free",
        "price": {
          "amount": 0,
          "currency": "USD",
          "period": "month"
        },
        "open": false,
        "distributions": [
          {
            "kind": "hosted",
            "url": "https://www.keeper.sh/register"
          }
        ]
      },
      {
        "name": "Cloud Pro",
        "price": {
          "amount": 5,
          "currency": "USD",
          "period": "month"
        },
        "open": false,
        "distributions": [
          {
            "kind": "hosted",
            "url": "https://www.keeper.sh/"
          }
        ]
      }
    ],
    "skills": {
      "kind": "none",
      "paths": [],
      "install": null,
      "note": "No SKILL.md, Claude Code plugin, or published skill found in the repo."
    },
    "customization": {
      "summary": "For the standalone image, generate BETTER_AUTH_SECRET and ENCRYPTION_KEY, set TRUSTED_ORIGINS to every origin you will use, and add GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET and MICROSOFT_CLIENT_ID/MICROSOFT_CLIENT_SECRET from your own OAuth apps. Split deployments add DATABASE_URL, REDIS_URL, BETTER_AUTH_URL, MCP_PUBLIC_URL and MCP_PORT; WEBHOOK_PUBLIC_URL turns on realtime push; RESEND_API_KEY enables email. Sources, destinations and privacy templates are configured in the dashboard.",
      "envVars": [
        "BETTER_AUTH_SECRET",
        "ENCRYPTION_KEY",
        "TRUSTED_ORIGINS",
        "GOOGLE_CLIENT_ID",
        "GOOGLE_CLIENT_SECRET",
        "MICROSOFT_CLIENT_ID",
        "MICROSOFT_CLIENT_SECRET",
        "DATABASE_URL",
        "REDIS_URL",
        "BETTER_AUTH_URL",
        "MCP_PUBLIC_URL",
        "MCP_PORT",
        "WEBHOOK_PUBLIC_URL",
        "RESEND_API_KEY",
        "COMMERCIAL_MODE",
        "WORKER_JOB_QUEUE_ENABLED",
        "BLOCK_PRIVATE_RESOLUTION"
      ],
      "configFiles": [
        ".env",
        "compose.yaml"
      ],
      "promptFiles": [],
      "effort": "config-only",
      "editCount": 19
    },
    "useWhen": [
      "I juggle a work calendar, a business calendar and a personal one and keep getting double-booked",
      "I want my agent to see one true picture of my availability and book into it through MCP"
    ],
    "accounts": [
      "Google Cloud (OAuth app, optional)",
      "Microsoft Entra (OAuth app, optional)",
      "Keeper.sh (hosted editions only)"
    ],
    "active": true,
    "lastActivity": "2026-09-02",
    "gotchas": [
      "AGPL-3.0 copyleft",
      "Self-hosting means registering your own Google and Microsoft OAuth apps; Google calendar scopes need app verification for non-test users",
      "Cloud Free: 2 linked accounts, 3 sync mappings, 30-minute refresh and 25 API requests per day",
      "The Bun rewrite changed environment variable names; migration notes are in issue #140",
      "Missing TRUSTED_ORIGINS fails CSRF checks for any origin other than http://localhost"
    ],
    "fit": {
      "adaptable": 2,
      "operable": 3
    },
    "evidence": {
      "formFactor": "README: web dashboard plus API, MCP, cron and worker services in Docker images",
      "executionModel": "no model at runtime; MCP exposes data to external agents",
      "operability": "services/mcp in the Builder's repo; README says /api/v1 is the same interface the dashboard and MCP use",
      "effort": "README environment variable table and compose examples",
      "editions": "README pricing table: Free USD 0, Pro USD 5 per month or USD 45 per year, self-hosted Pro at USD 0",
      "active": "shortlist pushedAt 2026-09-02"
    },
    "confidence": {
      "formFactor": 0.95,
      "executionModel": 0.95,
      "operability": 0.9,
      "effort": 0.95,
      "reach": 0.9,
      "editions": 0.95
    },
    "openQuestions": [
      "Triage called this native; recorded as official because the dashboard remains the primary interface and MCP is one of three callers. Curator to decide",
      "Is the hosted MCP endpoint available on the Cloud Free plan within the 25 requests per day cap?"
    ],
    "sources": [
      {
        "url": "https://github.com/ridafkih/keeper.sh",
        "foundBy": "sourcing:scheduling-staffing:curated"
      },
      {
        "url": "https://www.keeper.sh/",
        "foundBy": "sourcing:scheduling-staffing:curated"
      },
      {
        "url": "https://github.com/ridafkih/keeper.sh/blob/main/services/mcp/src/toolset.ts",
        "foundBy": "analysis:scheduling-staffing"
      }
    ],
    "research": {
      "stage": "verified",
      "verdict": "unverified",
      "reason": "Builder-published MCP and REST with an explicit tool list and complete env documentation; AGPL and own-OAuth-app burden cap adaptable at 2.",
      "disputed": []
    },
    "url": "apps/ridafkih--keeper.sh.html",
    "coverage": "partial",
    "paid": true,
    "source": "research/verified/ridafkih--keeper.sh.json"
  }
}
