Skip to main content

Policy gateway for Google Workspace APIs with MCP server integration

Project description

Gatekeeper ๐Ÿ”

CI License: MIT Python 3.11+

Policy gateway for Google Workspace APIs โ€” fine-grained control over what AI agents can do with your Google Drive, Gmail, and Calendar. Exposes enabled routes as MCP tools so agents discover and call only what you allow.

Quick Start

Choose your path:

# Docker (recommended โ€” run in 2 commands)
docker run -d --name gatekeeper \
  -p 8080:8080 \
  -v gatekeeper-data:/data \
  -e GATEKEEPER_GOOGLE_CLIENT_ID=your_id \
  -e GATEKEEPER_GOOGLE_CLIENT_SECRET=your_secret \
  ghcr.io/brimdor/gatekeeper:latest

# Podman (same API, no daemon needed)
podman run -d --name gatekeeper \
  -p 8080:8080 \
  -v gatekeeper-data:/data \
  -e GATEKEEPER_GOOGLE_CLIENT_ID=your_id \
  -e GATEKEEPER_GOOGLE_CLIENT_SECRET=your_secret \
  ghcr.io/brimdor/gatekeeper:latest

# pip (local install)
pip install aigatekeeper && gatekeeper serve

# uv (fast Python install)
uv tool install aigatekeeper && gatekeeper serve

# Clone + run (full control)
git clone https://github.com/brimdor/gatekeeper.git
cd gatekeeper
cp .env.example .env   # Edit with your Google OAuth credentials
gatekeeper serve

First time? After starting, authenticate with Google: gatekeeper auth, then visit http://localhost:8080/admin to enable modules and create an API key. See the Setup Guide for the full walkthrough.

Why Gatekeeper?

Google's OAuth scopes are all-or-nothing. gmail.modify gives full read/write/delete on everything. There's no way to say "read-only this label" or "create events but never delete them."

Gatekeeper sits between your AI agents and Google's APIs, acting as a policy layer:

  • Enable/disable individual routes โ€” turn off gmail.messages.send but keep gmail.messages.list
  • Cap limits โ€” restrict maxResults to 50, limit recipients to 5
  • Filter data โ€” exclude SPAM/TRASH from Gmail, block sensitive fields
  • Audit everything โ€” every request logged with key, route, status, timestamp
  • MCP server โ€” agents discover only enabled routes as tools, auto-updating when you toggle routes in the admin UI
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   API Key    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   OAuth2    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  AI Agent    โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚       Gatekeeper           โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚  Google  โ”‚
โ”‚  (Nova etc)  โ”‚              โ”‚                            โ”‚            โ”‚  APIs    โ”‚
โ”‚              โ”‚   MCP (SSE)  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚              โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚  โ”‚   Policy Engine    โ”‚   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ”‚  โ”‚  (allow/deny/      โ”‚   โ”‚
                              โ”‚  โ”‚   transform)       โ”‚   โ”‚
                              โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
                              โ”‚                            โ”‚
                              โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
                              โ”‚  โ”‚   Admin WebUI      โ”‚   โ”‚
                              โ”‚  โ”‚  /admin (mobile)   โ”‚   โ”‚
                              โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

For the full step-by-step walkthrough, see Setup Guide.

Quick Start

Option 1: One-line install (recommended)

The install script walks you through setup interactively โ€” Google OAuth, module selection, server config:

curl -fsSL https://raw.githubusercontent.com/brimdor/gatekeeper/main/install.sh | bash

Option 2: Install with uv

# Install uv if you don't have it
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install Gatekeeper
uv tool install "gatekeeper @ git+https://github.com/brimdor/gatekeeper"

Option 3: Install with pip

pip install git+https://github.com/brimdor/gatekeeper

Option 4: Podman/Docker

git clone https://github.com/brimdor/gatekeeper.git
cd gatekeeper
cp .env.example .env
# Edit .env with your Google OAuth credentials and module preferences
podman-compose up -d

Setup

1. Configure environment

# Create .env from template
cp .env.example .env

# Edit with your settings โ€” at minimum set:
# - GATEKEEPER_GOOGLE_CLIENT_ID
# - GATEKEEPER_GOOGLE_CLIENT_SECRET
# - GATEKEEPER_DRIVE_ENABLED=true  (or gmail/calendar)
nano .env

