Skip to main content
Glama
nigamgoyal

governed-calendar-agent

by nigamgoyal

Governed Calendar Agent

A working proof of concept: Claude given scoped, auditable write access to a principal's calendar and project system.

Built to answer one question — how do you let an LLM touch a busy executive's calendar without anyone having to trust it blindly? The answer here is four mechanisms, all demonstrable in about five minutes:

Mechanism

What it means in practice

Propose, don't act

Claude produces a plan. Planning writes nothing, ever.

Dry run as consent

The plan renders as a plain-English diff. Approval is a separate, explicit step.

Stated preferences are binding

The principal's rules are data, and the planner cannot propose anything that violates them.

Every action is evidence

Who, what, exact parameters, before state, after state, outcome — in Postgres, append-only.

Two rules do most of the work:

  1. The agent reschedules what it owns; it flags what it does not. It will move an internal prep block. It will not move a meeting organised by an outside party, because that emails a counterparty in the principal's name. Those are surfaced for a human decision instead.

  2. Failure is loud. A retry cannot double-book, a half-applied plan never reports success, and an expired credential raises an alert rather than quietly dropping writes.


Run it

Requires Python 3.11+ and a local PostgreSQL.

./run_demo.sh

That resets the database, seeds a realistic week, and walks all eleven steps — ending by deliberately expiring the calendar credential to show the alert fire.

PYTHONPATH=src ./.venv/bin/python -m pytest tests -q      # 20 tests
PYTHONPATH=src ./.venv/bin/python -m gca.cli week         # the seeded week
PYTHONPATH=src ./.venv/bin/python -m gca.cli audit        # the trail
PYTHONPATH=src ./.venv/bin/python -m gca.cli break calendar auth_expired

Related MCP server: Mariana Google MCP

Connect it to Claude

Copy claude_desktop_config.example.json into your Claude Desktop config, replacing the two absolute paths. Then ask, in plain English:

"Give Project Atlas four hours this week."

Claude calls propose_plan, shows you the diff, and waits. Nothing is written until you say so.


The MCP surface

Tool design is the governance boundary. Note what is deliberately absent: no generic run_sql, no graph_request, no unscoped delete. Claude can only express intents the server already knows how to make safe.

Tool

Writes?

Purpose

get_week

no

Calendar + tasks for a week

get_preferences

no

The principal's stored rules

propose_plan

no

Turns an intent into a reviewable plan

apply_plan

only with dry_run=false

Executes an approved plan, idempotently

get_audit_trail

no

Who did what, before and after

health_check

no

Every connected system; alerts on failure

set_preference

config only

Change a rule, fully audited

Architecture

Claude  ──MCP/stdio──▶  server.py          seven scoped tools, dry-run by default
                            │
                            ├─▶ planner.py     intent ─▶ plan. READ ONLY.
                            │      └── preferences.py   the binding rules
                            ├─▶ diff.py        plan ─▶ a diff a human can approve
                            ├─▶ engine.py      the ONLY path that mutates anything
                            │      ├── audit.py    before/after + idempotency keys
                            │      └── health.py   alerting on any provider failure
                            └─▶ providers/
                                   ├── sandbox.py       persistent demo tenant
                                   ├── graph.py         Microsoft Graph (Outlook)
                                   └── clickup_api.py   ClickUp
                                              │
                                        PostgreSQL
                    preferences · plans · audit_log · system_events

Providers sit behind one contract, so the demo tenant and the principal's real Outlook are interchangeable. Going to production is an environment change, not a rewrite: set GCA_CALENDAR_PROVIDER=graph and supply credentials.

What this POC does not yet do

Stated plainly, because a POC that pretends to be a product is worse than no POC:

  • No event-driven sync loop yet (n8n / Power Automate). Reconciliation here is pull-based and manual.

  • No OAuth device-code flow for the personal-tenant consent journey.

  • Recurring events are treated as individual instances.

  • The alert sink is a webhook. Production wants a real on-call path.

  • The sandbox provider models auth failure, unreachability and etags, but not Graph's full concurrency semantics.

Documentation

  • RUNBOOK.md — operating, diagnosing and taking this over

  • DEMO.md — the five-minute script

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nigamgoyal/governed-calendar-agent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server