Skip to main content
Glama
cayde-6
by cayde-6

service-bridge-mcp

A calendar-first, deny-by-default MCP service broker prototype. The agent is a caller, never the broker administrator. MCP provides interoperability; it is not a security boundary by itself.

Status: local dummy-data prototype, not production-ready. No real calendar credentials, calendars, or invitations were used. The default executable only stores temporary dummy data in memory. The CalDAV implementation is a protocol fixture exercised against an in-memory fake, and cannot make live network requests. There is no arbitrary-service execution, generic URL tool, proxy, shell tool, credential-reading tool, or admin tool.

What works

  • Official MCP TypeScript v2 SDK, pinned in the lockfile. Streamable HTTP request handler, compatible with current and supported legacy clients.

  • OAuth resource-server bearer-token verification: asymmetric signature, allowed algorithms, exact issuer/audience, access-token type (at+jwt), expiry, issued-at, subject, and scopes. No token passthrough.

  • Per-subject, per-calendar, server-owned grants intersected with token scopes. Unknown callers and missing permissions fail closed.

  • Separate calendar:read, calendar:create, and calendar:invite capabilities. Create cannot carry attendees. Invite requires a separate preconfigured recipient allowlist and a version match.

  • Canonical UTC timestamps, server-owned date bounds, maximum 31-day query/event window, strict schemas, bounded request sizes, minimal read fields.

  • Idempotent creation scoped to subject/calendar/key, payload-conflict detection, ETag-guarded changes. Duplicate invite attempts with an old ETag fail rather than resend.

  • Exact Host/Origin checks, standard OAuth protected-resource metadata, generic failure responses, no request/token/provider-body logging.

Related MCP server: Apple Calendar MCP

Quick check

Requires Node.js 24 or newer and npm. No account or credentials are needed for tests.

npm ci --ignore-scripts
npm run check
npm run demo

The demo negotiates MCP, creates a dummy event, safely retries it, and reads it back without opening a network connection.

Tests create ephemeral signing keys in memory; they never persist them or provision credentials. They exercise signed/invalid access tokens, policy denials, MCP calls, idempotency, concurrency versions, field injection, fake CalDAV responses, and invitation non-delivery. npm run build compiles TypeScript; npm test runs Node's test runner.

Surface

Tool

Scope

Purpose

calendar_read

calendar:read

At most 100 minimal events in an authorized UTC window

calendar_create

calendar:create

One event with title/start/end and an idempotency key; no attendees

calendar_invite

calendar:invite

Dummy attendee-list change only; recipient allowlist + ETag; no delivery

Read responses expose only event ID, title, UTC start/end, and ETag. Calendar contents are untrusted data, never instructions. Invite responses expose only event ID, ETag, and delivery: "not_attempted". An attendee list is not evidence that any invitation was sent or delivered. CalDAV scheduling returns SCHEDULING_UNVERIFIED without making a request.

Operator-owned configuration

createBroker(config, adapter) is the embedding API. npm start -- /path/to/operator-public-config.json starts the dummy-only executable on 127.0.0.1:3000. It reads only the explicitly supplied file, never .env. It refuses to start without a configuration. The repository intentionally contains no usable auth credentials or provisioned identity provider.

The JSON shape is:

{
  "issuer": "https://identity.example",
  "resource": "https://broker.example/mcp",
  "jwks": { "keys": ["REPLACE WITH AN EXISTING ISSUER PUBLIC JWK OBJECT"] },
  "allowedOrigins": [],
  "grants": [
    {
      "subject": "existing-subject-id",
      "calendarId": "demo",
      "scopes": ["calendar:read"],
      "startUtc": "2026-10-01T00:00:00Z",
      "endUtc": "2026-11-01T00:00:00Z",
      "maxRangeDays": 7,
      "allowedAttendees": []
    }
  ]
}

The placeholder is intentionally not a runnable JWK. Supply only public verification keys from a separately managed issuer; symmetric or private key material is rejected. The broker does not issue tokens, provide login, refresh keys automatically, or manage users. Public JWKS are pinned at startup; key rotation currently requires an operator reload. A real deployment needs an OAuth authorization server with MCP client authorization and resource/audience support. Do not use an ID token as an access token.

The resource and issuer must be HTTPS. Local HTTP is restricted to loopback behind a separately managed TLS reverse proxy; preserve the configured public Host. No wildcard Origin is implicit; absent Origin is allowed for non-browser MCP clients, while a present Origin must exactly match the operator list. No forwarded-header identity is trusted. Remote deployment has not been performed or validated.

Persistence and boundaries

The memory adapter holds at most 1,000 events and loses all data/idempotency records on restart. It is a single-process test adapter, not a durable calendar database. CalDAV create fixtures use deterministic object identifiers plus If-None-Match: *, and changes require a strong ETag. A retry of a changed payload under the same key conflicts. Actual CalDAV scheduling, timezone/recurrence semantics, provider permissions and durable multi-instance guarantees are future integration gates.

Adding another service means adding an explicit typed adapter, narrow schemas, independent capability checks, data minimization, provider-specific tests and security review. Do not let an agent register services or configure URLs/credentials. See adapter contract and threat model.

Before any production use

  1. Deploy and test a real OAuth issuer/client flow, TLS termination, trusted Host handling, key rotation/revocation, request deadlines and rate limits.

  2. Implement a reviewed live CalDAV transport: strict destination allowlist, no redirects, public-IP validation and connection pinning, DNS-rebinding protection, timeout/body limits, separate server-side service credentials. Do not substitute arbitrary fetch.

  3. Verify read/write behavior against a disposable real provider and least-privilege account. Keep invitation sending disabled until provider scheduling behavior and approval requirements are verified.

  4. Add durable transaction/idempotency storage, multi-process concurrency tests, resource quotas, audit-event design, operational monitoring, backup and retention policies.

  5. Run independent deployment/security review and dependency scanning. Passing dummy tests is not evidence of production security.

Provenance

Original implementation; no source from the imported @cayde-6/icalendar project was copied. Its sanitized package/license was located for comparison only, and no private configuration was read. Third-party dependency licenses remain with their packages. Licensed under MIT; see LICENSE.

Official references checked during implementation:

Related MCP Connectors

Related MCP Servers