Crawler Summary

google-calendar-mcp answer-first brief

MCP server for Google Calendar integration with multi-account OAuth support MCP Server Template for Cloudflare Workers A production-ready template for building MCP (Model Context Protocol) servers on Cloudflare Workers with better-auth social login. Features - **better-auth Social Login** - Google, Microsoft, and GitHub OAuth with automatic session management - **MCP OAuth Provider** - Dynamic client registration for Claude.ai and Claude Code - **Cloudflare Workers** - Serverless deployment Published capability contract available. No trust telemetry is available yet. Last updated 2/24/2026.

Freshness

Last checked 2/22/2026

Best For

Contract is available with explicit auth and schema references.

Not Ideal For

google-calendar-mcp is not ideal for teams that need stronger public trust telemetry, lower setup complexity, or more explicit contract coverage before production rollout.

Evidence Sources Checked

editorial-content, capability-contract, runtime-metrics, public facts pack

Claim this agent
Agent DossierGitHubSafety: 100/100

google-calendar-mcp

MCP server for Google Calendar integration with multi-account OAuth support MCP Server Template for Cloudflare Workers A production-ready template for building MCP (Model Context Protocol) servers on Cloudflare Workers with better-auth social login. Features - **better-auth Social Login** - Google, Microsoft, and GitHub OAuth with automatic session management - **MCP OAuth Provider** - Dynamic client registration for Claude.ai and Claude Code - **Cloudflare Workers** - Serverless deployment

MCPverified

Public facts

6

Change events

1

Artifacts

0

Freshness

Feb 22, 2026

Verifiededitorial-content1 verified compatibility signal

Published capability contract available. No trust telemetry is available yet. Last updated 2/24/2026.

Schema refs publishedTrust evidence available

Trust score

Unknown

Compatibility

MCP

Freshness

Feb 22, 2026

Vendor

Jezweb

Artifacts

0

Benchmarks

0

Last release

1.0.0

Executive Summary

Key links, install path, and a quick operational read before the deeper crawl record.

Verifiededitorial-content

Summary

Published capability contract available. No trust telemetry is available yet. Last updated 2/24/2026.

Setup snapshot

git clone https://github.com/jezweb/google-calendar-mcp.git
  1. 1

    Setup complexity is MEDIUM. Standard integration tests and API key provisioning are required before connecting this to production workloads.

  2. 2

    Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data.

Evidence Ledger

Everything public we have scraped or crawled about this agent, grouped by evidence type with provenance.

Verifiededitorial-content
Vendor (1)

Vendor

Jezweb

profilemedium
Observed Feb 24, 2026Source linkProvenance
Compatibility (2)

Protocol compatibility

MCP

contracthigh
Observed Feb 24, 2026Source linkProvenance

Auth modes

mcp, api_key, oauth

contracthigh
Observed Feb 24, 2026Source linkProvenance
Artifact (1)

Machine-readable schemas

OpenAPI or schema references published

contracthigh
Observed Feb 24, 2026Source linkProvenance
Security (1)

Handshake status

UNKNOWN

trustmedium
Observed unknownSource linkProvenance
Integration (1)

Crawlable docs

6 indexed pages on the official domain

search_documentmedium
Observed Apr 15, 2026Source linkProvenance

Release & Crawl Timeline

Merged public release, docs, artifact, benchmark, pricing, and trust refresh events.

Self-declaredagent-index

Artifacts Archive

Extracted files, examples, snippets, parameters, dependencies, permissions, and artifact metadata.

Self-declaredGITHUB MCP

Extracted files

0

Examples

6

Snippets

0

Languages

typescript

Executable Examples

bash

# Copy this template to your new project
cp -r mcp-server-template-cloudflare my-new-mcp
cd my-new-mcp

# Install dependencies
npm install

jsonc

{
  "name": "my-new-mcp",  // Your worker name
  "kv_namespaces": [
    {
      "binding": "OAUTH_KV",
      "id": "YOUR_KV_NAMESPACE_ID"  // Create with: npx wrangler kv:namespace create OAUTH_KV
    }
  ],
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "my-mcp-db",
      "database_id": "YOUR_D1_DATABASE_ID"  // Create with: npx wrangler d1 create my-mcp-db
    }
  ],
  "durable_objects": {
    "bindings": [
      {
        "name": "MCP_OBJECT",
        "class_name": "MyMCP"  // Update if you rename the class
      }
    ]
  },
  "migrations": [
    {
      "tag": "v1",
      "new_sqlite_classes": ["MyMCP"]  // Must match class_name above
    }
  ],
  "vars": {
    "ENABLE_CONVERSATION_MEMORY": "true",  // D1-backed chat history
    "ENABLE_INTERNAL_AGENT": "false"       // ask_agent tool (for voice agents)
  }
}