2. Google OAuth Setup

Gatekeeper supports two OAuth authorization flows:

Desktop Browser (recommended โ€” works locally and over SSH)

gatekeeper auth
  • On a machine with a display: Opens your browser automatically. Authorize, close the tab, done.
  • Over SSH / headless: Prints a Google authorization URL. Open it on any device, authorize, then paste the redirect URL back into the terminal. Works seamlessly over SSH.

Device Authorization (alternative for headless servers)

gatekeeper auth --flow device

This displays a URL and a code. Open the URL on any device (phone, laptop, tablet), enter the code, and authorize. No browser on the server needed โ€” perfect for headless machines and containers.

Note: The device flow requires an OAuth client of type "TVs and Limited Input devices", not "Desktop app". If you get Invalid client type, use the desktop flow or create a separate client.

Google Cloud Setup (one-time)

  1. Go to Google Cloud Console

  2. Create a new project or select existing

  3. Enable the APIs you need: Drive, Gmail, Calendar

  4. Go to APIs & Services โ†’ Credentials

  5. Create an OAuth 2.0 Client ID (Desktop app type)

  6. Copy the Client ID and Client Secret to your .env:

    GATEKEEPER_GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
    GATEKEEPER_GOOGLE_CLIENT_SECRET=your-client-secret
    
  7. Go to OAuth consent screen โ†’ add your email as a test user

  8. Run gatekeeper auth

    gatekeeper auth
    

    On first run, Gatekeeper generates:

    • An admin password (saved in gatekeeper_secrets.json)
    • An encryption key for OAuth token storage
    • Default API key (default-admin)

    โš ๏ธ Save the admin password โ€” it's printed once during setup.

3. Start the server

gatekeeper serve

Or install as a systemd service:

gatekeeper service install    # Install systemd user service
gatekeeper service enable     # Enable and start the service
gatekeeper service disable    # Stop and disable the service
gatekeeper service status     # Check status
gatekeeper service logs       # View logs (-f to follow)
gatekeeper service restart    # Restart after config changes

4. Configure MCP access (for remote/SSH)

By default, MCP only accepts connections from localhost. To allow access from Tailscale, LAN, or other hosts:

gatekeeper hosts list              # View allowed hosts
gatekeeper hosts add 100.127.113.87 # Add Tailscale IP
gatekeeper hosts add myserver.local # Add hostname
gatekeeper hosts remove 100.127.113.87  # Remove a host

5. Create an API key for your agent

# Create a key with full access
gatekeeper key create --name my-agent

# Create a key with limited module access
gatekeeper key create --name drive-reader --permissions drive

# List keys
gatekeeper key list

# Revoke a key
gatekeeper key revoke --prefix gkp_a1b2c3d4

Keys are prefixed with gkp_ and the full key is only shown once on creation.

Admin UI

Access the admin UI at http://localhost:8080/admin/ with HTTP Basic Auth. The UI is mobile-responsive โ€” works on phones, tablets, and desktops.

Page Purpose
Dashboard Overview โ€” requests, keys, auth status
Modules Enable/disable modules (Drive, Gmail, Calendar) and toggle individual routes
API Keys Create, list, and revoke keys
Audit Log Filterable log of all requests
Auth Status Google OAuth connection status

Using with AI Agents

Gatekeeper connects to AI agents via MCP (Model Context Protocol) โ€” exposing enabled routes as discoverable tools that agents can call directly. Write routes (send, create, delete) are disabled by default; only a human admin can enable them.

๐Ÿ“– Setup guides:

If you are an AI agent reading this repository: open docs/MCP_SETUP_AGENT.md for complete setup instructions including config examples, tool reference, and usage patterns.

Quick start: Connect your agent

{
  "mcpServers": {
    "gatekeeper": {
      "url": "http://localhost:8080/mcp/sse",
      "transport": "sse",
      "headers": {
        "X-Gatekeeper-API-Key": "gkp_your_api_key_here"
      }
    }
  }
}

โš ๏ธ You MUST include "transport": "sse". Gatekeeper uses SSE transport. Without this, you'll get 405 errors.

