io.b3os/google-calendar 1.0.0 · calendar, scheduling, productivity · MIT

Read and schedule with Google Calendar using your own Google OAuth token: list calendars, list and search events in a time window, read one event, find free and busy time across calendars, create events with attendees, and delete events. Needs calendar.readonly for reading and calendar.events to create or delete.

Every call's result carries upstream_status and timing: validate_ms, inject_ms, render_ms, upstream_ms, map_ms and total_ms. upstream is the service's time; the others are B3OS's own (call actions). The snippets below show no timing values, because a fixture records none.

Connection

google, type oauth2: Google account (Calendar).

An OAuth access token for your Google account from your own Google Cloud OAuth client, with the scopes listed here. Store the refresh_token, client_id and client_secret with it so the vault can refresh the token (access tokens last an hour); B3OS never uses a Google client of its own.

How to get one: developers.google.com.

Scopes the pack's actions use: https://www.googleapis.com/auth/calendar.readonly, https://www.googleapis.com/auth/calendar.events. The manifest names them per connection, not per action.

The credential is sent only to www.googleapis.com.

Store the credential once as a vault connection for this pack and key, then name its id in a call's connections. Leave the key out and B3OS uses the project's newest connection for the pack and key without a subject (connections).

Hosts it reaches: www.googleapis.com.

Actions

ActionEffectMCP toolTitle
list-calendarsreadgoogle-calendar__list-calendarsList calendars
list-eventsreadgoogle-calendar__list-eventsList events
get-eventreadgoogle-calendar__get-eventGet event
find-free-busyreadgoogle-calendar__find-free-busyFind busy time
create-eventwritegoogle-calendar__create-eventCreate event
delete-eventirreversiblegoogle-calendar__delete-eventDelete event

list-calendars

List calendars. Calendars in the user's list with id, name, time zone, access role (owner, writer, reader, freeBusyReader) and whether it is the primary one.

Ref io.b3os/google-calendar/list-calendars@1.0.0 · effect read · connection google · MCP tool google-calendar__list-calendars

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/google-calendar/list-calendars@1", "input": {}, "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: List calendars (documented response shape, example values). From the bundle's fixtures/list-calendars.json, not a live call.

json
{ "calendars": [ { "id": "mona@acme.example", "summary": "mona@acme.example", "time_zone": "America/Los_Angeles", "access_role": "owner", "primary": true }, { "id": "c_1a2b3c4d5e6f@group.calendar.google.com", "summary": "On-call", "time_zone": "UTC", "access_role": "writer", "primary": false } ]}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404nobuilt from the service's response
connection_unauthorized401noGoogle rejected the access token (expired or revoked); refresh or reconnect it.
rate_limited429, 403yesbuilt from the service's response
forbidden403nobuilt from the service's response
invalid_request400nobuilt from the service's response
conflict409nobuilt from the service's response

list-events

List events. Events in a time window, recurring events expanded into single occurrences and sorted by start time, optionally matching free text. Returns summary, time, location, Meet link, organizer and attendee responses. Page with page_token.

Ref io.b3os/google-calendar/list-events@1.0.0 · effect read · connection google · MCP tool google-calendar__list-events

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/google-calendar/list-events@1", "input": { "time_min": "2026-10-27T00:00:00-07:00", "time_max": "2026-10-28T00:00:00-07:00", "max_results": 2 }, "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: List events (documented response shape, example values). From the bundle's fixtures/list-events.json, not a live call.

json
{ "events": [ { "id": "7f1a2b3c4d5e6f7a8b9c0d1e2f", "status": "confirmed", "summary": "Release sync", "description": null, "location": "Room 4 / Meet", "start": "2026-10-27T09:00:00-07:00", "end": "2026-10-27T09:30:00-07:00", "all_day": false, "html_link": "https://www.google.com/calendar/event?eid=7f1a2b3c4d5e6f7a8b9c0d1e2f", "meet_link": "https://meet.google.com/abc-defg-hij", "organizer": "mona@acme.example", "attendees": [ {"email": "mona@acme.example", "response": "accepted"}, {"email": "hubot@acme.example", "response": "needsAction"} ], "recurring_event_id": null }, { "id": "a1b2c3d4e5f6a7b8c9d0e1f2a3", "status": "confirmed", "summary": "Offsite", "description": null, "location": "Room 4 / Meet", "start": "2026-10-27", "end": "2026-10-28", "all_day": true, "html_link": "https://www.google.com/calendar/event?eid=a1b2c3d4e5f6a7b8c9d0e1f2a3", "meet_link": null, "organizer": "mona@acme.example", "attendees": [], "recurring_event_id": null } ], "time_zone": "America/Los_Angeles", "next_page_token": null}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404nobuilt from the service's response
connection_unauthorized401noGoogle rejected the access token (expired or revoked); refresh or reconnect it.
rate_limited429, 403yesbuilt from the service's response
forbidden403nobuilt from the service's response
invalid_request400nobuilt from the service's response
conflict409nobuilt from the service's response

get-event

Get event. One event by id with its time, description, location, Meet link, organizer and attendees.