bash

# Required: Google OAuth
echo "YOUR_GOOGLE_CLIENT_ID" | npx wrangler secret put GOOGLE_CLIENT_ID
echo "YOUR_GOOGLE_CLIENT_SECRET" | npx wrangler secret put GOOGLE_CLIENT_SECRET

# Required: better-auth session encryption
python3 -c "import secrets; print(secrets.token_hex(32))" | npx wrangler secret put BETTER_AUTH_SECRET

# Required: Cookie encryption for approved clients
python3 -c "import secrets; print(secrets.token_hex(32))" | npx wrangler secret put COOKIE_ENCRYPTION_KEY

# Optional: For Bearer token authentication
python3 -c "import secrets; print(secrets.token_urlsafe(32))" | npx wrangler secret put AUTH_TOKEN

# Optional: Microsoft Entra
# echo "YOUR_MS_CLIENT_ID" | npx wrangler secret put MICROSOFT_CLIENT_ID
# echo "YOUR_MS_CLIENT_SECRET" | npx wrangler secret put MICROSOFT_CLIENT_SECRET

# Optional: GitHub
# echo "YOUR_GH_CLIENT_ID" | npx wrangler secret put GITHUB_CLIENT_ID
# echo "YOUR_GH_CLIENT_SECRET" | npx wrangler secret put GITHUB_CLIENT_SECRET

bash

npx wrangler deploy

typescript

// Basic user info
const GOOGLE_SCOPES = 'openid email profile';

// Google Tasks
const GOOGLE_SCOPES = 'openid email profile https://www.googleapis.com/auth/tasks';

// Google Calendar (read-only)
const GOOGLE_SCOPES = 'openid email profile https://www.googleapis.com/auth/calendar.readonly';

// Gmail (read-only)
const GOOGLE_SCOPES = 'openid email profile https://www.googleapis.com/auth/gmail.readonly';

typescript

this.server.tool(
  'tool_name',                    // Unique identifier
  'Tool description.',            // Shown to Claude
  {
    param1: z.string().describe('Parameter description'),
    param2: z.number().optional().describe('Optional parameter'),
  },
  async ({ param1, param2 }) => {
    try {
      // For Google API calls, use authorizedFetch():
      const response = await this.authorizedFetch(
        `https://api.example.com/endpoint?param=${param1}`
      );

      if (!response.ok) {
        const error = await response.text();
        throw new Error(`API error: ${error}`);
      }

      const data = await response.json();

      return {
        content: [{ type: 'text', text: `Result: ${JSON.stringify(data)}` }],
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Unknown error';
      return {
        content: [{ type: 'text', text: `Error: ${message}` }],
        isError: true,
      };
    }
  }
);

Docs & README

Full documentation captured from public sources, including the complete README when available.

Self-declaredGITHUB MCP

Docs source

GITHUB MCP

Editorial quality

ready

MCP server for Google Calendar integration with multi-account OAuth support MCP Server Template for Cloudflare Workers A production-ready template for building MCP (Model Context Protocol) servers on Cloudflare Workers with better-auth social login. Features - **better-auth Social Login** - Google, Microsoft, and GitHub OAuth with automatic session management - **MCP OAuth Provider** - Dynamic client registration for Claude.ai and Claude Code - **Cloudflare Workers** - Serverless deployment

Full README

MCP Server Template for Cloudflare Workers

A production-ready template for building MCP (Model Context Protocol) servers on Cloudflare Workers with better-auth social login.

Features

  • better-auth Social Login - Google, Microsoft, and GitHub OAuth with automatic session management
  • MCP OAuth Provider - Dynamic client registration for Claude.ai and Claude Code
  • Cloudflare Workers - Serverless deployment with global edge distribution
  • D1 Database - SQLite-compatible database with Drizzle ORM
  • Durable Objects - Persistent MCP session storage
  • MCP Tools - Example tools with error handling patterns
  • MCP Resources - Read-only data exposure (future-ready for Claude.ai)
  • MCP Prompts - Templated prompt definitions (future-ready for Claude.ai)
  • Marketing homepage - Professional landing page in Jezweb style
  • Admin Dashboard - Manage tokens, view tools/resources/prompts
  • AI Chat Testing - Built-in AI chat to test MCP tools (Workers AI + external providers)
  • Multi-Provider AI - Workers AI (free), OpenAI, Anthropic, Google AI Studio
  • Conversation Memory - D1-backed persistent chat history with configurable TTL
  • Internal Agent - Optional ask_agent tool with Workers AI gatekeeper for voice agents

Quick Start

1. Clone and Install

# Copy this template to your new project
cp -r mcp-server-template-cloudflare my-new-mcp
cd my-new-mcp

# Install dependencies
npm install

2. Configure Cloudflare

Update wrangler.jsonc:

{
  "name": "my-new-mcp",  // Your worker name
  "kv_namespaces": [
    {
      "binding": "OAUTH_KV",
      "id": "YOUR_KV_NAMESPACE_ID"  // Create with: npx wrangler kv:namespace create OAUTH_KV
    }
  ],
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "my-mcp-db",
      "database_id": "YOUR_D1_DATABASE_ID"  // Create with: npx wrangler d1 create my-mcp-db
    }
  ],
  "durable_objects": {
    "bindings": [
      {
        "name": "MCP_OBJECT",
        "class_name": "MyMCP"  // Update if you rename the class
      }
    ]
  },
  "migrations": [
    {
      "tag": "v1",
      "new_sqlite_classes": ["MyMCP"]  // Must match class_name above
    }
  ],
  "vars": {
    "ENABLE_CONVERSATION_MEMORY": "true",  // D1-backed chat history
    "ENABLE_INTERNAL_AGENT": "false"       // ask_agent tool (for voice agents)
  }
}

