honest-calendar-mcp
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., "@honest-calendar-mcpWhat's on my calendar tomorrow?"
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.
honest-calendar-mcp
Local Google Calendar MCP server. Your calendar data never leaves your machine except to Google. No third party in the middle.
Companion project to honest-gmail-mcp.
Why
Most Calendar integrations for AI assistants route your event data through a hosted service that sees everything: meetings, attendees, locations, private descriptions. This one doesn't.
Data flow: You ↔ this server (on your Mac) ↔ Google Calendar API. That's it.
You can read the entire server — one file, ~250 lines of Python — and confirm exactly what it can and cannot do.
Related MCP server: Google Calendar MCP Server
Features
Six tools exposed over MCP:
list_calendars— all calendars available on this accountlist_events— events in a calendar within a time range, with optional free-text searchget_event— full details of a single eventcreate_event— new event (timed or all-day), with attendees, description, location, timezoneupdate_event— partial patch of an existing eventdelete_event— delete an event
All tools that send invites accept a send_updates parameter (none by default — no email is sent unless you explicitly ask for it).
Requirements
Python 3.10+
A Google account you want to give it access to
A one-time setup in Google Cloud Console (~10 min, can reuse the OAuth client from honest-gmail-mcp if you already set that up)
Setup
1. Clone + install
git clone https://github.com/bartosz-kuc/honest-calendar-mcp.git
cd honest-calendar-mcp
python3 -m venv venv
./venv/bin/pip install -r requirements.txt2. Get Google OAuth credentials
Same process as honest-gmail-mcp — a Desktop-app OAuth client from your own Google Cloud project. If you already have a project set up, just enable the Calendar API on it:
https://console.cloud.google.com/ (signed in with the account you want to authorize)
Select existing project (or create new one)
APIs & Services → Library → search Google Calendar API → Enable
Reuse existing OAuth consent screen / client, OR create new — Desktop app type
Save
credentials.jsonin this repo's root directory
3. First run (does the OAuth dance)
./venv/bin/python server.pyBrowser opens → sign in → Allow. Token saved locally as token.json. Press Ctrl+C after.
4. Register with your MCP client
Claude Code:
claude mcp add calendar-personal /absolute/path/to/venv/bin/python /absolute/path/to/server.pyClaude Desktop: edit claude_desktop_config.json:
{
"mcpServers": {
"calendar-personal": {
"command": "/absolute/path/to/venv/bin/python",
"args": ["/absolute/path/to/server.py"]
}
}
}Example usage
"What's on my calendar tomorrow?"
AI calls list_events with tomorrow's time range → gets back events with summary, start, end, attendees.
"Book a 1h call with alice@example.com next Thursday at 15:00."
AI calls create_event with summary, start, end, attendees, send_updates: "all" if you want Alice invited.
Data flow (detail)
Your AI client (Claude Code / Claude Desktop)
↕ MCP protocol over stdio (local process pipe)
This server (Python, on your machine)
↕ HTTPS to googleapis.com
Google Calendar APINo cloud middle. No telemetry. credentials.json and token.json stay on your disk and are .gitignored.
Security notes
You own the OAuth client. Nobody else can revoke, rotate, or misuse it.
Revoke anytime at https://myaccount.google.com/permissions.
Scope requested:
calendar(full read/write on all your calendars). Google does not offer read-only + write-only splits for the standard Calendar scope; the write-heavy nature of a calendar-editing tool needs full scope.No secrets in git.
.gitignoreblockscredentials.json,token.json, and virtualenvs.send_updates defaults to "none" — the AI cannot accidentally spam attendees. You must explicitly ask for updates to be sent.
Author
Bartosz Kuć — Warsaw-based developer, JDG owner running skanfirmy.pl.
Site: https://skanfirmy.pl
GitHub: https://github.com/bartosz-kuc
Email: firma@bartosza.pl
Consulting
Available for consulting on Polish tax and business integrations (KSeF, GUS/NFZ/GIOŚ APIs, mBank data), MCP server design, and AI-assisted tooling for JDGs and small teams. See skanfirmy.pl/uslugi for productized packages (audit 3k PLN, setup 8-15k PLN, retainer 2-4k PLN/mo), or reach out via email.
License
MIT — see LICENSE.
Available Tools
6 toolscreate_eventC
Create a new event. Times as RFC3339 datetimes (timed) or YYYY-MM-DD (all-day). Attendees is a list of email strings.
| Name | Required | Description | Default |
|---|---|---|---|
| end | Yes | RFC3339 datetime or YYYY-MM-DD for all-day | |
| start | Yes | RFC3339 datetime or YYYY-MM-DD for all-day | |
| summary | Yes | ||
| location | No | ||
| timezone | No | IANA tz like Europe/Warsaw, default Europe/Warsaw | |
| attendees | No | ||
| calendar_id | No | primary | |
| description | No | ||
| send_updates | No | none |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It gives useful time-format semantics but omits mutation-relevant behavior: whether invitations are dispatched to attendees, permissions required, side effects, or reversibility. The format detail is helpful but leaves key behavioral traits undocumented.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the core action and then the two format constraints that matter most. Zero filler; every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter mutation tool with no annotations and no output schema, the description is too thin. It should disclose invitation/side-effect behavior, required scopes, and defaults for send_updates/calendar_id, none of which are covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 33%, so the description should compensate, but it only restates the start/end formats already in the schema and clarifies that attendees are email strings. Six parameters (summary, location, timezone, calendar_id, description, send_updates) get no semantic elaboration in either place.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Create a new event'), which clearly separates it from the list/get/update/delete siblings. However, it never explicitly names or contrasts against those siblings, so it stops short of the 5-tier differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use create_event versus update_event, or on prerequisites such as needing write access to a calendar. The description only describes what the tool does, never when or when-not to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_eventC
Delete an event by id.
| Name | Required | Description | Default |
|---|---|---|---|
| event_id | Yes | ||
| calendar_id | No | primary | |
| send_updates | No | none |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden for a destructive mutation and falls short. It never states that deletion is permanent/irreversible, what permissions are needed, whether notifications are sent, or what the response contains.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single well-formed sentence with the action front-loaded, but it is under-specified rather than concise. Every word earns its place, yet there is too little information for a 3-parameter destructive tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero annotations, zero schema descriptions, a destructive operation, and an enum parameter governing attendee notifications, the definition is materially incomplete. An agent cannot determine notification side effects or safety requirements before calling it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the description only covers event_id ('by id'). The calendar_id parameter with its 'primary' default and the send_updates enum (all/externalOnly/none, default none) are left entirely unexplained in both description and schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Delete) and resource (event), with the lookup key (id) identified. It is distinguishable from siblings create_event/update_event/get_event/list_events by the verb alone, though it does not explicitly contrast itself with any of them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this versus update_event or when deletion is appropriate, no prerequisites, no warnings about irreversibility. The only usage signal is the implicit 'by id' lookup requirement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_eventC
Fetch full details of a single event by id.
| Name | Required | Description | Default |
|---|---|---|---|
| event_id | Yes | ||
| calendar_id | No | primary |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does not say whether this is a read-only operation, whether access requires calendar permissions, or what happens for missing/invalid ids — gaps that matter for a fetch tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with the resource and retrieval key front-loaded; nothing is wasted, though it is arguably too terse given the undocumented calendar_id.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The core operation is communicated and no output schema exists, so return values need not be described. However, with 0% schema coverage and no annotations, the unexplained calendar_id parameter and absent permissions/error context leave it only minimally complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. 'By id' loosely maps to event_id, but calendar_id (with default 'primary') is never mentioned, leaving half the parameters undocumented anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fetch full details of a single event by id'), which clearly separates it from list_events and the mutating siblings. It does not name the siblings explicitly, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No statement of when to use this versus list_events or what happens when the id is unknown. An agent must infer that this is the single-record retrieval path from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_calendarsA
List all calendars available on this account with id, summary, and access role.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses scope (all calendars on this account) and the shape of the returned fields, which is useful, but says nothing about authentication requirements, pagination, or rate limits for a listing call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the resource and the return fields are stated immediately without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no parameters, the description compensates reasonably by naming the fields returned (id, summary, access role). For a trivial zero-arg read tool this is nearly sufficient, though it omits any note on account scope or auth.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the rubric the baseline is 4. There is no parameter surface for the description to illuminate or neglect.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (List) and resource (calendars) and even enumerates returned fields (id, summary, access role). It does not explicitly contrast with siblings, but the sibling set is entirely event-focused, so the distinction is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: an agent can infer this is the discovery step before calling list_events or create_event, but the description never says when to reach for it or what it is not for. No alternatives or preconditions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_eventsA
List events in a calendar within a time range. Returns event id, summary, start, end, location, attendees. Default calendar is 'primary'.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Free-text search filter | |
| time_max | Yes | RFC3339 | |
| time_min | Yes | RFC3339 (e.g. 2026-07-22T00:00:00+02:00) | |
| calendar_id | No | primary | |
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It does disclose the returned field set and the default calendar behavior, which is real value since no output schema exists. It omits pagination/truncation behavior, which matters for a list tool capped at 250 results with a default of 50.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, front-loaded sentences: purpose, then return fields, then default. Every sentence carries information and nothing is padded, though the return-field enumeration reads as a list rather than integrated prose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-list tool with 5 parameters at 60% schema coverage and no annotations or output schema, the description covers the essentials: what it lists, the time-range scope, and what comes back. The main gap is that pagination/result-limit behavior is left entirely to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 60% and the schema itself documents query, time_max, time_min formats. The description adds only time-range framing and the 'primary' default, neither of which goes beyond the schema (calendar_id already has default 'primary'). No meaning is added for query or max_results.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('events in a calendar') plus the scoping constraint ('within a time range'), which distinguishes it from the singular get_event sibling. It stops short of naming any sibling explicitly, so differentiation is inferred rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'within a time range' phrasing implies when this tool applies, and the required time_min/time_max reinforce that. However, there is no explicit guidance on when to prefer this over get_event or list_calendars, and no exclusions or prerequisites are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_eventB
Partial update of an existing event. Only pass the fields you want to change. Uses PATCH semantics.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ||
| start | No | ||
| summary | No | ||
| event_id | Yes | ||
| location | No | ||
| timezone | No | ||
| attendees | No | ||
| calendar_id | No | primary | |
| description | No | ||
| send_updates | No | none |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does add one genuinely useful trait: PATCH semantics, meaning omitted fields are left unchanged. However, it says nothing about side effects such as attendee notifications via send_updates, authorization requirements, or whether the update is reversible, which matters for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the purpose and free of padding. 'Uses PATCH semantics' slightly restates the preceding partial-update sentence, but it is a useful reinforcement rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter mutation tool with no annotations, no output schema, and zero schema description coverage, the description is far too thin. An agent cannot tell what a successful response looks like, what happens to attendees, or how the enum and defaulted parameters behave.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 10 parameters, so the description must compensate and largely does not. It never explains send_updates (the one enum, controlling who is notified), calendar_id's 'primary' default, the timezone or attendee semantics, or the expected format for start/end. 'PATCH semantics' only partially covers the update contract.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Partial update of an existing event'), which distinguishes it from create_event and delete_event by name. It is clear about what it operates on, though it does not explicitly contrast itself with the sibling set beyond the verb.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Only pass the fields you want to change' gives real guidance on how to invoke it, but there is no statement of when to use update_event versus create_event or delete_event, nor any prerequisites such as required permissions or ownership of the event.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
create_event - First observed
delete_event - First observed
get_event - First observed
list_calendars - First observed
list_events - First observed
update_event
TDQS
Scored across 6 tools
Each tool targets a distinct resource and action: listing calendars vs. events, and get/create/update/delete for events. There is no overlap between any pair of tools, so an agent can select correctly without hesitation.
All names follow a strict snake_case verb_noun pattern: list_calendars, list_events, get_event, create_event, update_event, delete_event. There are no deviations in style or verb forms.
Six tools is well-scoped for a calendar server, covering the essential read/write/delete operations without bloat. Every tool has a clear place in the surface.
Event lifecycle is fully covered with list, get, create, update, and delete. Minor gaps exist such as no search/free-busy query and no calendar management beyond listing, but core calendar workflows are complete and workable.
Maintenance
Related MCP Connectors
Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.
A MCP server that works with Google Calendar to manage event listing, reading, and updates.
GDPR-compliant calendar access for AI assistants: read, create, edit, RSVP. Google, MS 365, Apple.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceMCP server that lets AI agents manage Google Calendar -- create events, check availability, and manage schedules.MIT
- AlicenseAqualityCmaintenanceAn MCP server that provides access to the Google Calendar API, allowing AI assistants to list and retrieve calendar items via OAuth 2.0 tokens.10MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that enables AI assistants to interact with Google Calendar and Gmail, allowing users to manage events, send emails, and organize their inbox through natural language.MIT
- FlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server for read-only Google Calendar integration, providing calendar access to AI assistants.-