Ref io.b3os/google-calendar/get-event@1.0.0 · effect read · connection google · MCP tool google-calendar__get-event

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/google-calendar/get-event@1", "input": {"event_id": "7f1a2b3c4d5e6f7a8b9c0d1e2f"}, "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Get event (documented response shape, example values). From the bundle's fixtures/get-event.json, not a live call.

json
{ "id": "7f1a2b3c4d5e6f7a8b9c0d1e2f", "status": "confirmed", "summary": "Release sync", "description": "Agenda: v2.4.1 go/no-go", "location": "Room 4 / Meet", "start": "2026-10-27T09:00:00-07:00", "end": "2026-10-27T09:30:00-07:00", "all_day": false, "html_link": "https://www.google.com/calendar/event?eid=7f1a2b3c4d5e6f7a8b9c0d1e2f", "meet_link": "https://meet.google.com/abc-defg-hij", "organizer": "mona@acme.example", "attendees": [ {"email": "mona@acme.example", "response": "accepted"}, {"email": "hubot@acme.example", "response": "needsAction"} ], "recurring_event_id": null}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404nobuilt from the service's response
connection_unauthorized401noGoogle rejected the access token (expired or revoked); refresh or reconnect it.
rate_limited429, 403yesbuilt from the service's response
forbidden403nobuilt from the service's response
invalid_request400nobuilt from the service's response
conflict409nobuilt from the service's response

find-free-busy

Find busy time. Busy intervals of up to 50 calendars (or people's primary calendars, by email) in a window, to find a time everyone is free. Calendars you cannot see come back with an error instead of intervals.

Ref io.b3os/google-calendar/find-free-busy@1.0.0 · effect read · connection google · MCP tool google-calendar__find-free-busy

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/google-calendar/find-free-busy@1", "input": { "time_min": "2026-10-27T09:00:00-07:00", "time_max": "2026-10-27T17:00:00-07:00", "calendars": ["mona@acme.example", "ceo@acme.example"] }, "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Find busy time (documented response shape, example values). From the bundle's fixtures/find-free-busy.json, not a live call.

json
{ "calendars": [ { "id": "mona@acme.example", "busy": [ { "start": "2026-10-27T16:00:00Z", "end": "2026-10-27T16:30:00Z" } ], "error": null }, {"id": "ceo@acme.example", "busy": [], "error": "notFound"} ]}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404nobuilt from the service's response
connection_unauthorized401noGoogle rejected the access token (expired or revoked); refresh or reconnect it.
rate_limited429, 403yesbuilt from the service's response
forbidden403nobuilt from the service's response
invalid_request400nobuilt from the service's response
conflict409nobuilt from the service's response

create-event

Create event. Create an event with a summary, start and end times (or all-day dates), optional description, location and attendees, optionally with a Google Meet link. send_updates controls invitation emails. Not idempotent.

Ref io.b3os/google-calendar/create-event@1.0.0 · effect write · connection google · MCP tool google-calendar__create-event

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/google-calendar/create-event@1", "input": { "summary": "Release sync", "start": "2026-10-27T09:00:00-07:00", "end": "2026-10-27T09:30:00-07:00", "time_zone": "America/Los_Angeles", "attendees": ["hubot@acme.example"], "add_meet": true }, "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Create event (documented response shape, example values). From the bundle's fixtures/create-event.json, not a live call.

json
{ "id": "7f1a2b3c4d5e6f7a8b9c0d1e2f", "status": "confirmed", "summary": "Release sync", "description": null, "location": "Room 4 / Meet", "start": "2026-10-27T09:00:00-07:00", "end": "2026-10-27T09:30:00-07:00", "all_day": false, "html_link": "https://www.google.com/calendar/event?eid=7f1a2b3c4d5e6f7a8b9c0d1e2f", "meet_link": "https://meet.google.com/abc-defg-hij", "organizer": "mona@acme.example", "attendees": [ {"email": "mona@acme.example", "response": "accepted"}, {"email": "hubot@acme.example", "response": "needsAction"} ], "recurring_event_id": null}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404nobuilt from the service's response
connection_unauthorized401noGoogle rejected the access token (expired or revoked); refresh or reconnect it.
rate_limited429, 403yesbuilt from the service's response
forbidden403nobuilt from the service's response
invalid_request400nobuilt from the service's response
conflict409nobuilt from the service's response

delete-event

Delete event. Delete an event (for a recurring series, the whole series unless the id is one occurrence). Attendees are emailed only if send_updates says so.

Ref io.b3os/google-calendar/delete-event@1.0.0 · effect irreversible · connection google · MCP tool google-calendar__delete-event

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/google-calendar/delete-event@1", "input": {"event_id": "7f1a2b3c4d5e6f7a8b9c0d1e2f"}, "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Delete event (documented response shape, example values). From the bundle's fixtures/delete-event.json, not a live call.

json
{"deleted": true, "event_id": "7f1a2b3c4d5e6f7a8b9c0d1e2f"}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404nobuilt from the service's response
connection_unauthorized401noGoogle rejected the access token (expired or revoked); refresh or reconnect it.
rate_limited429, 403yesbuilt from the service's response
forbidden403nobuilt from the service's response
invalid_request400nobuilt from the service's response
conflict409nobuilt from the service's response
Ask a question... ⌘I