3. Set Up OAuth Provider (Google)

  1. Go to Google Cloud Console
  2. Create a new project or select existing
  3. Enable the APIs you need (e.g., Google Tasks API, Calendar API)
  4. Go to "APIs & Services" → "Credentials"
  5. Create OAuth 2.0 Client ID (Web application)
  6. Add authorized redirect URI: https://your-worker.workers.dev/api/auth/callback/google

Note: better-auth uses /api/auth/callback/{provider} pattern for OAuth callbacks.

Alternative Providers (Microsoft Entra, GitHub):

  • See docs/BETTER_AUTH_ARCHITECTURE.md for setup instructions
  • Each provider requires its own OAuth app and secrets

4. Set Secrets

# Required: Google OAuth
echo "YOUR_GOOGLE_CLIENT_ID" | npx wrangler secret put GOOGLE_CLIENT_ID
echo "YOUR_GOOGLE_CLIENT_SECRET" | npx wrangler secret put GOOGLE_CLIENT_SECRET

# Required: better-auth session encryption
python3 -c "import secrets; print(secrets.token_hex(32))" | npx wrangler secret put BETTER_AUTH_SECRET

# Required: Cookie encryption for approved clients
python3 -c "import secrets; print(secrets.token_hex(32))" | npx wrangler secret put COOKIE_ENCRYPTION_KEY

# Optional: For Bearer token authentication
python3 -c "import secrets; print(secrets.token_urlsafe(32))" | npx wrangler secret put AUTH_TOKEN

# Optional: Microsoft Entra
# echo "YOUR_MS_CLIENT_ID" | npx wrangler secret put MICROSOFT_CLIENT_ID
# echo "YOUR_MS_CLIENT_SECRET" | npx wrangler secret put MICROSOFT_CLIENT_SECRET

# Optional: GitHub
# echo "YOUR_GH_CLIENT_ID" | npx wrangler secret put GITHUB_CLIENT_ID
# echo "YOUR_GH_CLIENT_SECRET" | npx wrangler secret put GITHUB_CLIENT_SECRET

5. Deploy

npx wrangler deploy

Customization

Update Server Identity

  1. src/index.ts: Update class name, server name, and tools
  2. src/oauth/google-handler.ts: Update GOOGLE_SCOPES and homepage content
  3. wrangler.jsonc: Update worker name and class references

Google OAuth Scopes

Edit GOOGLE_SCOPES in src/oauth/google-handler.ts:

// Basic user info
const GOOGLE_SCOPES = 'openid email profile';

// Google Tasks
const GOOGLE_SCOPES = 'openid email profile https://www.googleapis.com/auth/tasks';

