Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
dynamitecircle avatar

DC Member API

  • 5 repo stars
  • Updated July 15, 2026
  • dynamitecircle/dc

Official clients for the [Dynamite Circle Member API](https://www.

About

Official clients for the [Dynamite Circle Member API](https://www.dynamitecircle.com/developers/) - your own profile, trips, events, virtual events, tickets, invites, inbox, rooms, chapters, places lookup, and the weekly locator digest. Official clients for the [Dynamite Circle Member API](https://www.dynamitecircle.com/developers/) - your own profile, trips, events, virtual events, tickets, invites, inbox, rooms, chapters, places lookup, and the weekly locator digest. The TypeScript client is an npm library for trusted server-side TypeScript projects. It is not a CLI and not an MCP server.

  • The TypeScript client is an npm library for trusted server-side TypeScript projects. It is not a CLI and not an MCP serv
  • py/dc.py ← Python: CLI + library + MCP server
  • ts/src/ ← TypeScript: npm library
  • contracts/ ← pinned OpenAPI contract shared by both clients
  • Never used Claude Code, Codex, or git? Here's the 5-minute path from zero to "Claude can read my DC profile."

DC Member API by the numbers

  • Exposes 78 verified tools (MCP introspection)
  • Data as of Jul 15, 2026 (Skillselion catalog sync)
terminal
claude mcp add --transport http dc https://api.dynamitecircle.com/mcp

Add your badge

Show developers this MCP server is listed on Skillselion. Paste this into your README.

Listed on Skillselion
repo stars5
TransportHTTP
AuthNone
Tools78
Last updatedJuly 15, 2026
Repositorydynamitecircle/dc

How do agents access DC Official Clients capabilities without custom integration code?

Official clients for the [Dynamite Circle Member API](https://www.dynamitecircle.com/developers/) - your own profile, trips, events, virtual events, tickets, invites, inbox, rooms, chapters, places lo

Who is it for?

Developers wiring DC Official Clients into Cursor, Claude Desktop, or other MCP clients.

Skip if: Teams that need features outside the documented DC Official Clients tool surface.

What you get

Configured MCP host can call DC Official Clients tools with schemas from the server README.

By the numbers

  • [object Object]
At a glance

DC Member API capabilities & compatibility

Capabilities
the typescript client is an npm library for trus · py/dc.py ← python: cli + library + mcp server · ts/src/ ← typescript: npm library · contracts/ ← pinned openapi contract shared by b
Use cases
api development · orchestration
Runs
Runs locally
Pricing
Bring your own API key

Tools 78

Public tool metadata - what this server can do for an agent.

announcements2 params

GET /announcements — List recent announcements Returns the most recent announcements from DC's broadcast channels — official updates from the DC team and chapter staff (DC, DCBKK, DCMEX, DC BLACK, etc.). Same content you see in the app's announcements channels, in a flat newest-first feed. Visibility mirrors the app: DC members see DC-scope announcements; DC BLACK members and staff additionally see DC BLACK announcements. There is no posting, replying, or per-channel filtering — announcements are intentionally one-way and minimal.

  • limitnumberMax announcements to return (1-50)
  • cursorstringOpaque cursor from a previous response's `nextCursor`
announcements_latest

GET /announcements/latest — Latest announcement per channel (quick overview) Returns the **single most recent announcement from each visible channel** — a one-shot overview rather than a paged feed. Useful as a "what's new across DC?" quick check before drilling into the full feed via `GET /announcements`. Visibility rules are identical to `/announcements`: DC members see DC-scope channels; DC BLACK members and staff additionally see DC BLACK channels. No pagination — the result size equals the number of dispatch channels you can see (currently ~4).

trips3 params

GET /trips — List your trips Returns your upcoming trips by default. Add `?past=true` to include past trips. **For "who should I meet on this trip?"** fetch `GET /trips/:tripID` (or the discovery-only `GET /trips/:tripID/discovery`) — both return the ranked top-10 DCers + AI-written summaries + the full pool of locals and visitors in town during the trip window. The list response below does NOT include the discovery block (lazy by design — discovery is a much heavier payload).

  • pastbooleanInclude past trips.
  • limitnumberMax results (1-100).
  • cursorstringCursor from a previous response's `nextCursor`. Pass to fetch the next page.
trips_create6 params

POST /trips — Create a trip Create a new trip. Provide exactly one of `placeID` or `eventID` — the server resolves the location (city, country, country code) automatically. Use `GET /places/search` to find a placeID by city/country name first, or pass an `eventID` from `/events` to create a trip to that event's city. **Trip points** (optional `points` array, up to 20 per trip): each item is `{ note: string (max 280 chars), noteHTML?: string, placeID?: string }`. The optional `placeID` is resolved against Google Places at write time and the full Place object (city, country, lat/lon, name, etc.) is stored on the trip — so reads don't do any lookups. `noteHTML` preserves the same rich text field the web trip editor stores for formatted notes, links, and mentions; `note` remains the required plain-text fallback. Notes without a placeID are valid ("remember to book a coworking space"). Pass an unknown / expired Google placeID → 400 with a clear error. ⚠️ WRITE operation: this mutates you

  • startDatestringrequiredStart date (ISO 8601)
  • endDatestringrequiredEnd date (ISO 8601)
  • placeIDstringGoogle Place ID for the destination. Look one up via `GET /places/search`. **Pass exactly one of `placeID` or `eventID`** — sending both rejects with 400.
  • eventIDstringDC event ID. Server uses the event's city placeID. **Pass exactly one of `placeID` or `eventID`** — sending both rejects with 400.
  • notestringTrip note
  • pointsarrayOptional. Up to 20 trip points (venues / ideas / notes). Each item: `{ note: string (max 280 chars), noteHTML?: string, placeID?: string }`. The optional `placeID` is resolved against Google Places at write time. Notes without a place are valid.
trip_update7 params

PATCH /trips/:tripID — Update a trip Update one or more fields on an existing trip. Only include the fields you want to change. To change destination, provide either `placeID` or `eventID` and the full location will be re-resolved. **Trip points**: passing `points` replaces the entire array (it's not a patch within the array). Up to 20 items, same shape as `POST /trips`: `{ note: string (max 280 chars), noteHTML?: string, placeID?: string }`. To clear all points, pass `points: []`. ⚠️ WRITE operation: this mutates your DC account data.

  • tripIDstringrequiredThe trip ID to update
  • startDatestringNew start date (ISO 8601)
  • endDatestringNew end date (ISO 8601)
  • placeIDstringNew destination — Google Place ID
  • eventIDstringNew destination — DC event ID (uses event's city). Pass `null` to unlink without changing the location.
  • notestringUpdated note
  • pointsarrayOptional. Replace the entire `points` array (not a patch within). Up to 20 items, same shape as `POST /trips`. Pass `[]` to clear all points.
trip_delete1 param

DELETE /trips/:tripID — Delete a trip Permanently delete one of your trips. Removes the trip doc and its linked chat room (`trip.roomID`). The destination chapter's upcoming-trip count is recomputed in the background. **Owner-only** — you can only delete trips you created. The action is irreversible; deleted trips don't go to a trash collection. ⚠️ WRITE operation: this mutates your DC account data.

  • tripIDstringrequiredThe trip ID to delete
trips_overlaps1 param

GET /trips/overlaps — Find overlapping trips Find other members whose trips overlap with yours by city + date range. **This is a narrow date-window match, NOT the AI-ranked discovery pool.** For the full set of DCers you could meet on a trip — including locals in town and AI-written "why you should meet them" summaries — fetch `GET /trips/:tripID/discovery` (or `GET /trips/:tripID`, which embeds the same `discovery` block). The discovery pool is typically 5–10× larger than `/trips/overlaps` because it includes locals and event attendees in addition to date-overlap visitors, and it carries ranked top-10 picks with AI summaries that this endpoint does not. Use `/trips/overlaps` for the simple "who is travelling here at the same time as me" question. Use `/trips/:tripID/discovery` for "who should I meet on this trip?".

  • limitnumberMax trips to check (1-20)
trip1 param

GET /trips/:tripID — Get a single trip Single-trip read with the full payload. **This is the canonical endpoint for "who should I meet on this trip?"** — the response embeds a complete `discovery` block (ranked top-10 picks with AI summaries, the full pool of locals + visitors, events in town, and date-overlapping trips). If you only want the discovery block without the trip body, use `GET /trips/:tripID/discovery`. **Key discovery fields agents almost always want:** - `discovery.people` — **ranked top-10 DCers to meet** on this trip, each carrying `score` (higher = better match), mini `profile` (userID, userName, displayName, photo, headline), `reason` (`local` / `visiting` / `event-attendee`), `overlapDays`, `detail`. Sourced from a vector-search + business-context ranking, not just date overlap. - `discovery.whyToMeet` — **AI-written "why you should meet them" paragraph** for each of the top-10, keyed by userID, each `{ text, generatedAt }`. The most useful AI signal in the whole

  • tripIDstringrequiredThe trip ID
trip_refresh_create1 param

POST /trips/:tripID/refresh — Trigger a trip refresh Owner-only sync trigger. Enqueues a deduped background job that recomputes the trip's discovery (overlapping people, events, AI blurbs). Spammy reloads coalesce. Returns 202 Accepted immediately; the cached `discovery` block on the trip doc updates when the job completes. ⚠️ WRITE operation: this mutates your DC account data.

  • tripIDstringrequiredThe trip ID to refresh
trip_discovery2 params

GET /trips/:tripID/discovery — Get the discovery block for a trip Discovery-only read for a trip. Returns the same `discovery` block as `GET /trips/:tripID` (people, fullPool, whyToMeet, events, overlappingTrips) without the trip body. Useful for callers that just want "who should I meet on this trip?" — the AI agent gets the ranked top-10 + their `whyToMeet` paragraphs in a single request. Use `?include=` to subset the response — comma-separated from `people,fullPool,whyToMeet,events,overlappingTrips`. Default is all. Common patterns: - `?include=people,whyToMeet` — top-10 picks + their AI-written "why you should meet them" paragraphs (keyed by userID, each carrying `{ text, generatedAt }`) - `?include=fullPool` — every visible DCer travelling/local during the trip window - `?include=events` — just events in the destination city during the trip window Open to any authenticated DCer; hidden + guest profiles are filtered out.

  • tripIDstringrequiredThe trip ID
  • includestringOptional. Comma-separated subset of `people,fullPool,whyToMeet,events,overlappingTrips`. Default = all five.
chapters2 params

GET /chapters — List chapters List all DC chapters (city-based community hubs), sorted by member count. Each chapter has a Google Place ID — pass it to `POST /trips` to create a trip to that chapter's city. **See also:** For a chapter by city or country name (`q='Lisbon'`, `q='Thailand'`), `POST /search/chapters` searches city + country names directly — faster than paginating this member-count-sorted list.

  • limitnumberMax chapters to return (1-100).
  • cursorstringCursor from a previous response's `nextCursor`. Pass to fetch the next page.
chapter1 param

GET /chapters/:cityID — Get a single chapter Get full details for a single chapter, including up to 100 home-chapter members and the list of DCers currently visiting via active trips. - `members` — DCers whose **home chapter** is this city (up to 100). - `currentVisitors` — DCers with an active trip to this city (`startDate <= now <= endDate`). Each entry carries a mini `profile` block, the visitor's `tripID`, and trip start/end dates. Use this to answer "who is in <city> right now?" — both locals (via `members`) and visitors (here). Hidden + guest profiles are filtered from both lists.

  • cityIDstringrequiredChapter ID (same as Google Place ID)
events3 params

GET /events — List upcoming events Returns upcoming DC events, sorted by date. Add `?past=true` to include past events. **See also:** For events by name or topic (`q='productivity'`, `q='DCBKK 2026'`), `POST /search/events` searches title + description directly — faster than paginating this date-sorted list. Combine with `?cityID`, `?country`, `?since`, `?until` filters for narrower scopes.

  • pastbooleanInclude past events.
  • limitnumberMax results (1-50).
  • cursorstringCursor from a previous response's `nextCursor`. Pass to fetch the next page.
event1 param

GET /events/:eventID — Get event details Returns full details for a specific event, including your ticket status.

  • eventIDstringrequiredThe event ID
event_attendees2 params

GET /events/:eventID/attendees — List event attendees List the confirmed attendees of an event — DCers holding a `valid` paid ticket OR a `valid`/`maybe` RSVP status. Refunded/canceled tickets are excluded. Hidden and guest profiles are filtered out. Profiles returned use the same shape as the rest of the API (`GET /profile-match`, `GET /trips/:tripID/discovery`, etc.) — full public-other-person view including businessName, socials, expertise, plus privacy-gated annualRevenue + teamSize where shared. **Access:** any active DCer can view event attendees, matching the in-app attendee tab.

  • eventIDstringrequiredThe event ID
  • limitnumberMax results (1-100).
event_rsvp2 params

POST /events/:eventID/rsvp — RSVP to a free event RSVP to an event that uses free RSVP (not ticketed). Only works for events with rsvpEnabled: true. ⚠️ WRITE operation: this mutates your DC account data.

  • eventIDstringrequiredThe event ID
  • statusstringrequiredRSVP status
event_schedule1 param

GET /events/:eventID/schedule — Get event schedule Returns the full schedule (sessions) for an event, sorted chronologically. **Access:** any active DCer who can see the event can view its public schedule. Personal agenda actions still require a valid ticket. **Time-zone handling:** session `startAt` / `endAt` are returned as ISO 8601 strings whose digits represent the **venue-local wall-clock time** (e.g. a 9 AM Mexico City session returns `2026-05-08T09:00:00.000Z`, NOT `15:00:00Z`). The session's `timezone` field carries the IANA zone (e.g. `America/Mexico_City`) — pair them when localizing. This matches the convention used by the DC ICS feed.

  • eventIDstringrequiredEvent ID
event_agenda1 param

GET /events/:eventID/agenda — Get your personal agenda for an event Returns the sessions and meetups **YOU** have on your personal agenda for an event: - Sessions you bookmarked from the schedule. - Meetups you RSVPd to. **Access:** caller must hold a valid ticket to the event. Use `POST /events/:eventID/schedule/:sessionID/bookmark` and `POST /events/:eventID/meetups/:meetupID/rsvp` to manage entries.

  • eventIDstringrequiredEvent ID
event_agenda_get2 params

GET /events/:eventID/agenda/:userID — Get another attendee's agenda for an event Returns another attendee's personal agenda for an event — the sessions they bookmarked + meetups they RSVPd to. Use this so an AI agent can plan together with another DCer (find a coffee window, suggest sessions to overlap, propose a meetup). **Access:** open to any active DCer who can see the event. The target must hold a valid ticket — otherwise there is no agenda to return (404).

  • eventIDstringrequiredEvent ID
  • userIDstringrequiredTarget attendee userID
event_schedule_attendees2 params

GET /events/:eventID/schedule/:sessionID/attendees — List session attendees (people who bookmarked it) Returns the list of attendees who have **bookmarked** a specific session into their agenda. Same profile shape as `/events/:eventID/attendees`. **Access:** any active DCer who can see the event.

  • eventIDstringrequiredEvent ID
  • sessionIDstringrequiredSession ID
event_meetups1 param

GET /events/:eventID/meetups — List event meetups Returns the approved member-organized meetups for an event, sorted chronologically. Only approved meetups are returned. **Access:** any active DCer who can see the event can view approved meetup listings + attendee lists. Only RSVPing to a meetup (and the resulting chat-channel access) requires a valid ticket. **Time-zone handling:** meetups use explicit wall-clock fields (`date` = YYYY-MM-DD, `startTime` / `endTime` = HH:mm) plus the event's `timezone` (IANA). Pair them when localizing.

  • eventIDstringrequiredEvent ID
event_meetup_attendees2 params

GET /events/:eventID/meetups/:meetupID/attendees — List meetup attendees Returns the list of attendees who have RSVPd to a specific meetup. Same profile shape as `/events/:eventID/attendees`. **Access:** any active DCer who can see the event.

  • eventIDstringrequiredEvent ID
  • meetupIDstringrequiredMeetup ID
event_sponsors1 param

GET /events/:eventID/sponsors — List event sponsors Returns the sponsors for an event, ordered by tier (primary → supporting) then display order. Deleted sponsors are filtered out. **Access:** any active DCer who can see the event — sponsors are public.

  • eventIDstringrequiredEvent ID
event_schedule_bookmark3 params

POST /events/:eventID/schedule/:sessionID/bookmark — Bookmark / unbookmark a session Add or remove a session from your personal agenda — this is the API equivalent of the bookmark/star icon on a session card in the DC app. Requires a valid ticket for the event. Counter `rsvpCount` on the session doc is updated atomically and idempotently: repeating the same desired state does not increment or decrement the counter again. ⚠️ WRITE operation: this mutates your DC account data.

  • eventIDstringrequiredEvent ID
  • sessionIDstringrequiredSession ID
  • bookmarkedbooleanrequired`true` to add to agenda, `false` to remove
event_meetup_rsvp3 params

POST /events/:eventID/meetups/:meetupID/rsvp — RSVP to / leave a meetup Join or leave a meetup. Requires a valid ticket for the event. The meetup's `rsvpCount` is updated atomically and idempotently. When the meetup has a linked chat channel, this mirrors the DC app side effects too: joining subscribes you to the meetup chat and leaving removes you from it. ⚠️ WRITE operation: this mutates your DC account data.

  • eventIDstringrequiredEvent ID
  • meetupIDstringrequiredMeetup ID
  • joinedbooleanrequired`true` to join, `false` to leave
event_agendas2 params

GET /events/:eventID/agendas — Get multiple attendees' agendas in one call Returns the agendas (bookmarked sessions + meetup RSVPs) for **multiple** attendees in a single call. Use when an AI agent needs to plan around several DCers at once — comparing schedules, finding shared sessions, building a meetup invite list. **Query**: `userIDs=A,B,C` — comma-separated. Max 20 IDs per call. **Behavior**: silently drops IDs that don't hold a valid ticket (so the AI doesn't need to pre-filter). Returns only the agendas for confirmed attendees, in the order requested. **Access:** open to any active DCer who can see the event (non-attendee target IDs are silently dropped).

  • eventIDstringrequiredEvent ID
  • userIDsstringrequiredRequired. Comma-separated userIDs (max 20). Non-attendees are silently dropped.
event_free_slots_create4 params

POST /events/:eventID/free-slots — Find shared free time slots across attendees Computes shared **free slots** across a set of event attendees — the time windows where they're NOT in a bookmarked session or meetup. Use to find a coffee window with one DCer, or a junto-style lunch slot for a group. **Body**: `userIDs[]` (1-20), `minDurationMinutes` (default 30, min 15, max 480), optional `eventDayDate: YYYY-MM-DD` to scope to a single event day. **Slot grid**: derived from the event's session schedule, partitioned into `minDurationMinutes` windows. For each window we subtract each user's bookmarked sessions + meetup RSVPs. **Sort**: slots ranked by `len(freeFor)` desc — fully-shared windows first, then partial overlaps. **Auth**: caller must hold a valid ticket. Non-attendee IDs are silently dropped. ⚠️ WRITE operation: this mutates your DC account data.

  • eventIDstringrequiredEvent ID
  • userIDsarrayrequiredAttendee userIDs to compare (1-20). Non-attendees silently dropped.
  • minDurationMinutesnumberMinimum slot duration in minutes (default 30, range 15-480)
  • eventDayDatestringOptional. Scope to a single event day (YYYY-MM-DD venue-local). Omit for the full event range.
follows_profiles

GET /follows/profiles — List followed DCers List the DCers you are currently following. Returns the same mini-profile shape used by every other list endpoint, so each entry roundtrips cleanly with `GET /profile/:userID` or `POST /follows/profiles/:userID`. Cap: 150 follows; the response `cap` echoes that so a client can warn the user as they approach the limit. This list also drives the `/locator/digest` `favoritePeople` and `favoriteCities` sections — surface trip + event activity from DCers and cities you care about without scrolling everywhere.

follows_profiles_by_id_create1 param

POST /follows/profiles/:userID — Follow a DCer Follow a DCer. Idempotent — calling it twice with the same userID is safe (no-op the second time). Target must exist and be publicly visible (hidden + guest profiles are refused with 404). You cannot follow yourself. When the cap of 150 is reached, returns `409 follow_limit_reached` with a hint to unfollow someone first. The response includes the new `profile` mini-card and updated `count` so the caller can render the change without re-fetching. This list also drives the `/locator/digest` `favoritePeople` and `favoriteCities` sections — surface trip + event activity from DCers and cities you care about without scrolling everywhere. ⚠️ WRITE operation: this mutates your DC account data.

  • userIDstringrequireduserID of the DCer to follow. Discover via `GET /profile-match` or `GET /chapters/:cityID` members lists.
follows_profiles_by_id_delete1 param

DELETE /follows/profiles/:userID — Unfollow a DCer Unfollow a DCer. Idempotent — unfollowing someone you weren't following is a no-op (still returns 200 with the updated `count`). Use it whenever you want to stop seeing a DCer in your `/locator/digest` favoritePeople section. ⚠️ WRITE operation: this mutates your DC account data.

  • userIDstringrequireduserID of the DCer to unfollow.
follows_chapters

GET /follows/chapters — List followed chapters List the DC chapters (city hubs) you are currently following. Each entry is a mini-chapter with the chapter's Google Place ID — useful for creating trips or surfacing activity in that city. Cap: 50 follows. This list also drives the `/locator/digest` `favoritePeople` and `favoriteCities` sections — surface trip + event activity from DCers and cities you care about without scrolling everywhere.

follows_chapter_create1 param

POST /follows/chapters/:cityID — Follow a chapter Follow a DC chapter (city hub). Idempotent. Target must exist in the chapters list (discover via `GET /chapters`). Cap 50 — hitting it returns `409 follow_limit_reached`. This list also drives the `/locator/digest` `favoritePeople` and `favoriteCities` sections — surface trip + event activity from DCers and cities you care about without scrolling everywhere. ⚠️ WRITE operation: this mutates your DC account data.

  • cityIDstringrequiredChapter ID (Google Place ID). Get from `GET /chapters` (each entry has `cityID`) or `GET /places/search` (`type === "city"`).
follows_chapter_delete1 param

DELETE /follows/chapters/:cityID — Unfollow a chapter Unfollow a DC chapter. Idempotent — unfollowing a chapter you weren't following is a no-op. ⚠️ WRITE operation: this mutates your DC account data.

  • cityIDstringrequiredChapter ID to unfollow.
inbox_unread1 param

GET /inbox/unread — Get unread counts Returns your total unread message count and per-room breakdown. Only includes rooms you are subscribed to or are a member of.

  • limitnumberMax rooms to return (1-100).
invites2 params

GET /invites — List your invites List the referral invites credited to you. Two source types appear: - **`manual`** — invites you sent via `POST /invites` (the explicit email-an-invitee flow). - **`permaCode`** — applicants who signed up through your shareable permacode link (`GET /invites/permacode`). Each record tracks where the prospective member is in the funnel (`new` → `invited` → `started` → `submitted` → `approved`/`rejected`/`expired`), the invite type, the invitee's name + email, and timestamps. Read-only.

  • limitnumberMax results (1-100).
  • cursorstringCursor from a previous response's `nextCursor`. Pass to fetch the next page.
invites_create3 params

POST /invites — Send an invite Send a referral invite to someone. The server queues a templated email (delivered via a background task) that points the invitee at the apply flow with you pre-credited as the referrer. The created invite shows up in `GET /invites` immediately at status `new`. ⚠️ WRITE operation: this mutates your DC account data.

  • fullNamestringrequiredInvitee full name. Used in the email greeting + matched against existing applications for dedup.
  • emailstringrequiredInvitee email address. Where the invite email is sent.
  • whyDCstringOptional. Short note about why they would be a good fit for DC — surfaces in the admin review queue if the application reaches it.
invites_permacode

GET /invites/permacode — Get your permacode Returns your permanent referral code. Share this link to let people apply with your referral.

calendar

GET /calendar — Get your iCalendar feed URL + settings Returns your iCalendar feed URLs and the toggles that control which event categories the feed includes. **Three URLs are returned:** - `httpsURL` — paste into any calendar app that accepts an HTTPS subscription - `webcalURL` — same URL with the `webcal://` scheme; macOS / iOS Calendar opens it directly - `googleURL` — one-click Google Calendar subscribe link The feed includes events you have tickets to, virtual calls, your trips, chapter events, and flagship events — exactly what each `include*` toggle below controls. Tokens are deterministic, so the URLs never change for a given member.

calendar_update9 params

PATCH /calendar — Update calendar feed settings Update any subset of your calendar feed toggles. Send only the toggles you want to change — omitted fields are left untouched. Returns `{ updated: true }` on success; re-fetch `GET /calendar` if you need the full toggle set + feed URLs (the URLs themselves are stable and don't change when toggles update). ⚠️ WRITE operation: this mutates your DC account data.

  • includeDCBlackEventsbooleanBoolean
  • includeEventAgendabooleanBoolean
  • includeFlagshipEventsbooleanBoolean
  • includeFollowedChapterEventsbooleanBoolean
  • includeHomeChapterEventsbooleanBoolean
  • includeMyTicketsbooleanBoolean
  • includeMyTripsbooleanBoolean
  • includeOtherChapterEventsbooleanBoolean
  • includeVirtualCallsbooleanBoolean
limits

GET /limits — Get your effective rate limits + current usage Returns the effective per-minute and per-day rate limits for your API key, **plus current usage** (how many calls you have already made in the current minute and day windows, when each window resets, and how many calls you have left). Limits derive from your membership tier (DC member: 10/min, 300/day; DC BLACK member and staff: 60/min, 3000/day) unless an admin has set per-key overrides — overrides win when present. The same usage data is also exposed on every API response via the `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `X-RateLimit-Daily-Remaining`, and `X-RateLimit-Daily-Reset` headers. Use this endpoint when you want a JSON snapshot, or the headers when you want to read it on every call.

locator_digest1 param

GET /locator/digest — Get locator digest Returns your weekly locator digest — the same data that powers the Friday locator email. Use this to surface trip/event activity around the people and cities a member already follows. The response is composed of four independent sections; pass `?sections=<csv>` to skip any you don't need. Each section is described in full below. - **`homeCity`** — Activity in the city you have set as your home chapter. Null if you have no home city, or if you don't belong to any chapter yet. - **`favoriteCities`** — Per-city digest for cities you have favorited (besides your home city). Each entry lists upcoming trips/events into that city + new ones added since last week. - **`favoritePeople`** — Recent activity from members you follow: their new trips, upcoming trips, recently purchased tickets, and events they've RSVPd to. - **`myTrips`** — For each of your own upcoming trips, the people you're likely to overlap with (chapter leads, local members, and othe

  • sectionsstringComma-separated list of sections to include. Defaults to all four sections when omitted.
locator_settings

GET /locator/settings — Get your Friday locator email settings Returns the four toggles that control the Friday locator email digest. The digest is a weekly outbound email surfacing new events, tickets, and trips relevant to you.

locator_settings_update4 params

PATCH /locator/settings — Update your Friday locator email settings Update any subset of the Friday locator email toggles. Send only the fields you want to change. ⚠️ WRITE operation: this mutates your DC account data.

  • enabledbooleanMaster toggle for the Friday digest
  • eventsbooleanInclude new events in your area
  • ticketsbooleanInclude DCers you follow getting event tickets
  • tripsbooleanInclude new trips to your area
membership

GET /membership — Get your membership state Returns your full membership state: role, lifecycle dates, trial status, billing/subscription details, and a link to the Stripe Customer Portal where you can manage your subscription, payment methods, and download invoices.

membership_invoices1 param

GET /membership/invoices — List your Stripe invoices Returns your Stripe invoices, newest first. Each entry includes a hosted-invoice URL and a PDF link, both safe to share — perfect for self-serve receipts. Returns an empty array for legacy paypal/chargify members or members with no Stripe customer.

  • limitnumberMax results (1-100)
notifications

GET /notifications — Get your notification preferences Returns your push + email preferences per notification category. Defaults are applied for any preference you have never explicitly set. Email is `null` for `reaction` / `myReaction` because email is not supported for those categories. For the Friday locator email digest, see `GET /locator/settings` — that's a separate concern (outbound digest, not per-event push/email).

notifications_update1 param

PATCH /notifications — Update your notification preferences Update any subset of your notification preferences. Send only the categories/channels you want to change — the rest stay as-is. Email is rejected for `reaction` / `myReaction` (not supported). ⚠️ WRITE operation: this mutates your DC account data.

  • categoriesobjectrequiredPer-category push/email toggles. Pass only the categories + channels you want to change.
places_search2 params

GET /places/search — Search Google Places Search for places by name. Use this to look up a Google Place ID before creating a trip or referencing a venue. Results include a `type` field that classifies each match as `city` (a chapter-level locality usable for trips) or `venue` (a specific establishment, address, or country/region match — usable for events/meetups but rejected by `POST /trips`). Filter on `type === "city"` if you're building a trip-creation flow; pass either type to event/meetup APIs. Every result also includes the full enriched location (`description`, `lat`, `lon`, `region`, `regionCode`, `utcOffsetMins`) so the same payload can be passed straight to `POST /trips` without a follow-up `GET /places/:placeID` lookup.

  • qstringrequiredSearch query (city name, country, address, etc.)
  • limitnumberMax results (1-20)
place1 param

GET /places/:placeID — Get place details Fetch full details for one Google Place ID. Useful for verifying a placeID before sending it to `POST /trips` (which only accepts `type: "city"` placeIDs and rejects venues with a 400). Same shape as a single entry from `GET /places/search`.

  • placeIDstringrequiredGoogle Place ID. Get one from `GET /places/search` or from a previous response (e.g. `event.city.placeID`).
profile_match_create11 params

POST /profile-match — Match DCers from a description (or recommend if omitted) **AI-powered profile matchmaker.** Match DCers against a natural-language description, or — when `query` is omitted — recommend DCers based on your own profile (chapter, industry, expertise, goals). Returns ranked results from a profile-vector search (Gemini embeddings + reranking under the hood). The caller's LLM synthesizes any narrative on top. Stricter rate limits than the standard CRUD endpoints because of the embedding/rerank cost. **Two modes**: - **With `query`**: free-form description ("DCers in Lisbon who run SaaS"). - **Without `query`**: AI builds an implicit query from your profile and returns "DCers you should meet". Useful for cold-start "who should I message this week?" prompts. **Optional structured filters** (combine with either mode, all AND-ed): - `locationChapterPlaceID` — narrow to DCers whose home / base location matches this Google Place ID. Use for "based in X" queries. Resolve v

  • querystringFree-form description of the DCers you want to find. Omit to get recommendations based on your own profile.
  • locationChapterPlaceIDstringOptional. Google Place ID — narrows results to DCers based here ("based in X"). Resolve via `GET /places/search`.
  • locationCurrentPlaceIDstringOptional. Google Place ID — narrows results to DCers currently here, whether they live there or are visiting. **Sparsely populated** — `currentLocation` is self-reported and most DCers leave it null, so this filter under-recalls. For "who is in <city> right now?" prefer creating a trip via `POST /trips` and reading `GET /trips/:tripID` — the `discovery.fullPool` block lists locals AND visitors during the trip window. Resolve placeIDs via `GET /places/search`.
  • eventIDstringOptional. DC event ID — narrows results to DCers with a valid ticket (RSVP yes/maybe or paid). Pair with `query` for "DCers attending X who do Y".
  • isDCBbooleanOptional. When `true`, narrows results to DC BLACK members only.
  • businessIndustrystringOptional. Exact-match filter on the DCer's primary business industry. Allowed values: `SaaS & Tech`, `Marketing Agency`, `Productized Services`, `Ecommerce & Amazon`, `Courses and Info Products`, `Affiliate, Content Creation, or Ad Revenue`, `Professional Services & Industry Specific Consulting`, `Real Estate and Investing`, `Coaching`, `Other`.
  • minTeamSizestringOptional. "At least this team size" filter — matches DCers whose team-size bucket is >= this value, ordered as `None < 1-2 < 3-5 < 6-9 < 10-14 < 15-19 < 20-34 < 35-49 < 50-74 < 75-99 < 100+`. `Prefer not to say` also exists in the bucket vocabulary but is treated as "unknown" and always filtered out. Only DCers who set their team-size visibility to "all DCers" are matched; the rest are excluded silently.
  • minAnnualRevenuestringOptional. "At least this revenue" filter on annual revenue. Pass any revenue label (e.g. `$1M+`, `$250K+`, `$100K+`); the filter parses to a number and matches DCers at-or-above. Only DCers who set their revenue visibility to "all DCers" are matched; the rest are excluded silently.
  • genderstringOptional. Exact-match filter on the DCer's self-reported gender. Allowed values: `Man`, `Woman`, `Non-binary`, `Prefer not to say`. **Note: Gender is sparsely populated — most DCers leave it blank** — combine with `query` rather than relying on this alone.
  • skipRerankingbooleanOptional. When `true`, skip the keyword reranker and return results in raw vector-similarity order. Useful when the query is fuzzy/semantic (where exact keyword overlap would add noise) or when comparing reranked vs raw ordering.
  • limitnumberMax results (1-50, default 50). Hard cap at 50 — match is expensive; narrow with filters instead of paginating.
profile

GET /profile — Get your own profile Returns your own full profile — every field the in-app profile editor surfaces to you, plus tier-derived state. Same shape regardless of tier (DC and DC BLACK members get identical own-profile payloads). Use `PATCH /profile` to update editable fields.

profile_update30 params

PATCH /profile — Update profile fields Update allowed profile fields. Only the fields you include will be changed. Location, photo, and gender cannot be updated via API. ⚠️ WRITE operation: this mutates your DC account data.

  • headlinestringOne-sentence elevator pitch shown at the top of your DC profile (max 64 chars).
  • businessNamestringName of the main business you run or are primarily focused on right now (max 256 chars). You can list other businesses in `otherBusinesses`.
  • businessDescriptionstringDescription of your primary business. Plain text or HTML, up to 1600 chars.
  • businessWebsitestringPublic website for your primary business — single URL only (max 256 chars).
  • businessIndustrystringCategory your primary business fits into. Must be one of the predefined industries.
  • annualRevenuestringApproximate annual revenue (in U.S. dollars) of your primary business over the last 12 months. Predefined bracket.
  • annualRevenueIsPrivatebooleanVisibility of your revenue. `true` = hidden from other DCers (only DC staff can see it); `false` = visible to all DCers.
  • teamSizestringNumber of full-time and part-time team members in your primary business. Predefined bracket.
  • teamSizeIsPrivatebooleanVisibility of your team size. `true` = hidden from other DCers (only DC staff can see it); `false` = visible to all DCers.
  • yearsInBusinessstringHow long you have been on the entrepreneurial path. Used for matching with other members. Predefined bracket.
  • otherBusinessesstringOther businesses you currently operate. Feel free to share URL, short description, and year started for each (up to 1600 chars).
  • previousBusinessesstringPrevious business exits and entrepreneurial experience worth listing (up to 1600 chars).
  • linkedinstringLinkedIn username only (no URL prefix). 1-50 chars: letters, digits, `.`, `_`, `-`.
  • twitterstringTwitter/X username only (no URL prefix). 1-15 chars: letters, digits, `_`.
  • instagramstringInstagram username only (no URL prefix). 1-30 chars: letters, digits, `.`, `_`.
  • facebookstringFacebook username only (no URL prefix). 5-50 chars: letters, digits, `.`.
  • focusmatestringFocusmate username only (no URL prefix). 3-50 chars: letters, digits, `_`, `-`.
  • githubstringGitHub username only (no URL prefix). 1-39 chars per GitHub's rules: letters, digits, `-`. Required to be granted access to the public DC client repo — set this to opt in.
  • whatsAppstringWhatsApp phone number in international format — `+` followed by 5-16 digits, no dashes or spaces. Required if you want to be added to the DC WhatsApp community. Always private — only visible to DC staff.
  • expertisestringAreas you might consider yourself an expert in — skills you can use to help other members (up to 1600 chars).
  • askMeAnythingTopicsstringTopics other members can ask you about, in your field of expertise (up to 1600 chars).
  • hobbiesstringYour non-business hobbies — games, camping, art, sports, anything (up to 1600 chars).
  • currentChallengestringYour current business challenge or goal. Used internally to match you with other members who can help (up to 1600 chars).
  • peopleOfIntereststringWhat kinds of community members you would like to connect with. Used to send recommendations of relevant DCers (up to 1600 chars). Set `peopleOfInterestIsPrivate: true` to keep this visible only to DC staff.
  • peopleOfInterestIsPrivatebooleanVisibility of your "who I want to meet" answer. `true` = hidden from other DCers (only DC staff can see it); `false` = visible to all DCers.
  • relevantLocationsstringCities or regions you frequently visit. Helps surface trip overlaps with other members (up to 1600 chars).
  • nicknamestringDisplay name override — what other DCers see in addition to your real name (max 256 chars).
  • spouseNamestringName of your spouse or partner — used only for the DCBKK partner pass. Always private (DC staff only).
  • shirtSizestringT-shirt size — used when DC sends event swag.
  • dietstringDietary restrictions — used when DC plans event meals.
report_issue_create4 params

POST /report-issue — Report an issue or feedback Submit a bug report, feedback, or question to the DC team. Optionally include a base64-encoded screenshot (PNG, JPEG, or WebP, up to 4 MB raw). **Privacy note:** Screenshots and report text are sent unredacted to the DC team. Don't include passwords, payment details, or other secrets. ⚠️ WRITE operation: this mutates your DC account data.

  • textstringrequiredA short description of the issue or feedback (1–4000 chars).
  • severitystringSeverity: bug | feedback | question. Defaults to "bug".
  • screenshotstringOptional base64-encoded screenshot. Accepts raw base64 OR a data URL (e.g. `data:image/png;base64,...`). PNG, JPEG, or WebP only. Max 4 MB raw, clamped to 4096×4096; re-encoded server-side to strip EXIF.
  • contextobjectOptional structured debug context — anything useful for triage (last error, request payload, endpoint, etc.). Up to 32 keys.
rooms2 params

GET /rooms — List your subscribed rooms Returns every room you are subscribed to (DMs, group DMs, channels you follow, discussions, activities, event rooms), sorted by `lastActivityAt` descending. Cursor-paginated. To filter by type use `GET /rooms/inbox/:type` (e.g. `/rooms/inbox/dm` for DMs only).

  • limitnumberMax results (1-100)
  • cursorstringCursor from a previous response's `nextCursor`. Pass to fetch the next page.
rooms_inbox3 params

GET /rooms/inbox/:type — List your rooms by type Returns your subscribed rooms filtered to a single type. Same shape as `GET /rooms` but scoped — e.g. `/rooms/inbox/dm` returns DMs only, `/rooms/inbox/group` returns group DMs.

  • typestringrequiredRoom type filter. Allowed: `channel`, `dm`, `group`, `discussion`, `quick-question`, `event`.
  • limitnumberMax results (1-100)
  • cursorstringCursor from a previous response's `nextCursor`. Pass to fetch the next page.
rooms_browse3 params

GET /rooms/browse/:type — Browse public channels by type Browse publicly-joinable rooms of a given type that you are NOT yet subscribed to. The same surface the in-app Browse Channels modal shows. DC BLACK rooms are filtered out for DC tier members.

  • typestringrequiredRoom type to browse. Allowed: `channel`, `discussion`, `quick-question`.
  • limitnumberMax results (1-100)
  • cursorstringCursor from a previous response's `nextCursor`. Pass to fetch the next page.
rooms_by_id1 param

GET /rooms/:roomID — Get a single room Get a single room's metadata + its latest daily AND weekly AI summaries (when they exist). **Access:** members and subscribers of the room, plus any DCer for browsable public channels/discussions/quick-questions. Private rooms, DMs, group DMs, and event/city rooms you are not a member of return 403. Reading this endpoint does **not** mark the room as read or modify any unread state. **AI summaries:** the latest daily digest is embedded under `aiSummaryDaily`, the latest weekly digest under `aiSummaryWeekly`. Rooms that don't have a given type yet return `null` for that slot. For history (older summaries), call `GET /rooms/:roomID/summaries/daily` or `/weekly`. **See also:** For specific content (`did anyone mention X?`), `POST /search/messages` with `q=` and `roomID=` is faster than paginating `/rooms/:roomID/messages` or reading summaries. The AI summaries cover broad activity per window; search is the tool for targeted lookup.

  • roomIDstringrequiredRoom ID
rooms_summary2 params

GET /rooms/:roomID/summary/:type — Get the latest daily or weekly summary Get the latest single summary of a given type for a room. **Type is required** — daily and weekly summaries cover different windows and live in separate slots. Pass the type you want as a path segment. For history (multiple past summaries) use `GET /rooms/:roomID/summaries/:type`. Same access gate as `GET /rooms/:roomID`. **See also:** AI summaries cover broad activity per window. For specific content (`did anyone mention X?`), `POST /search/messages` with `q=` and `roomID=` is faster than reading summaries.

  • roomIDstringrequiredRoom ID
  • typestringrequiredSummary type — `daily` or `weekly`.
rooms_summaries4 params

GET /rooms/:roomID/summaries/:type — List past daily or weekly summaries List past summaries of a given type for a room, newest first. Cursor-paginated — pass `cursor` from the previous response to fetch the next (older) page. Each summary covers a non-overlapping window (one per day for daily, one per week for weekly). Use this for catch-up workflows ("show me the last 7 daily summaries before I rejoin the conversation"). Same access gate as `GET /rooms/:roomID`. **See also:** Summaries cover broad activity per window. For specific content (`did anyone mention X?`), `POST /search/messages` with `q=` and `roomID=` is faster than reading multiple summaries.

  • roomIDstringrequiredRoom ID
  • typestringrequiredSummary type — `daily` or `weekly`.
  • limitnumberMax results (1-50)
  • cursorstringCursor from a previous response's `nextCursor`. Pass to fetch the next (older) page.
rooms_messages3 params

GET /rooms/:roomID/messages — List messages in a room List messages in a room you are a member of. **Read-only — no write side effects, no unread-state mutation, no reactions/posts/edits.** Cursor-paginated newest-first. **Access:** strict — the caller must be a subscribed member of the room (same `seen` doc check used by the web inbox). For browsable public channels, any DCer can read. Private rooms, DMs (`dm`), group DMs (`group`), event rooms, and city/country/mastermind rooms hard-block non-members with 403. Hidden/deleted/sunk messages are excluded. **Pagination:** pass `?before=<nextCursor>` from a previous response to fetch the next (older) page. Default page size 50, max 50. **See also:** For specific content in this room (`did anyone mention X?`), `POST /search/messages` with `q=` and `roomID=` searches body text directly — far faster than paginating with `?before`. This endpoint is the right call when you want a chronological window (last N messages, conversation reconstr

  • roomIDstringrequiredRoom ID. Discover from `GET /rooms` (your subscribed list), `GET /inbox/unread`, `trip.roomID` on `GET /trips/:tripID`, or event chat-room IDs on `GET /events/:eventID`.
  • limitnumberMax results (1-50)
  • beforestringCursor from a previous response's `nextCursor` (encodes the previous page's oldest message timestamp). Pass to fetch the next older page.
rooms_subscribe_create1 param

POST /rooms/:roomID/subscribe — Subscribe to a room Subscribe to a public channel, discussion, quick-question room, or event room. The caller is added to the room's `seen` subcollection with `flags.isSubscribed: true` and starts receiving its updates in their inbox. **Access:** the room must be enabled, non-archived, non-private, non-hidden, and of a subscribable type (`channel`, `discussion`, `quick-question`, `event`). Event rooms additionally require a valid ticket to the linked event — call `/events/:eventID` first to verify ticket status. DMs and group DMs cannot be subscribed/unsubscribed via the API; they are managed in-app only. **Idempotent:** subscribing when already subscribed is a no-op (returns 200 with the current state). ⚠️ WRITE operation: this mutates your DC account data.

  • roomIDstringrequiredRoom ID
rooms_unsubscribe_create1 param

POST /rooms/:roomID/unsubscribe — Unsubscribe from a room Unsubscribe from a public channel, discussion, quick-question, or event room. The caller's `seen` doc is updated to `flags.isSubscribed: false`, the badge count is cleared, and the room drops out of the inbox sidebar. **Access:** the caller must already be a subscriber. DMs and group DMs cannot be unsubscribed via the API. **Idempotent:** unsubscribing when already unsubscribed is a no-op. ⚠️ WRITE operation: this mutates your DC account data.

  • roomIDstringrequiredRoom ID
rooms_mute_create1 param

POST /rooms/:roomID/mute — Mute a room Mute notifications for a room. Sets `mutedUntilAt` to a far-future timestamp (no expiry) — the room stays muted until explicitly unmuted. The room still appears in the inbox; only notifications are suppressed. **Access:** the caller must be a member/subscriber of the room. ⚠️ WRITE operation: this mutates your DC account data.

  • roomIDstringrequiredRoom ID
rooms_unmute_create1 param

POST /rooms/:roomID/unmute — Unmute a room Unmute a previously-muted room. Clears `mutedUntilAt`. **Access:** the caller must be a member/subscriber of the room. Idempotent. ⚠️ WRITE operation: this mutates your DC account data.

  • roomIDstringrequiredRoom ID
rooms_archive_create1 param

POST /rooms/:roomID/archive — Archive a room Archive a room — hides it from the inbox sidebar without unsubscribing. Use `unarchive` to bring it back. **Access:** the caller must be a member/subscriber. Idempotent. ⚠️ WRITE operation: this mutates your DC account data.

  • roomIDstringrequiredRoom ID
rooms_unarchive_create1 param

POST /rooms/:roomID/unarchive — Unarchive a room Unarchive a previously-archived room. Restores it to the inbox sidebar. **Access:** the caller must be a member/subscriber. Idempotent. ⚠️ WRITE operation: this mutates your DC account data.

  • roomIDstringrequiredRoom ID
rooms_pin_create1 param

POST /rooms/:roomID/pin — Pin a room Pin a room to the top of the inbox. For subscription-type rooms the caller is auto-subscribed if not already (mirrors the in-app behavior — you can't pin what you don't follow). **Access:** the caller must already have an interaction history with the room (DMs and group DMs require having received at least one message). Idempotent. ⚠️ WRITE operation: this mutates your DC account data.

  • roomIDstringrequiredRoom ID
rooms_unpin_create1 param

POST /rooms/:roomID/unpin — Unpin a room Unpin a previously-pinned room. Returns it to its normal place in the inbox sort order. **Access:** the caller must be a member/subscriber. Idempotent. ⚠️ WRITE operation: this mutates your DC account data.

  • roomIDstringrequiredRoom ID
search3 params

GET /search — Cross-resource omni-search Cross-resource search across profiles, rooms, messages (incl. private DMs + group DMs you're in), events, and chapters in one round trip. Returns the top-N matches per resource, grouped by resource. Use this when you don't yet know which resource carries the answer — agents typically call this first, then drill into a specific `GET /search/<resource>` for more depth on a single bucket. There's no page param: when you hit the per-resource limit and want more, switch to the per-resource endpoint for that one. The events slice has a baked-in forward-looking default (events ending in the last 30 days or later, and currently enabled) — this matches the in-app "Search across DC" surface. Use `GET /search/events` directly to look further back in time. **Query syntax (`q=`):** plain words match with prefix + typo tolerance. Wrap a phrase in double quotes to require an exact ordered match — e.g. `q="remote work"`. AND/OR/NOT/parentheses are NOT parse

  • qstringrequiredSearch text (1-500 chars). Required.
  • limitnumberPer-resource hits cap (1-25). The same cap applies to each resource — so `limit=5` returns up to 5 profiles + 5 rooms + 5 messages + 5 events + 5 chapters.
  • userIDstringScope each resource to this DCer's content — their profile, messages they authored, rooms they created, events they host, chapters they belong to. The @-mention pattern from the in-app search.
search_profiles3 params

GET /search/profiles — Search profiles Full-text search across DCer profiles — headlines, bios, business descriptions, expertise, hobbies, etc. Returns matching profile records with privacy gates applied (hidden + guest profiles filtered out). For structured/AI-driven matchmaking ("DCers in Lisbon who run SaaS"), prefer `POST /profile-match` — it has a richer ranking pipeline and filters. This endpoint is the plain full-text fallback. **Query syntax (`q=`):** plain words match with prefix + typo tolerance. Wrap a phrase in double quotes to require an exact ordered match — e.g. `q="remote work"`. AND/OR/NOT/parentheses are NOT parsed in `q=` — use the structured filter params below for boolean composition.

  • qstringrequiredSearch text. Required.
  • limitnumberMax hits per page (1-50).
  • pagenumber1-indexed page number.
search_rooms5 params

GET /search/rooms — Search rooms Search rooms by name, description, and topic. Returns rooms that match the query AND that you have access to (subscribed-or-browsable; private rooms / DMs / group DMs you're NOT a member of are filtered out). **Query syntax (`q=`):** plain words match with prefix + typo tolerance. Wrap a phrase in double quotes to require an exact ordered match — e.g. `q="remote work"`. AND/OR/NOT/parentheses are NOT parsed in `q=` — use the structured filter params below for boolean composition.

  • qstringrequiredSearch text. Required.
  • typestringRoom type filter. Allowed: `channel`, `dm`, `group`, `discussion`, `quick-question`, `event`.
  • userIDstringScope to rooms created by this DCer.
  • limitnumberMax hits per page (1-100).
  • pagenumber1-indexed page number.
search_messages5 params

GET /search/messages — Search messages (incl. your private DMs) Search message bodies across every room you can access. **This is the key surface for "catch me up on what was said about X"** — your private DMs, group DMs, and any room you're a member of are all searchable. Messages from rooms you don't belong to are filtered out before any results return. Scope to one room with `?roomID=` (the room is double-gated against your membership — passing a roomID you're not in returns 403, not silently-empty results). Scope to one author with `?userID=`. The two compose: `?roomID=<id>&userID=<id>` returns just messages by that author in that one room. **Query syntax (`q=`):** plain words match with prefix + typo tolerance. Wrap a phrase in double quotes to require an exact ordered match — e.g. `q="remote work"`. AND/OR/NOT/parentheses are NOT parsed in `q=` — use the structured filter params below for boolean composition.

  • qstringrequiredSearch text. Required.
  • roomIDstringScope to a single room. Must be a room you are a member of — otherwise returns 403. Discover roomIDs via `GET /rooms`, `GET /inbox/unread`, or `trip.roomID` on `GET /trips/:tripID`.
  • userIDstringScope to messages authored by this DCer.
  • limitnumberMax hits per page (1-100).
  • pagenumber1-indexed page number.
search_events8 params

GET /search/events — Search events Search enabled DC events by name, description, host, and venue. No default time filter — pass `?since=` or `?until=` (ISO 8601 dates) to constrain. They compose: pass both for an explicit window. **Query syntax (`q=`):** plain words match with prefix + typo tolerance. Wrap a phrase in double quotes to require an exact ordered match — e.g. `q="remote work"`. AND/OR/NOT/parentheses are NOT parsed in `q=` — use the structured filter params below for boolean composition.

  • qstringrequiredSearch text. Required.
  • userIDstringScope to events hosted by this DCer.
  • cityIDstringEvents whose chapter city is this Google Place ID.
  • countrystringISO 3166-1 alpha-2 country code (e.g. `TH`, `MX`).
  • sincestringEvents ending on or after this date (ISO 8601).
  • untilstringEvents starting on or before this date (ISO 8601).
  • limitnumberMax hits per page (1-100).
  • pagenumber1-indexed page number.
search_chapters3 params

GET /search/chapters — Search chapters Search DC chapters by city or country name. **Query syntax (`q=`):** plain words match with prefix + typo tolerance. Wrap a phrase in double quotes to require an exact ordered match — e.g. `q="remote work"`. AND/OR/NOT/parentheses are NOT parsed in `q=` — use the structured filter params below for boolean composition.

  • qstringrequiredSearch text. Required.
  • limitnumberMax hits per page (1-100).
  • pagenumber1-indexed page number.
tickets3 params

GET /tickets — List your tickets Returns your tickets across events, newest first. Defaults to the tickets you're holding (`valid` plus `maybe`) — "what am I attending". Pass `?status=valid`, `?status=maybe`, or `?status=refunded` to narrow to one.

  • statusstringFilter by a single ticket status. With no value, returns the tickets you're holding (`valid` and `maybe`). `refunded` is available on request.
  • limitnumberMax results (1-100).
  • cursorstringCursor from a previous response's `nextCursor`. Pass to fetch the next page.
virtual_events3 params

GET /virtual-events — List Live Calls Returns upcoming Live Calls (online sessions like Connect Calls, Happy Hour, Welcome Call, plus DC BLACK-only calls). Add `?past=true` to include past calls.

  • pastbooleanInclude past Live Calls.
  • limitnumberMax results (1-100).
  • cursorstringCursor from a previous response's `nextCursor`. Pass to fetch the next page.
virtual_event1 param

GET /virtual-events/:sessionID — Get Live Call details Returns the same payload shape as one entry from `GET /virtual-events` for a single online Live Call — `sessionID`, `name`, `description`, `kind` (which audience tier the session is open to), `scheduledAt` / `scheduledEndAt` (ISO 8601), `duration` in minutes, `attendeeCount`, `chatRoomID`, `isLive`, `meetUrl` (the video-call join link, returned regardless of your RSVP state), `myRsvp` (your current `yes`/`no`/`maybe` or `null`), and `status`. DC BLACK callers also see DC BLACK-only sessions; DC tier callers get `tier_restricted` (403) on those.

  • sessionIDstringrequiredThe Live Call session ID. Find IDs via `GET /virtual-events`.
virtual_event_rsvp2 params

POST /virtual-events/:sessionID/rsvp — RSVP to Live Call RSVP to a Live Call. The user is added to the matching attendance list on the session doc (`participantIDs` for `yes`, `maybeIDs` for `maybe`, `notIDs` for `no`) and removed from the others. Three statuses: - `yes` — you intend to attend; you'll show up in `attendeeCount`. - `maybe` — soft attendance signal. - `no` — you're declining. Use this to back out after a prior `yes` or `maybe`. **Note:** the `meetUrl` (join link) on `GET /virtual-events/:sessionID` is **not** gated on your RSVP — it's returned whenever the host has set one, regardless of attendance state. RSVPing is purely an attendance signal. **Idempotent** — re-RSVPing with the same status is a no-op. ⚠️ WRITE operation: this mutates your DC account data.

  • sessionIDstringrequiredThe Live Call session ID. Find IDs via `GET /virtual-events`.
  • statusstringrequiredYour RSVP status for this session.
README.md

DC Official Clients

Official clients for the Dynamite Circle Member API — your own profile, trips, events, virtual events, tickets, invites, inbox, rooms, chapters, places lookup, and the weekly locator digest.

The Python client is a single self-contained file. Zero dependencies (stdlib only). Works as a CLI, a Python library, and a Model Context Protocol server. Compatible with Claude Code, Claude Desktop, Codex CLI, Gemini CLI, Cursor, GitHub Copilot, and every other Agent Skills / MCP-compatible tool.

The TypeScript client is an npm library for trusted server-side TypeScript projects. It is not a CLI and not an MCP server.

py/dc.py       ← Python: CLI + library + MCP server
ts/src/        ← TypeScript: npm library
contracts/     ← pinned OpenAPI contract shared by both clients

About the Dynamite Circle

The Dynamite Circle is the place where global founders find their people — a curated, members-only community of location-independent business owners running profitable companies around the world. Founded in 2011 (it started with twenty listeners on a remote tropical island), the DC has grown into a hand-selected network of ~1,500 active founders who meet at vetted in-person events like DCBKK and DCMEX, swap notes in private rooms, and travel through each other's home cities year-round.

DC is a private community, but it's open to applications from founders running location-independent businesses doing $100k+ in annual revenue. Every application is personally reviewed by a team member within 48 business hours — start an application here if that sounds like you.

Quick Start

Never used Claude Code, Codex, or git? Here's the 5-minute path from zero to "Claude can read my DC profile."

1. Install the basics (one-time)

You need three free things on your computer:

  • Python 3.9+ — the language this client is written in. Download here (Mac/Windows/Linux installers; check "Add Python to PATH" on Windows).
  • Git — the tool that downloads code from GitHub. Download here.
  • An AI assistant — pick one:
    • Claude Coderecommended — this repo is built around it
    • Codex CLI — works too, slightly different commands
    • Claude Desktop — the chat app, gets you the MCP server but no CLI

If anything during install asks "do you want to add to PATH?" — say yes.

2. Get the code

Open a terminal:

  • Mac: Spotlight → "Terminal"
  • Windows: Start → "Terminal" (or "PowerShell")
  • Linux: you know what to do

Then paste:

git clone https://github.com/dynamitecircle/dc.git
cd dc

You now have a folder called dc with all the code in it.

3. Get your DC API key

In your browser: go to https://dc.dynamitecircle.com, log in, click your profile photo (top-right), and choose DC Member API Key. Copy the long string starting with dk_….

4. Tell the client about your key

Back in your terminal (still inside the dc folder):

python3 py/dc.py setup --api-key dk_paste_your_key_here

5. Try it

Open Claude Code and make sure it's pointed at the dc folder you just downloaded. (Claude usually opens to your last project — if it's somewhere else, click the folder icon and pick dc.)

Then ask:

"Show me my DC profile"

Claude runs the right command and shows you back your profile. A few more to try:

"What's the latest in DC announcements?" "What events am I attending?" "Show me the DCMEX schedule and bookmark anything about marketing" "Who else from my chapter is going to DCBKK?"

You're done. The rest of this README explains what's possible in more detail; py/SKILL.md lists every command Claude can run.

If something didn't work

Symptom What to try
python3: command not found Python didn't install or didn't get added to PATH. Re-install and check the "Add to PATH" box on Windows; on Mac, try python instead of python3.
git: command not found Same idea — re-install Git.
Claude says "I don't see a dc skill" Make sure Claude Code is opened to the dc folder, not your home directory or another project. Or just ask Claude: "are you in the dc folder?"
Anything else Run python3 py/dc.py self-test from the dc folder — it tells you exactly which step is broken.

How it's exposed

The same dc.py file is shipped as four integrations — pick whichever fits how your tool talks to it:

Integration What it is Invoke with Dependencies
Agent Skill Auto-discovered via SKILL.md frontmatter (Claude Code, Codex, Gemini CLI, Cursor, Copilot) Just open the repo with the tool — it reads py/SKILL.md and offers the commands stdlib only
CLI Run commands directly from the shell or scripts python3 py/dc.py <command> stdlib only
Python library Import in your own Python code from dc import DC; DC().profile() stdlib only
MCP server Speaks Model Context Protocol over stdio (Claude Desktop, Cursor, Codex MCP, Cline, etc.) python3 py/dc.py --mcp pip install mcp (optional)

The mcp package is lazy-imported — Agent Skill / CLI / Python-library users never need it.

TypeScript npm library

For TypeScript projects, use the package under ts/:

import { DC } from "@dynamitecircle/dc";

const dc = new DC({ apiKey: process.env.DC_API_KEY! });

const profile = await dc.profile.get();
const trips = await dc.trips.list({ limit: 10 });

Keep dk_... API keys server-side. Do not ship a member API key in browser JavaScript.

Don't want to install anything? Use the hosted MCP

The DC Member API is also a hosted MCP server — a remote endpoint you point your AI app at, with nothing to clone, install, or update:

https://api.dynamitecircle.com/mcp        (Streamable HTTP)

Add to Cursor   Install in VS Code

  • Claude Code: claude mcp add --transport http dc https://api.dynamitecircle.com/mcp
  • Claude (web / Desktop / mobile): Settings → Connectors → Add custom connector → paste the URL → Connect
  • VS Code: click the badge above, or code --add-mcp '{"name":"dc","url":"https://api.dynamitecircle.com/mcp"}'
  • Cursor: click the badge above, or add a custom MCP connector pointing at the URL
  • ChatGPT / any other MCP app: add a custom / remote MCP connector pointing at the URL above

When prompted, sign in with your DC account (one-click OAuth) — or send a dk_ key as Authorization: Bearer. The server is always on the current API version, so there's nothing to keep up to date.

Hosted MCP vs. this client — which do I want?

You want… Use
Zero install, always-current, just MCP tools in a chat app Hosted MCP (URL above)
To call DC from your own Python code (from dynamitecircle import DC) This client (library)
A local CLI (dc profile) or shell scripting This client (CLI)
A local stdio MCP server (offline-capable, pin a version, dev against localhost) This client (dc --mcp)

The rest of this README is about this client. For the hosted MCP, the URL above is all you need.

Features

  • Full Member API coverage — read + write across every public endpoint (run python3 py/dc.py help for the live list)
  • Setup command — saves your API key to a chmod-600 .env.dc next to the skill
  • Self-test command — validates env, network, key shape, and a live /profile call end-to-end
  • Cursor pagination — every list-returning command uses the same [--limit N] [--cursor TOKEN] shape and returns the canonical envelope {items, count, cursor, has_more}
  • Three output formats — text (default, pretty JSON), --json, --python
  • MCP-ready — same skill auto-exposes all commands as MCP tools
  • Pre-configured for Claude Code — repo ships an .mcp.json, just cd and claude

CLI quickstart (already comfortable in a terminal?)

If you're skipping past the Quick Start above and just want the CLI flow, here's the condensed version.

1. Get an API key

DC profile dropdown → DC Member API Key (admins/testers only). Keys look like dk_<api-key> and are revocable from the same dropdown.

2. Save the key

python3 py/dc.py setup --api-key dk_<api-key>

This writes py/.env.dc (chmod 600, gitignored).

3. Verify the connection

python3 py/dc.py self-test

Expected output:

{
  "ok": true,
  "userID": "<your-id>",
  "displayName": "<Your Name>",
  "checks": [
    { "step": "env",      "ok": true, "message": "DC_API_KEY loaded from ..." },
    { "step": "keyShape", "ok": true, "message": "Key prefix valid (expected userID: <id>)" },
    { "step": "profile",  "ok": true, "message": "connected as userID[<id>] <Your Name>" }
  ]
}

4. Try a few commands

python3 py/dc.py profile
python3 py/dc.py trips --limit 5
python3 py/dc.py events --past --limit 3
python3 py/dc.py chapters --limit 5
python3 py/dc.py permacode

Run python3 py/dc.py help for the full command list.

Setup per AI tool

Hosted MCP (no install, always current)

Nothing to clone or update — point your tool at the remote endpoint:

# Claude Code
claude mcp add --transport http dc https://api.dynamitecircle.com/mcp

For Claude web / Desktop, Cursor, ChatGPT, and other MCP apps, add a custom / remote connector pointing at https://api.dynamitecircle.com/mcp (Streamable HTTP). Sign in with your DC account (OAuth) or send a dk_ key as a Bearer header. Discovery is published at /.well-known/mcp.json. This is the lowest-effort path; everything below runs the client locally instead.

Claude Code (local client)

.mcp.json is already shipped with this repo. Open the repo with claude:

cd dc
claude

Tools become available as mcp__dc__*. First-time install of the optional MCP dependency:

pip install -r py/requirements.txt

Skill discovery (CLI + import) works automatically via py/SKILL.md.

Auto-updating local MCP via uvx (PyPI)

Prefer a local stdio server that pulls the latest published client on every launch with no clone to maintain? Use uv's uvx and pass your key in the env block:

{
  "mcpServers": {
    "dc": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--refresh", "--from", "dynamitecircle[mcp]", "dc", "--mcp"],
      "env": { "DC_API_KEY": "dk_<api-key>" }
    }
  }
}

Notes: the console script is dc (not dynamitecircle), so --from dynamitecircle[mcp] is required — it both names the package and pulls the optional mcp extra. --refresh is what makes it auto-update; drop it to let uvx cache. The DC_API_KEY in env wins over any .env.dc (an ephemeral uvx install has none).

Claude Desktop

Easiest — one-click .mcpb: download dc.mcpb from the latest GitHub release and double-click it. Claude Desktop installs the dc server and prompts for your DC_API_KEY (no JSON editing). Requires Python 3.9+ with the mcp package available on your machine (pip install 'dynamitecircle[mcp]'). (Or skip local install entirely and use the hosted MCP connector above.)

Manual — edit your config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "dc": {
      "command": "python3",
      "args": ["/absolute/path/to/dc/py/dc.py", "--mcp"]
    }
  }
}

Restart Claude Desktop.

Codex CLI

Edit ~/.codex/config.toml:

[mcp_servers.dc]
command = "python3"
args = ["/absolute/path/to/dc/py/dc.py", "--mcp"]

Codex auto-discovers AGENTS.md (symlinked to CLAUDE.md) and .agents/skills/ (symlinked to .claude/skills/).

Gemini CLI

Reads GEMINI.md (symlinked to CLAUDE.md) for context. For MCP, configure in your Gemini CLI settings:

mcp_servers:
  dc:
    command: python3
    args:
      - /absolute/path/to/dc/py/dc.py
      - --mcp

Cursor

Settings → MCP → Add server, then point at the same dc.py --mcp.

GitHub Copilot

Reads .github/copilot-instructions.md for context. Copilot doesn't have native MCP support yet — use it for in-editor suggestions while developing.

Any other MCP client

Same recipe: command = python3, args = ["/path/to/dc.py", "--mcp"]. The protocol is standard.

Output formats

python3 dc.py profile             # text (pretty JSON for dicts/lists)
python3 dc.py profile --json      # explicit JSON
python3 dc.py profile --python    # Python repr (eval-safe)

Global flags work before or after the command name:

python3 dc.py --json profile
python3 dc.py profile --json

Cursor pagination

All list-returning commands take the same flags:

python3 dc.py trips
python3 dc.py trips --limit 10
python3 dc.py trips --limit 10 --cursor <opaque-token-from-previous-response>
python3 dc.py trips --past --limit 5

Standard envelope:

{
  "items":    [ /* page of records */ ],
  "count":    42,
  "cursor":   "opaque-token-or-null",
  "has_more": true
}

Non-paginated extras (e.g. totalUnread on inbox) are passed through under an extra key.

Use as a Python library

Installed from PyPI (pip install dynamitecircle) — import by the package name:

from dynamitecircle import DC

dc = DC()

Working from a clone instead? Point sys.path at the py/ folder and import as dc:

import sys
sys.path.insert(0, "py")
from dc import DC

dc = DC()

# Reads
profile  = dc.profile()
trips    = dc.trips(past=True, limit=10)
events   = dc.events(past=True, limit=5)
chapters = dc.chapters()
overlaps = dc.overlaps()
locator  = dc.locator(sections="homeCity,favoriteCities")

# Writes
dc.profile_update({"headline": "CEO at Acme"})
dc.trip_create(start_date="2026-12-01", end_date="2026-12-05", place_id="ChIJ...")
dc.event_rsvp("<eventID>", "yes")
dc.invite_create(email="new@friend.com", full_name="New Friend")

Override the API URL (e.g. for a local dev server):

dc = DC(api_url="http://localhost:8080")

API reference

The full live reference for the DC Member API — every endpoint, parameter, and response shape — is at https://www.dynamitecircle.com/developers/. The page is regenerated on every deploy, so it's always current.

Staying up to date

The DC Member API ships new endpoints and refinements regularly. This skill is the official client and we update it whenever the API changes. Plan for updates — the skill will warn you on stderr the first time a request returns an X-API-Version newer than DC_API_VERSION, and major-version bumps may break older clients.

The no-maintenance option: if you use the hosted MCP (https://api.dynamitecircle.com/mcp), there's nothing to update — the server always runs the current API version. The strategies below apply only to the local client.

Pick whichever integration style fits your project. From simplest to most isolated:

0. PyPI — pip / uvx

pip install dynamitecircle              # CLI + library
pip install 'dynamitecircle[mcp]'       # + local MCP server (dc --mcp)

Then dc setup --api-key dk_<api-key> and dc self-test. Update with pip install --upgrade dynamitecircle. For a local MCP that auto-updates on every launch, use the uvx config above.

Best for: the quickest local install, and the auto-updating uvx MCP setup.

1. Plain git clone — quick local use

git clone https://github.com/dynamitecircle/dc.git
cd dc
python3 py/dc.py setup --api-key dk_<api-key>

To update: cd dc && git pull. Run self-test afterwards.

Best for: trying things out, scripts you run by hand, no other repo involved.

2. Git submodule — pinned to a specific commit

If you have your own project repo and want the dc repo versioned alongside it:

cd your-project
git submodule add https://github.com/dynamitecircle/dc.git vendor/dc
git commit -m "Add dc client as submodule"

To update later:

cd vendor/dc
git pull origin main
cd ../..
git add vendor/dc
git commit -m "Bump dc client"

Then in your code:

import sys
sys.path.insert(0, "vendor/dc/py")
from dc import DC

Best for: production-ish code where you want explicit, reviewable bumps.

3. Git subtree — same updates, no submodule indirection

cd your-project
git subtree add --prefix vendor/dc \
  https://github.com/dynamitecircle/dc.git main --squash

Update with:

git subtree pull --prefix vendor/dc \
  https://github.com/dynamitecircle/dc.git main --squash

Best for: teammates who don't know submodules — files just appear in your repo.

4. Symlink — share one clone across many projects

If you keep all your projects in ~/code/:

git clone https://github.com/dynamitecircle/dc.git ~/code/dc

# In each project that uses it:
cd ~/code/your-project
ln -s ../dc vendor/dc

Now cd ~/code/dc && git pull updates every consumer at once. Project-level .mcp.json / .codex/config.toml entries can use vendor/dc/py/dc.py and they'll resolve through the symlink.

Best for: power users with multiple personal projects and one machine.

5. Pip-installable Git ref — one-shot for a virtualenv

The skill is one file with no setup.py, but you can install the package the MCP server needs and check the file out as a sibling:

pip install mcp
git clone https://github.com/dynamitecircle/dc.git

Best for: CI environments, ephemeral containers, scripted setups.

Update etiquette

  • Stay current. The DC Member API ships new endpoints regularly and the client mirrors them; running stale means missing features and (eventually) compatibility warnings on stderr.
  • Run self-test after every update. Five seconds, catches breakage.
  • Watch stderr the first time you call any command after updating. The version-mismatch warning prints once per process when the API is on a newer minor/major.
  • Major version bumps may be backwards-incompatible. Read the release notes on the GitHub repo before pulling across a major boundary.

Rate limits

Tier Per minute Per day
DC Community 10 300
DC BLACK 60 3,000

Headers on every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Daily-Remaining.

Platform support

Tested on macOS, Linux, and Windows 10/11. Python 3.9+ required (uses pathlib, Path.replace, inspect.signature, contextvars, urllib).

Windows notes

  • The skill auto-reconfigures stdout and stderr to UTF-8 at startup, so emoji and em-dashes render correctly even on legacy cmd.exe (which defaults to cp1252). If you still see mojibake on a very old terminal, set PYTHONIOENCODING=utf-8 once: setx PYTHONIOENCODING utf-8 then restart your shell.
  • setup writes .env.dc and tries to chmod 600 it. On Windows this is a no-op — the file inherits NTFS perms from its parent. The skill emits a one-time note about this when you run setup. Make sure your repo isn't on a shared drive.
  • Use python or python3.exe to invoke; the #!/usr/bin/env python3 shebang is ignored on Windows.

Project layout

dc/
├── README.md                          # this file
├── CLAUDE.md                          # AI-tool guide (also linked as AGENTS.md, GEMINI.md)
├── AGENTS.md       → CLAUDE.md        # symlink (Codex)
├── GEMINI.md       → CLAUDE.md        # symlink (Gemini)
├── LICENSE                            # MIT
├── manifest.json                      # MCPB manifest (MCP 2025-11 spec)
├── .mcp.json                          # auto-registers `dc` MCP server in Claude Code
├── .codex/
│   └── config.toml                    # auto-registers `dc` for Codex CLI
├── .github/
│   └── copilot-instructions.md        # GitHub Copilot
│
├── py/                                # ← Python client (canonical)
│   ├── SKILL.md                       # Agent Skills frontmatter + usage
│   ├── config.json                    # name, version, env requirements
│   ├── dc.py                          # CLI + Python import + --mcp server
│   ├── requirements.txt               # optional MCP dep — skip for CLI/import
│   ├── .env.dc.example                # template
│   └── .env.dc                        # gitignored (created by `setup`)
│
├── ts/                                # ← TypeScript npm library (@dynamitecircle/dc)
│   ├── src/                           # hand-written SDK surface
│   ├── tests/                         # contract + request behavior tests
│   ├── examples/                      # TypeScript usage examples
│   ├── package.json
│   └── tsconfig.json
│
├── contracts/                         # pinned API contract shared by clients
│   ├── openapi.json                   # committed snapshot of /openapi.json
│   └── operation-map.json             # OpenAPI op → Python command → TS method
│
├── DC/
│   └── SKILL.md     → ../py/SKILL.md  # human-friendly skill path (symlink)
│
├── docs/                              # ← REAL design docs (canonical)
│   ├── skill-info.md                # design rules / architecture
│   └── mcp-info.md                    # MCP setup for every supported client
│
├── .claude/                           # Agent Skills discovery (Claude Code)
│   ├── skills/dc  → ../../py          # symlink to canonical Python client
│   └── docs       → ../docs           # symlink to canonical docs
│
├── .agents/                           # Agent Skills discovery (Codex CLI + Gemini CLI alias)
│   ├── skills/dc  → ../../py          # symlink to canonical Python client
│   └── docs       → ../docs           # symlink to canonical docs
│
├── .gemini/                           # Gemini CLI MCP config
│   └── settings.json                  # auto-approves dc MCP tools (trust: true)
│
├── .gitignore
└── .gitattributes

About the layout

This is a monorepo. The Python client lives at /py/; the TypeScript client lives at /ts/. Both wrap the same DC Member API and are validated against the pinned contract in /contracts/. /docs/ is shared. The dotfile-prefixed directories (.claude/, .agents/, .gemini/) exist because AI tools auto-discover skills from those specific paths — they're kept hidden but each one symlinks (or points) straight to the canonical folder, so you only edit files in one place. Edit py/dc.py and Claude Code, Codex, and Gemini CLI all see the same file via their respective discovery directories. Gemini CLI also reads .agents/skills/ as an alias, so we don't need a redundant .gemini/skills/ symlink.

If you're adding Python code or skill docs, edit py/ (or docs/) directly. If you're adding TypeScript library code, edit ts/. The discovery folders take care of themselves.

Pre-approval out of the box

.claude/settings.json, .codex/config.toml, and .gemini/settings.json all auto-approve the dc MCP server's tools so users don't get a per-call approval prompt when they open this repo with their AI tool. Anyone uncomfortable with that can override with their personal .claude/settings.local.json, ~/.codex/config.toml, or ~/.gemini/settings.json. Every dc write tool is scoped to the caller's own DC account via their personal API key — pre-approval doesn't widen any blast radius, just removes per-call friction.

Maintenance

This repo is maintained by the Dynamite Circle team. It's read-only for the public — clone it and use it, but don't open PRs. If you spot a bug or want a new feature, contact us through the official DC channels.

License

MIT — see the LICENSE file for the full text.

Recommended MCP Servers

FAQ

What does DC Official Clients do?

Official clients for the [Dynamite Circle Member API](https://www.

When should I use DC Official Clients?

Official clients for the [Dynamite Circle Member API](https://www.dynamitecircle.com/developers/) - your own profile, trips, events, virtual events, tickets, invites, inbox, rooms, chapters, places lo

Is DC Official Clients safe to install?

Review the Security Audits panel on this page before installing in production.

Developer Toolsintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.