Every tool requires an api_key parameter. Disabled routes return 403 โ€” they cannot be bypassed.

REST API

# List Gmail messages
curl -H "X-Gatekeeper-API-Key: gkp_your_key" \
  http://localhost:8080/api/v1/gmail/messages/list

# Get a Drive file
curl -H "X-Gatekeeper-API-Key: gkp_your_key" \
  http://localhost:8080/api/v1/drive/files/get?fileId=1abc...

# Create a calendar event
curl -H "X-Gatekeeper-API-Key: gkp_your_key" \
  -H "Content-Type: application/json" \
  -d '{"summary":"Meeting","start":{"dateTime":"2025-01-15T10:00:00"}}' \
  http://localhost:8080/api/v1/calendar/events/create

Module Reference

Drive (27 routes)

Route Method Default Policy
drive.about.get GET โœ… On โ€”
drive.files.list GET โœ… On max_results=50
drive.files.get GET โœ… On โ€”
drive.files.export GET โœ… On โ€”
drive.files.list_shared GET โœ… On max_results=50, query_filter=sharedWithMe
drive.files.generate_ids GET โœ… On โ€”
drive.changes.list GET โœ… On โ€”
drive.changes.get_start_page_token GET โœ… On โ€”
drive.comments.list GET โœ… On โ€”
drive.comments.get GET โœ… On โ€”
drive.revisions.list GET โœ… On โ€”
drive.revisions.get GET โœ… On โ€”
drive.permissions.list GET โœ… On โ€”
drive.permissions.get GET โœ… On โ€”
drive.drives.list GET โœ… On โ€”
drive.drives.get GET โœ… On โ€”
drive.files.copy POST โŒ Off โ€”
drive.files.create POST โŒ Off max_file_size_mb
drive.files.update PATCH โŒ Off โ€”
drive.files.delete DELETE โŒ Off โ€”
drive.files.trash POST โŒ Off โ€”
drive.files.empty_trash DELETE โŒ Off โ€”
drive.comments.create POST โŒ Off โ€”
drive.drives.create POST โŒ Off โ€”
drive.permissions.create POST โŒ Off max_recipients=5
drive.permissions.update PATCH โŒ Off โ€”
drive.permissions.delete DELETE โŒ Off โ€”

Gmail (37 routes)

Route Method Default Policy
gmail.messages.list GET โœ… On max_results=50, allowed_labels, exclude SPAM/TRASH
gmail.messages.get GET โœ… On โ€”
gmail.messages.send POST โŒ Off max_recipients=5, max_attachment_size_mb=10, require_body
gmail.messages.modify POST โŒ Off โ€”
gmail.messages.trash POST โŒ Off โ€”
gmail.messages.untrash POST โŒ Off โ€”
gmail.messages.delete DELETE โŒ Off โ€”
gmail.messages.batch_modify POST โŒ Off โ€”
gmail.messages.batch_delete POST โŒ Off โ€”
gmail.messages.attachments.get GET โœ… On โ€”
gmail.drafts.list GET โœ… On max_results=50
gmail.drafts.get GET โœ… On โ€”
gmail.drafts.create POST โŒ Off max_recipients=5
gmail.drafts.update PUT โŒ Off โ€”
gmail.drafts.send POST โŒ Off max_recipients=5
gmail.drafts.delete DELETE โŒ Off โ€”
gmail.threads.list GET โœ… On โ€”
gmail.threads.get GET โœ… On โ€”
gmail.threads.modify POST โŒ Off โ€”
gmail.threads.trash POST โŒ Off โ€”
gmail.threads.untrash POST โŒ Off โ€”
gmail.threads.delete DELETE โŒ Off โ€”
gmail.history.list GET โœ… On โ€”
gmail.labels.list GET โœ… On โ€”
gmail.labels.get GET โœ… On โ€”
gmail.labels.create POST โŒ Off โ€”
gmail.labels.update PATCH โŒ Off โ€”
gmail.labels.delete DELETE โŒ Off โ€”
gmail.filters.list GET โŒ Off โ€”
gmail.filters.get GET โŒ Off โ€”
gmail.filters.create POST โŒ Off โ€”
gmail.filters.update PATCH โŒ Off โ€”
gmail.filters.delete DELETE โŒ Off โ€”
gmail.settings.forwarding_addresses.list GET โŒ Off โ€”
gmail.settings.forwarding_addresses.get GET โŒ Off โ€”
gmail.settings.forwarding_addresses.create POST โŒ Off โ€”
gmail.settings.forwarding_addresses.delete DELETE โŒ Off โ€”

