Atlas / MCP servers / ridafkih / Keeper

KeeperBLOCK

mcp/ridafkih/keeper-1

Calendar sync tool & universal calendar MCP server. Aggregate, sync and control calendars on Google, Outlook, Office 365, iCloud, CalDAV or ICS.

Verdict
BLOCK
Grade
F
Trust score
40 /100
Exposed tools
2 2r · 0w · 0d
Transport
streamable-http
License
AGPL-3.0
Stars
1,355
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Keeper.sh is a simple & open-source calendar syncing tool. It allows you to pull events from your Google Calendar, Outlook, iCloud, Fastmail, CalDAV server, or remotely hosted iCal and ICS links, and push them to one or many calendars so the time slots can align across them all. Google, Outlook, iCloud, Fastmail, and CalDAV are first-class integrations that can each be used as a source or as a destination, while iCal and ICS links are pull-only. It also serves as a global MCP server and API for you or your agents to manage all your calendars from one convenient interface.

The recommended way to run it is the hosted version at keeper.sh: the same code, minus the server, the domain, the upgrades, the backups and the Google and Microsoft sign-in apps you would otherwise register yourself. Self-hosting is a first-class path and every Pro feature is included when you self-host — that is not a trial, and it is not going away. It costs you the upkeep instead of the $5.

Features

  • First-class Google Calendar, Outlook, iCloud, Fastmail, and CalDAV integrations, each usable as a source or a destination
  • Pull-only ingestion of remotely hosted iCal and ICS links
  • Incremental syncing on Google and Outlook using provider sync tokens rather than refetching everything
  • Event content agnostic syncing engine
  • Push aggregate events to one or more calendars
  • Per-source privacy controls to strip event names, descriptions, and locations, replacing the title with a {{calendar_name}} or {{event_name}} template
  • REST API under /api/v1 authenticated with API tokens
  • MCP (Model Context Protocol) server for AI agent calendar access
  • Combined iCal feed you can subscribe to from any calendar app
  • Open source under AGPL-3.0
  • Easy to self-host
  • Easy-to-purge remote events

Bug Reports & Feature Requests

If you encounter a bug or have an idea for a feature, you may [open an issue on Gi

Read from source at commit 2fc93464d952OBSERVED · 2026-09-25
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.

claude-code
claude mcp add worker -- npx -y @keeper.sh/worker
claude-desktop
{
  "mcpServers": {
    "worker": {
      "command": "npx",
      "args": [
        "-y",
        "@keeper.sh/worker"
      ]
    }
  }
}
03

Exposed tools (2)

2 read · 0 write · 0 destructive.

ToolRiskDescription
FreereadEnough for two calendar accounts and three connections.
ProreadAs many calendars as you want, and changes that land within a minute.
04

Trust audit

BLOCKgrade F · trust 40/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryFAIL
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (11 observation(s))
Network
declared (13 observation(s))
Shell
declared (1 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (25)

HIGHInventory / provenance · inv.suspicious_name · CWE-1104
services/api/src/handlers/websocket-payload.ts
websocket-payload.ts
Why it matters. member named after an attack tool
Fix. remove or justify
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
packages/calendar/src/core/utils/redis-rate-limiter.ts:36
eval(script: string, numberOfKeys: number, ...arguments_: string[]): Promise<unknown>;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
docker/services/Dockerfile:74
ENV VITE_API_URL=http://127.0.0.1:3001
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
docker/standalone/Dockerfile:97
ENV VITE_API_URL=http://127.0.0.1:3001
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
docker/standalone/Dockerfile:98
ENV VITE_MCP_URL=http://127.0.0.1:3002
MEDIUMObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
packages/calendar/src/ics/utils/apply-patches.ts:48
const BYTE_ORDER_MARK = "";
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.github/workflows/checks.yml:201
KEEPER_TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.github/workflows/checks.yml:268
MIGRATION_TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
README.md:91
| Postgres | 5432       | `postgresql://postgres:postgres@localhost:5432/postgres` |
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
README.md:355
DATABASE_URL=postgres://keeper:keeper@postgres:5432/keeper
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
README.md:484
DATABASE_URL: postgres://keeper:keeper@postgres:5432/keeper
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/auth/tests/a-microsoft-sign-in-links-only-an-asserted-email.test.ts:14
const SECRET = "test-secret-for-microsoft-sign-in-account-linking";
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/auth/tests/abandoned-unverified-registration-reclaim.test.ts:11
const SECRET = "test-secret-for-abandoned-unverified-registration-reclaim";
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/auth/tests/an-outlook-sign-in-records-the-email-as-verified.test.ts:8
const SECRET = "test-secret-for-outlook-sign-in-email-verification";
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/auth/tests/provider-signed-in-registrations-are-left-alone.test.ts:15
const SECRET = "test-secret-for-provider-asserted-email-not-reclaimable";
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/auth/tests/signup-leaves-an-existing-registration-intact.test.ts:35
secret: "test-secret-value-for-signup-reclaim-ownership",
MEDIUMAuth / authz · mcp.remote_no_auth · CWE-287, CWE-862
streamable-http
Why it matters. a network transport with no auth environment variable found
Fix. require a token
LOWInventory / provenance · inv.hidden_file · CWE-1104
.gitmodules
.gitmodules
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.oxlintrc.json
.oxlintrc.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
applications/web/.eslintrc.cjs
.eslintrc.cjs
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
packages/database/.env.template
.env.template
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
services/api/.env.template
.env.template
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.suspicious_name · CWE-1104
services/api/tests/handlers/websocket-payload.test.ts
websocket-payload.test.ts
Why it matters. member named after an attack tool
Fix. remove or justify
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
packages/calendar/tests/core/utils/rate-limiter-abandoned-waiter.test.ts:17
eval(script: string, numberOfKeys: number, ...arguments_: string[]): Promise<unknown>;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
packages/calendar/tests/core/utils/rate-limiter-arrival-order.test.ts:11
eval(script: string, numberOfKeys: number, ...arguments_: string[]): Promise<unknown>;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table

Gates applied: no_behavioural_pass.

Audited 2026-09-25 · audit v0.4.1 · source sha 2fc93464d952full audit observations/trust-audit/mcp-server/ridafkih__keeper-1.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-09-252fc93464d952BLOCKF40first audit
06

Questions

What is the Keeper MCP server?

Calendar sync tool & universal calendar MCP server. Aggregate, sync and control calendars on Google, Outlook, Office 365, iCloud, CalDAV or ICS.

What tools does Keeper expose?

2 in total: 2 read-only, 0 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is Keeper safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (40/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does Keeper need?

No credential environment variables were found in its source, so it appears to need none.

How does Keeper run?

It speaks streamable-http, so it runs as a service you connect to over the network. It is published on npm as @keeper.sh/worker.

How current is this page?

The grade is for one exact copy of the source (2fc93464d952), read on 2026-09-25. The repository is watched and re-audited when it changes.

Advertisement