create_poll
Create a scheduling poll with time slots for participants to vote. Provide title and time options (ISO 8601 with timezone). Get a shareable URL to send to participants and an admin passphrase for managing results.
Instructions
Create a Timergy scheduling poll (like Doodle) where participants vote on preferred time slots. Provide a title and at least 2-5 time slot options with ISO 8601 date-times (include timezone, e.g. 2026-03-20T18:00:00+02:00 or use UTC with Z suffix). Returns a shareable URL to send to participants and a passphrase for admin access. The passphrase is automatically remembered for finalize_poll. Workflow: create_poll -> share URL -> wait for votes -> get_results -> finalize_poll.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | Poll title (e.g. 'Dinner with Moritz') | |
| options | Yes | Time slot options (recommend 3-5) | |
| description | No | Optional poll description | |
| deadline | No | Optional voting deadline (ISO 8601) | |
| location | No | Optional event location | |
| creatorName | No | Name shown as poll creator (e.g. 'Claude for Max') |
Implementation Reference
- src/tools.ts:70-92 (handler)The main handler logic for create_poll: validates input with Zod, calls client.createPoll(), stores the passphrase in session state, and returns formatted JSON with pollId, URL, passphrase, options, etc.
case "create_poll": { const input = z.object({ title: z.string(), options: z.array(z.object({ start: z.string(), end: z.string() })).min(1), description: z.string().optional(), deadline: z.string().optional(), location: z.string().optional(), creatorName: z.string().optional(), }).parse(args); const result = await client.createPoll(input); passphraseMap.set(result.id, result.passphrase); return JSON.stringify({ pollId: result.id, title: result.title, url: result.url, passphrase: result.passphrase, options: result.options, expiresAt: result.expiresAt, note: "Share the URL with participants. The passphrase is saved for finalization.", }, null, 2); } - src/client.ts:6-13 (schema)TypeScript interface defining the input schema for createPoll: title, options (start/end), and optional description, deadline, location, creatorName.
export interface CreatePollInput { title: string; options: Array<{ start: string; end: string }>; description?: string; deadline?: string; location?: string; creatorName?: string; } - src/client.ts:21-30 (schema)TypeScript interface defining the result returned from createPoll: pollId, title, URL, passphrase, options, expiration, and timestamps.
export interface CreatePollResult { id: string; title: string; description: string | null; url: string; passphrase: string; options: PollOption[]; expiresAt: string; createdAt: string; } - src/client.ts:96-105 (helper)HTTP client method that POSTs to /api/open/polls to create the poll on the Timergy API, then ensures a valid share URL is set.
async createPoll(input: CreatePollInput & { source?: string }): Promise<CreatePollResult> { const result = await this.request<CreatePollResult>("POST", "/api/open/polls", { ...input, source: input.source || "mcp" }); // Ensure URL is present; only override if it looks suspicious (not HTTPS and not localhost) if (!result.url) { result.url = `https://timergy.com/en/polls/${result.id}`; } else if (!result.url.startsWith("https://") && !result.url.startsWith("http://localhost")) { result.url = `https://timergy.com/en/polls/${result.id}`; } return result; } - src/index.ts:37-59 (registration)MCP tool registration using server.tool() with the name "create_poll", Zod schema for arguments, and a handler that delegates to handleToolCall.
server.tool( "create_poll", TOOL_DESCRIPTIONS.create_poll, { title: z.string().describe("Poll title (e.g. 'Dinner with Moritz')"), options: z.array(z.object({ start: z.string().describe("Slot start (ISO 8601 with timezone, e.g. 2026-03-20T18:00:00+02:00)"), end: z.string().describe("Slot end (ISO 8601 with timezone, e.g. 2026-03-20T20:00:00+02:00)"), })).min(1).describe("Time slot options (recommend 3-5)"), description: z.string().optional().describe("Optional poll description"), deadline: z.string().optional().describe("Optional voting deadline (ISO 8601)"), location: z.string().optional().describe("Optional event location"), creatorName: z.string().optional().describe("Name shown as poll creator (e.g. 'Claude for Max')"), }, async (args) => { try { const text = await handleToolCall("create_poll", args, client, stdioSession()); return { content: [{ type: "text", text }] }; } catch (e) { return { content: [{ type: "text", text: `Error: ${e instanceof Error ? e.message : String(e)}` }], isError: true }; } }, );