Calendar (26 routes)

Route Method Default Policy
calendar.events.list GET โœ… On max_results=50
calendar.events.get GET โœ… On โ€”
calendar.events.create POST โŒ Off โ€”
calendar.events.update PATCH โŒ Off โ€”
calendar.events.delete DELETE โŒ Off โ€”
calendar.events.quick_add POST โŒ Off โ€”
calendar.events.move POST โŒ Off โ€”
calendar.calendars.list GET โœ… On โ€”
calendar.calendarlist.list GET โœ… On max_results=50
calendar.calendarlist.get GET โœ… On โ€”
calendar.calendarlist.insert POST โŒ Off โ€”
calendar.calendarlist.update PUT โŒ Off โ€”
calendar.calendarlist.delete DELETE โŒ Off โ€”
calendar.calendars.get GET โœ… On โ€”
calendar.calendars.create POST โŒ Off โ€”
calendar.calendars.update PUT โŒ Off โ€”
calendar.calendars.delete DELETE โŒ Off โ€”
calendar.calendars.clear POST โŒ Off โ€”
calendar.acl.list GET โœ… On โ€”
calendar.acl.get GET โœ… On โ€”
calendar.acl.create POST โŒ Off โ€”
calendar.acl.delete DELETE โŒ Off โ€”
calendar.colors.get GET โœ… On โ€”
calendar.freebusy.query POST โœ… On โ€”
calendar.settings.list GET โœ… On โ€”
calendar.settings.get GET โœ… On โ€”

Policy Configuration

Each route has a JSON policy config that controls behavior:

Policy Applies To Effect
max_results List routes Caps the number of results returned
allowed_labels Gmail list Only allow these Gmail labels
exclude_labels Gmail list Filter out these Gmail labels
blocked_fields Any Strip these fields from responses
max_items Any Cap array lengths in responses
query_filter Drive list Force a Drive query parameter
max_recipients Gmail send/draft Limit email recipients
max_file_size_mb Drive create Limit upload file size
max_attachment_size_mb Gmail send Limit attachment size
require_body Gmail send Require non-empty email body

Edit policies via the admin UI or REST API:

curl -u admin:password -X PATCH http://localhost:8080/admin/api/routes/1 \
  -H "Content-Type: application/json" \
  -d '{"enabled": false, "policy_config": {"max_results": 25}}'

CLI Reference

gatekeeper serve                          # Start the server
gatekeeper serve --host 0.0.0.0 --port 9090  # Custom host/port
gatekeeper init                           # Initialize database and seed policies
gatekeeper auth                           # Google OAuth (desktop flow โ€” opens browser)
gatekeeper auth --flow device             # Google OAuth (device flow โ€” for SSH/headless)
gatekeeper key create --name my-agent     # Create an API key
gatekeeper key create --name drv --permissions drive  # Scoped key
gatekeeper key list                       # List all keys
gatekeeper key revoke --prefix gkp_a1b2   # Revoke a key
gatekeeper status                         # Show configuration status
gatekeeper service install                # Install systemd user service
gatekeeper service uninstall              # Remove systemd user service
gatekeeper service enable                 # Enable and start the service
gatekeeper service disable                 # Stop and disable the service
gatekeeper service restart                # Restart the service
gatekeeper service status                 # Show service status
gatekeeper service logs                   # Show service logs (-f to follow)
gatekeeper hosts list                     # List MCP allowed hosts
gatekeeper hosts add <hostname>           # Add a host (Tailscale, LAN, etc.)
gatekeeper hosts remove <hostname>        # Remove a host

Configuration

All configuration via environment variables (prefix GATEKEEPER_) or .env file:

