Skip to main content
Glama

Neutra

A neutral place where people's AI assistants agree on things for them, without anyone seeing anyone else's data.

Today it does one thing: two people's assistants find a time to meet. Each assistant tells Neutra when its person is free. Neutra finds a common time and sends one calendar invite to both. Neither side ever sees the other's times.

sequenceDiagram
    participant A as Anna's assistant
    participant N as Neutra
    participant B as Ben's assistant
    A->>N: Anna's free times
    N-->>A: a message for Anna to forward to Ben
    Note over A,B: Anna forwards it in any chat
    B->>N: Ben's free times + the code
    N-->>A: calendar invite
    N-->>B: calendar invite

It works across assistants: Anna can use Claude and Ben another assistant, as long as both support MCP connectors.

Privacy, by design

  • No AI on Neutra's side. Neutra is plain code that compares time ranges. Your times never go into an AI model of ours.

  • Nobody sees anyone's times. Only the matched meeting time comes back. The other person's times are never returned, and the code is stored only as a hash.

  • Times are deleted as soon as a decision is settled, at the latest after 14 days. The person answering never has their times stored at all.

  • Retries can't map a calendar. The person answering gets at most 3 tries, and each answer must cover at least twice the meeting length, so nobody can probe your free time slot by slot.

  • Data stays in the EU, in Cloudflare's EU jurisdiction.

  • Checked by tests: test/decisions.test.ts verifies that no times or codes appear in any response.

Details: privacy page.

Related MCP server: Meeting Scheduler

Try it

  1. In Claude: Customize → Connectors → Add custom connector, URL https://neutra.day/mcp, then Add.

  2. Sign in with Google. Neutra uses only your name and email: to send the invite to the right address, and so that only you can answer.

  3. Ask: "Use Neutra to find an hour with Ben next week. I'm free Tuesday and Thursday, 18:00–21:00." Forward the message it gives you.

For agent builders

A remote MCP server with Google sign-in. Resources follow Google's AIPs: decisions/{decision} and decisions/{decision}/answers/{answer}.

Tool

What it does

create_decision

Start a decision with your person's free times and the meeting length. Returns a code and a message to forward.

create_answer

Answer with the code from the message (neutra:<id>.<code>) and your person's free times. A match sends the invite.

get_decision

Status (WAITING, NO_MATCH, INVITE_SENT, ACCEPTED, DECLINED, EXPIRED) and the meeting time.

delete_decision

Cancel a decision you started, including its invite.

get_answer

Read your own answer.

create_feature_request

Tell Neutra's makers about something your person wanted that Neutra can't do yet.

get_feature_request

Read a feature request you sent.

Errors use google.rpc codes: NOT_FOUND, PERMISSION_DENIED, FAILED_PRECONDITION, INVALID_ARGUMENT, RESOURCE_EXHAUSTED (a daily or hourly limit was reached).

Running Neutra

Runs on Cloudflare Workers with D1, based on Cloudflare's remote-mcp-google-oauth template. Every push to main is type-checked, tested and deployed by GitHub Actions (.github/workflows/deploy.yml); migrations in migrations/ are applied before each deploy. Changes go through pull requests.

Setup (done once)

Cloudflare

  • Account ID and the MCP_RESOURCE address are in wrangler.jsonc. The domain neutra.day is attached to the Worker as a Custom Domain in the Cloudflare dashboard.

  • API token: "Edit Cloudflare Workers" template plus D1: Edit.

  • The D1 database (EU jurisdiction) and the OAUTH_KV namespace were created once with wrangler d1 create neutra --jurisdiction eu and wrangler kv namespace create OAUTH_KV; their IDs are in wrangler.jsonc.

Google Cloud (project neutra)

  • Google Auth Platform: audience External, publishing status In production (testing mode makes refresh tokens expire after 7 days). Branding: home page and privacy links above, authorized domain neutra.day.

  • Web client with redirect URI https://neutra.day/callback (add https://developers.google.com/oauthplayground only while making a new inviter key, and http://localhost:8788/callback for local dev).

  • Google Calendar API and Gmail API enabled.

  • Sign-in asks only for email and profile. While ACCESS_MODE is allowlist, only ALLOWED_EMAILS can sign in.

Inviter (neutra.invites@gmail.com)

  • Refresh token with scopes calendar.events and gmail.send, obtained via the OAuth 2.0 Playground using the web client's own credentials (steps in docs/RUNBOOK.md).

GitHub secrets (Settings → Secrets and variables → Actions)

Secret

What

CLOUDFLARE_API_TOKEN

Cloudflare API token

GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET

Web client

COOKIE_ENCRYPTION_KEY

Any long random string

ALLOWED_EMAILS

Comma-separated emails of the test users

INVITER_REFRESH_TOKEN

Inviter's refresh token

Local development

npm install, copy .dev.vars.example to .dev.vars and fill it in, then npm run dev. Test with npx @modelcontextprotocol/inspector@latest against http://localhost:8788/mcp.

License

MIT, see LICENSE. Includes code from Cloudflare's MIT-licensed templates.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to intelligently schedule meetings by checking Microsoft Outlook calendars, finding available time slots across multiple participants, and automatically booking meetings with Teams integration. Uses Microsoft Graph API with smart fallback logic for optimal scheduling.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Automates meeting logistics with tools for scheduling, availability checking, slot finding, timezone conversion, and recurring date generation. Eliminates the need for custom calendar logic by providing validated time operations and formatted invitations for applications and AI assistants.
    MIT