// Google Calendar (read-only)
const GOOGLE_SCOPES = 'openid email profile https://www.googleapis.com/auth/calendar.readonly';

// Gmail (read-only)
const GOOGLE_SCOPES = 'openid email profile https://www.googleapis.com/auth/gmail.readonly';

Adding Tools

Add tools in the init() method of your MCP class:

this.server.tool(
  'tool_name',                    // Unique identifier
  'Tool description.',            // Shown to Claude
  {
    param1: z.string().describe('Parameter description'),
    param2: z.number().optional().describe('Optional parameter'),
  },
  async ({ param1, param2 }) => {
    try {
      // For Google API calls, use authorizedFetch():
      const response = await this.authorizedFetch(
        `https://api.example.com/endpoint?param=${param1}`
      );

      if (!response.ok) {
        const error = await response.text();
        throw new Error(`API error: ${error}`);
      }

      const data = await response.json();

      return {
        content: [{ type: 'text', text: `Result: ${JSON.stringify(data)}` }],
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Unknown error';
      return {
        content: [{ type: 'text', text: `Error: ${message}` }],
        isError: true,
      };
    }
  }
);

Adding Resources

Resources expose read-only data that LLMs can access. Add resources in the init() method:

this.server.resource(
  'resource_name',              // Unique identifier
  'mcp://my-mcp/resource-path', // URI for the resource
  {
    description: 'What this resource provides',
    mimeType: 'application/json',
  },
  async (uri) => ({
    contents: [{
      uri: uri.href,
      mimeType: 'application/json',
      text: JSON.stringify({
        // Your data here
      }, null, 2),
    }],
  })
);

Note: Claude.ai doesn't support resources yet (as of Dec 2025), but the API does. Adding resources now future-proofs your server.

Adding Prompts

Prompts are templated prompt definitions (like slash commands). Add prompts in the init() method:

this.server.prompt(
  'prompt_name',                // Unique identifier
  'Description of what this prompt does',
  {
    content: z.string().describe('Required parameter'),
    option: z.string().optional().describe('Optional parameter'),
  },
  async ({ content, option }) => ({
    messages: [{
      role: 'user',
      content: {
        type: 'text',
        text: option
          ? `Process this with ${option}: ${content}`
          : `Process this: ${content}`,
      },
    }],
  })
);

Note: Claude.ai doesn't support prompts yet (as of Dec 2025), but the API does. Adding prompts now future-proofs your server.

Admin Dashboard

Access the admin dashboard at /admin after logging in with Google OAuth.

Features:

  • View server info, tools, resources, and prompts
  • Create and manage Bearer auth tokens
  • AI Chat for testing MCP tools

Admin Setup:

Set admin emails (comma-separated):

echo "admin@example.com,user@example.com" | npx wrangler secret put ADMIN_EMAILS

AI Chat Testing

The admin dashboard includes an AI-powered tool tester:

  1. Click the chat bubble icon in the bottom-right corner
  2. Select an AI provider (Workers AI is free)
  3. Ask the AI to test tools, e.g., "test the hello tool with name John"

Supported Providers:

  • Workers AI (Free) - Llama 3.3 70B and other models, no API key needed
  • OpenAI - GPT-4o, GPT-4o-mini, o1
  • Anthropic - Claude 3.5 Sonnet, Claude 3.5 Haiku
  • Google AI Studio - Gemini 2.5 Pro, Gemini 2.5 Flash
  • Groq - Fast inference with Llama 3.3 70B

All external providers use AI Gateway's Compat endpoint - a single OpenAI-compatible API that works for all providers. The gateway handles format conversion automatically.

Setting up External Providers (BYOK - Recommended):

The easiest way is to configure API keys in AI Gateway (no code changes needed):

  1. Go to Cloudflare DashboardAIAI Gateway
  2. Create a gateway named default (or use existing)
  3. Enable Authenticated Gateway (required for BYOK)
  4. Go to Provider KeysAdd API Key
  5. Select provider (OpenAI, Anthropic, etc.) and enter your API key
  6. Create a Gateway Token: User API Tokens → Create → select AI Gateway permissions
  7. Set the token as a Worker secret: echo "token" | npx wrangler secret put CF_AIG_TOKEN
  8. Redeploy: npx wrangler deploy

Keys are securely stored and automatically injected into requests.

Alternative: Environment Secrets

You can also set API keys as Worker secrets (overrides BYOK):

# Anthropic
echo "sk-ant-..." | npx wrangler secret put ANTHROPIC_API_KEY

# OpenAI
echo "sk-..." | npx wrangler secret put OPENAI_API_KEY

# If using Authenticated Gateway, also set:
echo "your-gateway-token" | npx wrangler secret put CF_AIG_TOKEN

# Don't forget to redeploy after setting secrets!
npx wrangler deploy

Note: Workers AI is free and works out of the box. External providers go through Cloudflare AI Gateway for logging, caching, and centralized key management.

AI Gateway Features

The template uses AI Gateway's Compat endpoint - a single OpenAI-compatible API for all providers. Additional features available:

Per-Request Headers (add to your AI calls): | Header | Purpose | Example | |--------|---------|---------| | cf-aig-cache-ttl | Cache responses (seconds) | 3600 = 1 hour | | cf-aig-skip-cache | Bypass cache | true | | cf-aig-request-timeout | Trigger fallback if slow (ms) | 10000 | | cf-aig-metadata | Tag for analytics | {"userId":"..."} |

Response Headers (check after AI calls): | Header | Meaning | |--------|---------| | cf-aig-cache-status | HIT or MISS | | cf-aig-step | Which fallback was used (0 = primary) |

Dashboard-Only Features (configure in Cloudflare dashboard):

  • Guardrails - Content filtering, prompt injection detection
  • DLP - Detect PII, secrets, source code in prompts/responses
  • Rate Limiting - Gateway-level request limits
  • Dynamic Routing - A/B testing, geographic routing, user-based routing
  • Analytics - Usage metrics, costs, error rates

See AI Gateway docs for details.

Architecture

src/
├── index.ts              # Main MCP class with tools, resources, prompts + helper methods
├── types.ts              # TypeScript interfaces (Env, Props, ToolMetadata, ChatMessage)
│
├── lib/
│   ├── auth.ts           # better-auth configuration (social providers, OAuth Provider plugin)
│   ├── db/
│   │   ├── index.ts      # Drizzle D1 database setup
│   │   └── schema.ts     # better-auth tables + custom tables (Drizzle ORM)
│   ├── ai/
│   │   ├── index.ts      # AI Gateway client
│   │   ├── providers.ts  # Provider/model registry
│   │   └── openrouter.ts # Dynamic model fetching from OpenRouter
│   ├── memory/
│   │   └── index.ts      # D1-backed conversation memory
│   ├── agent/
│   │   └── index.ts      # Internal agent pattern (Workers AI gatekeeper)
│   ├── crypto.ts         # Timing-safe token comparison
│   └── rate-limit.ts     # KV-based rate limiting
│
├── admin/
│   ├── routes.ts         # Admin API endpoints
│   ├── ui.ts             # Admin dashboard HTML/CSS/JS
│   ├── chat.ts           # AI chat handler with tool execution + D1 memory
│   ├── middleware.ts     # Admin auth middleware
│   ├── session.ts        # Admin session management
│   └── tokens.ts         # Bearer token CRUD
│
├── oauth/                # MCP OAuth protocol handlers
│   ├── better-auth-handler.ts   # OAuth routes via better-auth sessions
│   └── workers-oauth-utils.ts   # CSRF, state, approval dialog utilities
│
├── pages/
│   ├── homepage.ts       # Server homepage (marketing landing page)
│   └── login.ts          # Social login page (Google, Microsoft, GitHub)
│
├── tools/
│   ├── index.ts          # Tool registry (single source of truth)
│   ├── types.ts          # Tool type definitions
│   ├── utility.ts        # Utility tools (no auth)
│   ├── user.ts           # User tools (require OAuth)
│   └── examples.ts       # Example API call patterns
│
├── resources/
│   ├── index.ts          # Resource registry
│   ├── types.ts          # Resource type definitions
│   └── server.ts         # Server info resources
│
├── prompts/
│   ├── index.ts          # Prompt registry
│   ├── types.ts          # Prompt type definitions
│   └── templates.ts      # Prompt templates
│
└── migrations/
    ├── 0001_better_auth_tables.sql    # better-auth core tables (user, session, account, etc.)
    ├── 0002_custom_tables.sql         # Custom tables (conversation memory, tool execution)
    └── 0003_add_jwks_table.sql        # JWT key rotation table (better-auth v1.4.0)

Key Components

  • MyMCP class: Extends McpAgent with your tools, resources, and prompts
  • ensureValidToken(): Automatically refreshes expired tokens
  • authorizedFetch(): Wrapper for API calls with auth
  • BetterAuthHandler: Hono app handling OAuth routes via better-auth
  • createAuth(): better-auth instance factory with D1 + Drizzle

Included Examples

Utility Tools (no auth required): | Name | Description | |------|-------------| | hello | Simple greeting | | get_current_time | Current date/time in various timezones | | generate_uuid | Generate UUID v4 (1-10) | | base64 | Encode/decode Base64 strings | | text_stats | Count words, characters, lines | | random_number | Generate random numbers in range | | json_format | Format/validate JSON | | hash_text | Generate SHA-256 hash |

User Tools (require OAuth): | Name | Description | |------|-------------| | get_user_info | Returns authenticated user's Google info | | list_my_conversations | List your conversation history |

Example Tools: | Name | Description | |------|-------------| | example_api_call | Demonstrates authorizedFetch() pattern |

Resources (read-only data): | Name | Description | |------|-------------| | server_info | Server metadata and capabilities | | user_profile | Authenticated user's profile |

Prompts (templates): | Name | Description | |------|-------------| | summarize | Content summarization template | | analyze | Content analysis template (sentiment/technical/business) |

Conversation Memory

The template includes optional D1-backed conversation memory for persistent chat history.

Setup:

# 1. Create D1 database
npx wrangler d1 create my-mcp-db

# 2. Add database_id to wrangler.jsonc d1_databases section

# 3. Run migrations
npx wrangler d1 execute my-mcp-db --local --file=migrations/0001_conversations.sql
npx wrangler d1 execute my-mcp-db --remote --file=migrations/0001_conversations.sql

# 4. Enable in wrangler.jsonc vars
"ENABLE_CONVERSATION_MEMORY": "true"

Configuration:

| Variable | Default | Description | |----------|---------|-------------| | ENABLE_CONVERSATION_MEMORY | false | Enable D1 conversation storage | | CONVERSATION_TTL_HOURS | 168 | Auto-delete conversations after 7 days | | MAX_CONTEXT_MESSAGES | 50 | Max messages to load for context |

When disabled, falls back to KV storage (backwards compatible).

Internal Agent

The template includes an optional internal agent pattern for voice agents (e.g., ElevenLabs) and prompt injection protection.

When enabled, the server exposes an ask_agent tool that wraps all other tools behind a Workers AI gatekeeper.

Enable:

// In wrangler.jsonc vars
"ENABLE_INTERNAL_AGENT": "true",
"INTERNAL_AGENT_MODEL": "@cf/qwen/qwen2.5-coder-32b-instruct"

How it works:

  1. External caller uses only ask_agent tool with natural language query
  2. Workers AI gatekeeper validates the request
  3. Internal agent selects and calls appropriate tools
  4. Clean response returned (no raw tool exposure)

Benefits:

  • Security layer against prompt injection from audio
  • Minimal context passed to inner agent (fast)
  • All tools available through single interface

Configuration:

| Variable | Default | Description | |----------|---------|-------------| | ENABLE_INTERNAL_AGENT | false | Enable ask_agent tool | | INTERNAL_AGENT_MODEL | @cf/qwen/qwen2.5-coder-32b-instruct | Workers AI gatekeeper model |

Token Refresh

The template includes automatic token refresh:

  1. authorizedFetch() calls ensureValidToken() before each request
  2. If token expires within 5 minutes, it's refreshed proactively
  3. New tokens are persisted to Durable Object storage
  4. 401 responses invalidate the stored token

This prevents sessions from disconnecting after 1 hour (Google token expiry).

Testing

Local Development

npx wrangler dev

Test with curl

# Test MCP endpoint (requires AUTH_TOKEN secret set)
curl -X POST "https://your-worker.workers.dev/mcp" \
  -H "Authorization: Bearer YOUR_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'

Dependencies

  • @cloudflare/workers-oauth-provider - OAuth 2.0 provider for Workers
  • @modelcontextprotocol/sdk - MCP protocol implementation
  • agents - McpAgent base class with Durable Object integration
  • hono - Lightweight web framework for OAuth routes
  • zod - Schema validation for tool parameters

Security

The template includes multiple security layers:

XSS Protection:

  • HTML escaping for all dynamic content in admin dashboard
  • Data attributes with event delegation (no inline onclick handlers)
  • Content Security Policy headers on admin routes

Session Security:

  • SameSite=Strict cookies prevent CSRF attacks
  • Timing-safe token comparison prevents timing attacks
  • Secure, HttpOnly cookies for admin sessions

Input Validation:

  • All tool inputs have max length limits (1MB default)
  • Chat message size limit (100KB)
  • Safe JSON parsing with fallbacks

Rate Limiting:

  • Admin chat: 30 requests/minute per user
  • Token creation: 10/hour per user

Access Control:

  • User-owned conversations (OAuth email verification)
  • Admin-only dashboard routes
  • Bearer token authentication for programmatic access

Future MCP Features

See docs/MCP_FEATURES_PLAN.md for planning around:

  • Tool Search - defer_loading for 85% token reduction (10+ tools)
  • Sampling - Server requests LLM completion from client (agentic workflows)
  • Completions - Autocomplete for prompt/resource arguments

License

MIT License - See LICENSE for details.


Built by Jezweb — AI agents, MCP servers, and business automation.

Contract & API

Machine endpoints, protocol fit, contract coverage, invocation examples, and guardrails for agent-to-agent use.

Verifiedcapability-contract

Contract coverage

Status

ready

Auth

mcp, api_key, oauth

Streaming

Yes

Data region

global

Protocol support

MCP: verified

Requires: mcp, lang:typescript, streaming

Forbidden: none

Guardrails

Operational confidence: medium

Contract is available with explicit auth and schema references.
Trust confidence is not low and verification freshness is acceptable.
Protocol support is explicitly confirmed in contract metadata.
Invocation examples
curl -s "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/snapshot"
curl -s "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/contract"
curl -s "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/trust"

Reliability & Benchmarks

Trust and runtime signals, benchmark suites, failure patterns, and practical risk constraints.

Missingruntime-metrics

Trust signals

Handshake

UNKNOWN

Confidence

unknown

Attempts 30d

unknown

Fallback rate

unknown

Runtime metrics

Observed P50

unknown

Observed P95

unknown

Rate limit

unknown

Estimated cost

unknown

No benchmark suites or observed failure patterns are available.

Media & Demo

Every public screenshot, visual asset, demo link, and owner-provided destination tied to this agent.

Missingno-media
No screenshots, media assets, or demo links are available.

Related Agents

Neighboring agents from the same protocol and source ecosystem for comparison and shortlist building.

Self-declaredprotocol-neighbors
GITLAB_AI_CATALOGgitlab-mcp

Rank

83

A Model Context Protocol (MCP) server for GitLab

Traction

No public download signal

Freshness

Updated 2d ago

MCP
GITLAB_PUBLIC_PROJECTSgitlab-mcp

Rank

80

A Model Context Protocol (MCP) server for GitLab

Traction

No public download signal

Freshness

Updated 2d ago

MCP
GITLAB_AI_CATALOGrmcp-openapi

Rank

74

Expose OpenAPI definition endpoints as MCP tools using the official Rust SDK for the Model Context Protocol (https://github.com/modelcontextprotocol/rust-sdk)

Traction

No public download signal

Freshness

Updated 2d ago

MCP
GITLAB_AI_CATALOGrmcp-actix-web

Rank

72

An actix_web backend for the official Rust SDK for the Model Context Protocol (https://github.com/modelcontextprotocol/rust-sdk)

Traction

No public download signal

Freshness

Updated 2d ago

MCP
Machine Appendix

Contract JSON

{
  "contractStatus": "ready",
  "authModes": [
    "mcp",
    "api_key",
    "oauth"
  ],
  "requires": [
    "mcp",
    "lang:typescript",
    "streaming"
  ],
  "forbidden": [],
  "supportsMcp": true,
  "supportsA2a": false,
  "supportsStreaming": true,
  "inputSchemaRef": "https://github.com/jezweb/google-calendar-mcp#input",
  "outputSchemaRef": "https://github.com/jezweb/google-calendar-mcp#output",
  "dataRegion": "global",
  "contractUpdatedAt": "2026-02-24T19:45:40.612Z",
  "sourceUpdatedAt": "2026-02-24T19:45:40.612Z",
  "freshnessSeconds": 4435425
}

Invocation Guide

{
  "preferredApi": {
    "snapshotUrl": "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/snapshot",
    "contractUrl": "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/contract",
    "trustUrl": "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/trust"
  },
  "curlExamples": [
    "curl -s \"https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/snapshot\"",
    "curl -s \"https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/contract\"",
    "curl -s \"https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/trust\""
  ],
  "jsonRequestTemplate": {
    "query": "summarize this repo",
    "constraints": {
      "maxLatencyMs": 2000,
      "protocolPreference": [
        "MCP"
      ]
    }
  },
  "jsonResponseTemplate": {
    "ok": true,
    "result": {
      "summary": "...",
      "confidence": 0.9
    },
    "meta": {
      "source": "GITHUB_MCP",
      "generatedAt": "2026-04-17T03:49:26.563Z"
    }
  },
  "retryPolicy": {
    "maxAttempts": 3,
    "backoffMs": [
      500,
      1500,
      3500
    ],
    "retryableConditions": [
      "HTTP_429",
      "HTTP_503",
      "NETWORK_TIMEOUT"
    ]
  }
}

Trust JSON

{
  "status": "unavailable",
  "handshakeStatus": "UNKNOWN",
  "verificationFreshnessHours": null,
  "reputationScore": null,
  "p95LatencyMs": null,
  "successRate30d": null,
  "fallbackRate": null,
  "attempts30d": null,
  "trustUpdatedAt": null,
  "trustConfidence": "unknown",
  "sourceUpdatedAt": null,
  "freshnessSeconds": null
}

Capability Matrix

{
  "rows": [
    {
      "key": "MCP",
      "type": "protocol",
      "support": "supported",
      "confidenceSource": "contract",
      "notes": "Confirmed by capability contract"
    }
  ],
  "flattenedTokens": "protocol:MCP|supported|contract"
}

Facts JSON

[
  {
    "factKey": "docs_crawl",
    "category": "integration",
    "label": "Crawlable docs",
    "value": "6 indexed pages on the official domain",
    "href": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
    "sourceUrl": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
    "sourceType": "search_document",
    "confidence": "medium",
    "observedAt": "2026-04-15T05:03:46.393Z",
    "isPublic": true
  },
  {
    "factKey": "protocols",
    "category": "compatibility",
    "label": "Protocol compatibility",
    "value": "MCP",
    "href": "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/contract",
    "sourceUrl": "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/contract",
    "sourceType": "contract",
    "confidence": "high",
    "observedAt": "2026-02-24T19:45:40.612Z",
    "isPublic": true
  },
  {
    "factKey": "auth_modes",
    "category": "compatibility",
    "label": "Auth modes",
    "value": "mcp, api_key, oauth",
    "href": "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/contract",
    "sourceUrl": "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/contract",
    "sourceType": "contract",
    "confidence": "high",
    "observedAt": "2026-02-24T19:45:40.612Z",
    "isPublic": true
  },
  {
    "factKey": "schema_refs",
    "category": "artifact",
    "label": "Machine-readable schemas",
    "value": "OpenAPI or schema references published",
    "href": "https://github.com/jezweb/google-calendar-mcp#input",
    "sourceUrl": "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/contract",
    "sourceType": "contract",
    "confidence": "high",
    "observedAt": "2026-02-24T19:45:40.612Z",
    "isPublic": true
  },
  {
    "factKey": "vendor",
    "category": "vendor",
    "label": "Vendor",
    "value": "Jezweb",
    "href": "https://github.com/jezweb/google-calendar-mcp",
    "sourceUrl": "https://github.com/jezweb/google-calendar-mcp",
    "sourceType": "profile",
    "confidence": "medium",
    "observedAt": "2026-02-24T19:43:14.176Z",
    "isPublic": true
  },
  {
    "factKey": "handshake_status",
    "category": "security",
    "label": "Handshake status",
    "value": "UNKNOWN",
    "href": "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/trust",
    "sourceUrl": "https://xpersona.co/api/v1/agents/mcp-jezweb-google-calendar-mcp/trust",
    "sourceType": "trust",
    "confidence": "medium",
    "observedAt": null,
    "isPublic": true
  }
]

Change Events JSON

[
  {
    "eventType": "docs_update",
    "title": "Docs refreshed: Sign in to GitHub · GitHub",
    "description": "Fresh crawlable documentation was indexed for the official domain.",
    "href": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
    "sourceUrl": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
    "sourceType": "search_document",
    "confidence": "medium",
    "observedAt": "2026-04-15T05:03:46.393Z",
    "isPublic": true
  }
]

Sponsored

Ads related to google-calendar-mcp and adjacent AI workflows.