Variable Default Description
GATEKEEPER_HOST 127.0.0.1 Host to bind to (0.0.0.0 in containers)
GATEKEEPER_PORT 8080 Port to bind to
GATEKEEPER_DEBUG false Enable debug mode
GATEKEEPER_DATABASE_URL sqlite+aiosqlite:///./gatekeeper.db Database URL
GATEKEEPER_SECRET_KEY (auto-generated) Secret key for sessions
GATEKEEPER_ENCRYPTION_KEY (auto-generated) Fernet key for Google token encryption
GATEKEEPER_ADMIN_USERNAME admin Admin UI username
GATEKEEPER_ADMIN_PASSWORD (auto-generated) Admin UI password
GATEKEEPER_API_KEY_PREFIX gkp_ Prefix for API keys
GATEKEEPER_MCP_ENABLED true Enable MCP server
GATEKEEPER_MCP_ALLOWED_HOSTS [] (localhost/127.0.0.1 always allowed) JSON array of additional hosts for MCP connections (use gatekeeper hosts add CLI)
GATEKEEPER_RATE_LIMIT_PER_MINUTE 120 Rate limit per minute per API key
GATEKEEPER_GOOGLE_CLIENT_ID (required) Google OAuth client ID
GATEKEEPER_GOOGLE_CLIENT_SECRET (required) Google OAuth client secret
GATEKEEPER_GOOGLE_TOKEN_FILE ./google_token.json Encrypted token file path
GATEKEEPER_DRIVE_ENABLED false Enable Drive module
GATEKEEPER_GMAIL_ENABLED false Enable Gmail module
GATEKEEPER_CALENDAR_ENABLED false Enable Calendar module
GATEKEEPER_DISPLAY_TIMEZONE America/Chicago IANA timezone for timestamp display
GATEKEEPER_CORS_ORIGINS ["http://localhost:8080","http://127.0.0.1:8080"] CORS allowed origins

Auto-generated secrets are persisted in gatekeeper_secrets.json so they survive restarts. This file is created with chmod 600 permissions. Add it to .gitignore (already in the default .gitignore).

Container Deployment (Podman)

# Build
podman build -t gatekeeper .

# Create .env
cp .env.example .env
# Edit .env with your credentials

# Run with compose
podman-compose up -d

# Or run directly
podman run -d \
  --name gatekeeper \
  -p 8080:8080 \
  -v gatekeeper-data:/data \
  --env-file .env \
  gatekeeper

The /data volume persists the SQLite database, Google token, and secrets across container restarts.

Raspberry Pi: The Dockerfile supports linux/arm64 โ€” Podman will build the correct architecture automatically with --platform linux/arm64.

Security

  • TLS: Use a reverse proxy (Caddy/nginx) for HTTPS in production
  • API Keys: bcrypt-hashed, prefix-based lookup, revocable
  • Token Encryption: Google OAuth refresh tokens encrypted at rest with Fernet
  • Secret Persistence: Auto-generated secrets stored in gatekeeper_secrets.json (chmod 600)
  • Network: Binds 127.0.0.1 by default โ€” only accessible locally unless configured otherwise
  • MCP Host Allowlist: DNS rebinding protection; only localhost and 127.0.0.1 by default โ€” add Tailscale/LAN hosts via gatekeeper hosts add
  • CORS: Configurable via GATEKEEPER_CORS_ORIGINS
  • Admin Auth: HTTP Basic Auth with auto-generated credentials

Development

# Clone and install dev dependencies
git clone https://github.com/brimdor/gatekeeper.git
cd gatekeeper
uv pip install -e ".[dev]"

# Run tests
uv run pytest tests/ -v

# Run linter
uv run ruff check gatekeeper/
uv run ruff format --check gatekeeper/ tests/

# Run locally
uv run gatekeeper serve

Architecture

