Meetgrid MCP Server
Sends organizer admin links by email via the Resend API when a poll is created with an email address. The response reports an email_status (sent, not_configured, or failed), and emailing is optional since poll creation works without a configured Resend key.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Meetgrid MCP Servercreate a scheduling poll for a 30-min team sync on Sept 15 and 16 at 10am"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Meetgrid
Dead-simple scheduling polls — a no-login Doodle alternative.
Create a poll, share a link, collect Yes/No availability, pick a time, and close. Built on Cloudflare Workers + D1 with an MCP server for AI agents.
What & why
Meetgrid helps groups find a meeting time without accounts, calendar integrations, or marketing fluff. Organizers get a public poll URL plus a secret capability token. Respondents enter a name and mark slots Yes or No. Results rank slots by yes-count; organizers mark the final choice and optionally close the poll.
Related MCP server: @calmesh/mcp-server
Features
Yes / No only — no maybe votes
Manual time slots (Doodle-style) — add date, start time, and duration per option; optional range generator
No accounts — unguessable poll IDs (or optional custom link slug), organizer secrets, and per-respondent edit tokens
Timezone-aware — required on create; defaults to
America/Los_Angelesin the UIThree thin pages — Create, Respond, Results (mobile-first, form aesthetic)
MCP tools for agents — same HTTP API the UI uses
Quick start
Prerequisites
Node.js 18+
Wrangler CLI (installed via npm below)
Local development
npm install
npm run db:migrate:local
npm run devOpen http://localhost:8787.
Deploy to Cloudflare
Create a D1 database:
npx wrangler d1 create meetgrid-dbCopy the returned
database_idintowrangler.toml(replacelocal-dev-placeholder).Apply migrations to production:
npm run db:migrate:remoteDeploy:
npm run deployEmailing organizers their admin link (optional)
When a poll is created with an email, Meetgrid sends that address the admin link through Resend. Set a Resend API key with sending access and a sender address on a domain you've verified in Resend:
npx wrangler secret put RESEND_API_KEY
npx wrangler secret put RESEND_FROM_EMAIL # or add it under [vars] in wrangler.toml
# optional: RESEND_FROM_NAME, e.g. "Meetgrid"For local dev, put the same keys in .dev.vars. With either one unset, no email is sent and poll creation works exactly as before; the response's email_status reads not_configured. A Resend error reads failed and is logged, and the poll is still created. The address is not stored.
Leave click tracking off for the sending domain in Resend (it is off by default). The admin link carries the organizer secret, and click tracking would route it through a redirect.
Project layout
├── src/
│ ├── index.ts # Worker entry (Hono app + /mcp Streamable HTTP)
│ ├── mcp/ # MCP handler + tool registration
│ ├── routes/
│ │ ├── api.ts # REST API
│ │ └── pages.ts # HTML pages
│ ├── db/queries.ts # D1 queries
│ └── lib/ # crypto, slots, timezone, rate-limit
├── migrations/
│ └── 0001_initial.sql
├── mcp/ # MCP server (stdio)
└── wrangler.tomlAPI
Base URL: https://your-worker.workers.dev (or http://localhost:8787 locally)
Method | Path | Description |
|
| Create poll |
|
| Public poll view (no organizer secret) |
|
| Submit/update response |
|
| Load own votes by edit token |
|
| Organizer: mark chosen slot |
|
| Organizer: close poll |
|
| Organizer: add/remove slots |
|
| Preview range-generated slots for create UI |
|
| MCP Streamable HTTP endpoint |
Write endpoints are lightly rate-limited (30 requests / 60s per IP by default).
curl examples
Create a poll (explicit slots — preferred)
curl -s -X POST http://localhost:8787/api/polls \
-H 'Content-Type: application/json' \
-d '{
"title": "Team sync",
"timezone": "America/Los_Angeles",
"slots": [
{"date": "2026-09-15", "start_time": "10:00", "duration_minutes": 30},
{"date": "2026-09-16", "start_time": "14:00", "duration_minutes": 45}
]
}'Create via range generator (optional fallback when slots omitted)
curl -s -X POST http://localhost:8787/api/polls \
-H 'Content-Type: application/json' \
-d '{
"title": "Team sync",
"timezone": "America/Los_Angeles",
"duration_minutes": 30,
"start_date": "2026-09-15",
"end_date": "2026-09-19",
"daily_start": "09:00",
"daily_end": "17:00",
"weekdays": [1, 2, 3, 4, 5]
}'Save poll_id, organizer_secret, and poll_url from the response. organizer_url is the admin link (results page with the secret). Add "email": "you@example.com" to have the admin link emailed to you; the response then includes email_status (sent, not_configured or failed). Optionally set a custom link with "slug": "team-sync" (or "poll_id" / "name") — lowercase letters, digits, and hyphens, 3–48 chars; returns 409 if taken.
curl -s -X POST http://localhost:8787/api/polls \
-H 'Content-Type: application/json' \
-d '{
"title": "Team sync",
"slug": "team-sync-sept",
"timezone": "America/Los_Angeles",
"slots": [{"date": "2026-09-15", "start_time": "10:00", "duration_minutes": 30}]
}'Get poll (public)
curl -s http://localhost:8787/api/polls/POLL_IDRespond
curl -s -X POST http://localhost:8787/api/polls/POLL_ID/respond \
-H 'Content-Type: application/json' \
-d '{
"name": "Alex",
"votes": [
{"slot_id": "SLOT_ID", "yes": true}
]
}'Update a response (pass edit_token from the prior response):
curl -s -X POST http://localhost:8787/api/polls/POLL_ID/respond \
-H 'Content-Type: application/json' \
-d '{
"name": "Alex",
"edit_token": "EDIT_TOKEN",
"votes": [
{"slot_id": "SLOT_ID", "yes": false}
]
}'Mark chosen slot
curl -s -X POST http://localhost:8787/api/polls/POLL_ID/decision \
-H 'Content-Type: application/json' \
-d '{
"organizer_secret": "ORGANIZER_SECRET",
"slot_id": "SLOT_ID"
}'Close poll
curl -s -X POST http://localhost:8787/api/polls/POLL_ID/close \
-H 'Content-Type: application/json' \
-d '{
"organizer_secret": "ORGANIZER_SECRET"
}'MCP server
Meetgrid exposes MCP over Streamable HTTP at /mcp on the Worker itself (stateless WebStandardStreamableHTTPServerTransport, one server per request). Same tools as the REST API. A stdio transport is optional for local CLI use.
Remote HTTP (recommended)
Production endpoint:
https://meetgrid.amandeep.app/mcpLocal dev (after npm run dev):
http://localhost:8787/mcpAdd to .cursor/mcp.json (or Cursor Settings → MCP):
{
"mcpServers": {
"meetgrid": {
"url": "https://meetgrid.amandeep.app/mcp"
}
}
}For local development, use "url": "http://127.0.0.1:8787/mcp".
Stdio (optional)
cd mcp
npm install
npm run buildSet MEETGRID_API_URL to your worker URL (defaults to http://127.0.0.1:8787).
{
"mcpServers": {
"meetgrid": {
"command": "node",
"args": ["/absolute/path/to/meetgrid/mcp/dist/index.js"],
"env": {
"MEETGRID_API_URL": "http://127.0.0.1:8787"
}
}
}
}MCP tools
Tool | Description |
| Create poll with explicit slots or date-range grid; optional custom link via |
| Get public poll view by ID |
| Alias of |
| Submit or update Yes/No votes |
| Alias of |
| Organizer marks chosen slot |
| Organizer closes poll |
Organizer secrets are returned only from poll_create — never from poll_get.
Auth (v0)
Meetgrid MCP matches the app’s no-login model: the /mcp endpoint is public and tools call the same REST API as the web UI. There is no OAuth or MCP-level authentication in v0.
Create:
poll_createreturnsorganizer_secretonce in the response — save it; it is not retrievable later.Organizer actions: pass
organizer_secrettopoll_set_decisionandpoll_close.Respond:
poll_respond/vote_pollreturns anedit_tokenfor the respondent to update their votes.
Do not treat MCP as a private admin API — anyone who can reach /mcp can create polls and respond. Protect the endpoint at the network layer if you need restriction (not implemented in v0).
Security model
poll_id — public, unguessable (12-char alphanumeric)
organizer_secret — capability token; shown once at creation; stored hashed in D1
edit_token — per-respondent; returned on respond; stored hashed; enables self-service edits via cookie or copyable link
Public GET responses never include organizer secrets
Pages
URL | Purpose |
| Create poll |
| Respond (Yes/No per slot) |
| Ranked results + heatmap; organizer actions with |
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Agent-first meeting schedule polls for humans and agents. Create polls, vote, find times.
- AstrocalOAuthdev.astrocal
AI-native scheduling: check availability, book meetings, cancel and reschedule via MCP
Scheduling for AI assistants: bookings, availability, meeting polls and routing forms.
Find a date with a group: polls, rosters, RSVPs and sign-ups, run by your assistant.
1
Related MCP Servers
- AlicenseAqualityCmaintenanceCreate scheduling polls (like Doodle) from AI agents. Find the best time for meetings, dinners, and events. 5 tools: create_poll, get_poll, vote_on_poll, get_results, finalize_poll. No authentication required.561 npm1MIT
- AlicenseAqualityDmaintenanceMCP server that connects AI agents to calendars, bookings, and scheduling polls via the Model Context Protocol.2212 npmMIT
- AlicenseNot gradedqualityDmaintenanceExposes Cal.com scheduling tools to AI agents via MCP, enabling listing event types, checking availability, and managing bookings (create, cancel, reschedule).570 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables scheduling polls for group chats to find common available times, with tools to create polls, get results, add candidate slots, and finalize appointments.-