gatekeeper/
โ”œโ”€โ”€ gatekeeper/
โ”‚   โ”œโ”€โ”€ __init__.py           # Version
โ”‚   โ”œโ”€โ”€ main.py               # FastAPI app, CLI, lifespan
โ”‚   โ”œโ”€โ”€ config.py             # Pydantic settings + secret persistence
โ”‚   โ”œโ”€โ”€ db.py                 # Async SQLite setup
โ”‚   โ”œโ”€โ”€ models.py             # SQLAlchemy models
โ”‚   โ”œโ”€โ”€ encryption.py         # Fernet encrypt/decrypt
โ”‚   โ”œโ”€โ”€ auth.py               # API key auth + admin auth
โ”‚   โ”œโ”€โ”€ policy.py             # Policy engine (allow/deny/transform)
โ”‚   โ”œโ”€โ”€ google_client.py     # Google OAuth desktop + device flow
โ”‚   โ”œโ”€โ”€ logging.py            # Audit logging
โ”‚   โ”œโ”€โ”€ service.py            # Systemd service management
โ”‚   โ”œโ”€โ”€ api/
โ”‚   โ”‚   โ”œโ”€โ”€ router.py          # Dynamic FastAPI router from modules
โ”‚   โ”‚   โ””โ”€โ”€ proxy.py           # Policy-enforced Google API proxy
โ”‚   โ”œโ”€โ”€ admin/
โ”‚   โ”‚   โ”œโ”€โ”€ routes.py          # Admin REST API
โ”‚   โ”‚   โ”œโ”€โ”€ models.py          # Pydantic response models
โ”‚   โ”‚   โ””โ”€โ”€ ui/
โ”‚   โ”‚       โ”œโ”€โ”€ __init__.py    # Jinja2 template rendering
โ”‚   โ”‚       โ”œโ”€โ”€ static/style.css
โ”‚   โ”‚       โ””โ”€โ”€ templates/     # Mobile-responsive admin dashboard
โ”‚   โ”œโ”€โ”€ mcp_server/
โ”‚   โ”‚   โ”œโ”€โ”€ __init__.py        # FastMCP SSE server
โ”‚   โ”‚   โ””โ”€โ”€ transport.py       # SSE transport config
โ”‚   โ””โ”€โ”€ modules/
โ”‚       โ”œโ”€โ”€ __init__.py         # Module registry
โ”‚       โ”œโ”€โ”€ base.py            # GoogleModule base class
โ”‚       โ”œโ”€โ”€ route.py           # ModuleRoute definition
โ”‚       โ”œโ”€โ”€ drive/             # Drive module (27 routes)
โ”‚       โ”œโ”€โ”€ gmail/             # Gmail module (37 routes)
โ”‚       โ””โ”€โ”€ calendar/          # Calendar module (26 routes)
โ”œโ”€โ”€ tests/                      # Test suite
โ”œโ”€โ”€ Dockerfile                  # Multi-arch Podman/Docker build
โ”œโ”€โ”€ docker-compose.yml          # Podman Compose config
โ”œโ”€โ”€ install.sh                  # One-line install script
โ”œโ”€โ”€ .env.example                # Environment template
โ””โ”€โ”€ pyproject.toml              # Package configuration

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aigatekeeper-0.2.1.tar.gz (223.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aigatekeeper-0.2.1-py3-none-any.whl (73.8 kB view details)

Uploaded Python 3

File details

Details for the file aigatekeeper-0.2.1.tar.gz.

File metadata

  • Download URL: aigatekeeper-0.2.1.tar.gz
  • Upload date:
  • Size: 223.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aigatekeeper-0.2.1.tar.gz
Algorithm Hash digest
SHA256 71af4435d35a2af20741153df874b8e3838016015cd4014b64298b0902eb0eac
MD5 93e4259ec914144be01a604b6bc21ebe
BLAKE2b-256 1afdb090f4de2c7819fdc61614796091c94dd3038f82514aaff20978179e6657

See more details on using hashes here.

Provenance

The following attestation bundles were made for aigatekeeper-0.2.1.tar.gz:

Publisher: pypi.yml on brimdor/gatekeeper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aigatekeeper-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: aigatekeeper-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 73.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aigatekeeper-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1906328fdcb77fed783c361fd1c7ebb675d224910d1b6018335e8203bb05d105
MD5 14b9a6d2151c68425c02c2988763df46
BLAKE2b-256 896d200c7f63fc003b7d54c5cd43f895e2984fdbf4ba2594084f3669a24fee1d

See more details on using hashes here.

Provenance

The following attestation bundles were made for aigatekeeper-0.2.1-py3-none-any.whl:

Publisher: pypi.yml on brimdor/gatekeeper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page