search + fetch are the
ChatGPT-standard discovery pair (all ChatGPT needs); the rest are helpers for
richer agent flows. Read-only tools never change state; write/billable tools are
annotated so hosts can prompt before invoking.
Tools at a glance
Index
index_org
Add one or more organizations’ calendars so their events become available to
your account.
- Input:
website(string — a single org website/domain) orwebsites(array of up to 500 — batch);startDate(string, optional,YYYY-MM-DD, defaults to today),endDate(string, optional,YYYY-MM-DD, defaults to +90 days). - Returns (single): either
status: "indexing"with ajobId(pollorg_status), orstatus: "ready"when a current, non-empty index already exists. A site that can’t be reached returns afound: falsenon-starter result (not an error). A completed crawl that found no events reportsindexStatus: "no_events_found"and is not treated as fresh — the nextindex_orgre-crawls it. Array input returns a batch; each item is billed and gated independently. - Cost: 40 credits for a fresh index; 10-credit refresh within 30 days of a successful, non-empty index; failed crawls are refunded.
- Auth: oauth2. Annotations:
title: "Add a Venue's Calendar", write / destructive / open-world.
org_status
Poll an index job started by index_org.
- Input:
jobId(string, required). - Returns:
status∈pending | indexing | ready | failed | expired, withprogress(0–100) andetaSecondswhile running, andorgId+eventCountwhen ready. When a crawl completed with zero events,indexStatus: "no_events_found"plus a note is included. - Auth: noauth or oauth2. Annotations:
title: "Check Calendar Progress", read-only.
report_issue
Report a problem with Momentra data or a crawl — missing events, a wrong
venue/address, an organization failing to parse — straight to the Momentra team.
Momentra automatically attaches diagnostics (the resolved org, its indexed event
count and address, the scraper scriptVersion, a sample of events, and any
related job status) so the issue can be triaged without a follow-up.
- Input:
message(string, required);domain(string, optional);orgId(string, optional);jobId(string, optional);email(string, optional — auto-filled when linked). - Returns:
{ status: "received", reportId, delivered, message }. The report is always recorded;deliveredindicates whether the notification email was sent. - Auth: noauth or oauth2. Annotations:
title: "Report an Issue", write / non-destructive / open-world.
recover_account
Recover a previous account’s purchased credits after reconnecting with a new
login. Takes no arguments — it returns a recoveryUrl to the Momentra
recovery page. There you enter the email tied to the prior account; a
confirmation link is emailed to that address. Opening the emailed link rebinds
your current connection onto the recovered account (keeping its credit balance,
Stripe customer link, and history) and consolidates duplicate accounts under
that email.
- Input: none.
- Returns:
{ status, message, recoveryUrl }wherestatus∈start | error. - Safety: same-email gated; link is single-use, 15-minute TTL, and rate-limited per email; a GET only previews — only the explicit confirm binds.
- Auth: oauth2 (must be a linked connection). Annotations:
title: "Recover Account", write / non-destructive.
Discover (over your indexed scope)
search
Search events across the organizations available to your account. Follows the
OpenAI search result contract.
- Input:
query(string) — free text over organizations and events. - Returns:
{ results: [{ id, title, url, ... }] }. Resultids are opaque:org:<orgId>orevent:<orgId>:<eventId>, for use withfetch. - Auth: noauth or oauth2. Annotations:
title: "Search Events", read-only.
search response shape (grouped by org)
search response shape (grouped by org)
search returns each matching org as a result stub ({id,title,url} — what the
ChatGPT connector reads) with its matching events nested under events:id/title/url; grouping-aware agents can
use events[]. Matching is token-based, so "ethan allen homestead events" or
a pasted domain/URL resolves the same org.fetch
Return the full document(s) for id(s) returned by search. Follows the OpenAI
fetch result contract.
- Input:
id(string — anorg:…orevent:…id) orids(array of up to 500 — batch). - Returns (single):
{ id, title, text, url, metadata }. For an org id,metadata.organizationcarries the full organization record; for an event id,textis the full event JSON. Array input returns a batch. - Cost: 1 credit per id. Auth: oauth2. Annotations:
title: "Open an Event or Venue", billable.
search_businesses
Find organizations available to your account by name or domain.
- Input:
query(string, required) — name or domain. - Returns:
{ count, query, businesses: [ <organization record> ] }, each with an upcomingeventCount. - Auth: noauth or oauth2. Annotations:
title: "Find Venues and Organizations", read-only.
search_business_events
List one or more organizations’ upcoming events.
- Input:
orgId(string, optional —org:prefix tolerated) ordomain(string, optional); one is required. For batch, useorgIdsordomains(arrays of up to 500). - Returns (single):
{ organization: <record>, eventCount, events: [ <event> ] }. Array input returns a batch. - Auth: noauth or oauth2. Annotations:
title: "List a Venue's Events", read-only.
list_orgs
List every organization currently in your scope — the orgs assigned to your
account. No query needed.
- Input:
limit(number, optional — capped at 500; defaults to all in your scope). - Returns:
{ count, total, organizations: [ <organization record> ] }, each with an upcomingeventCount. Unauthenticated returns{ count: 0, organizations: [] }. - Auth: noauth or oauth2. Annotations:
title: "List My Organizations", read-only.
Identity
get_profile
Return the profile for the connected credentials — a stable, opaque account
identifier (used by multi-account hosts to label connections).
- Input: none.
- Returns:
{ id, email?, nickname? }in bothstructuredContentand a JSON text block. Theidis stable across token refresh and reconnection and encodes no personal data. - Auth: oauth2. Annotations:
title: "View Connected Account", read-only.
Brief
The brief is your account’s editorial policy — the include/exclude document that drives matching. One brief per account. See Brief shape.get_brief
Read your account’s editorial brief.
- Input: none.
- Returns:
{ status, briefId, briefStatus, clientName?, version, updatedAt, brief }, or{ status: "no_brief" }when none exists yet. - Auth: oauth2. Annotations:
title: "Get Editorial Brief", read-only.
update_brief
Create or update your account’s editorial brief.
- Input:
brief(object, optional — the full policy document; replaces the stored one),status(draft | active, optional — only anactivebrief drives matching),clientName(string, optional — a label). - Returns: the saved brief metadata
{ status: "ok", briefId, briefStatus, clientName?, version, updatedAt }. - Auth: oauth2. Annotations:
title: "Update Editorial Brief", write (not destructive; reversible by editing again).
Matching (brief-driven discovery)
matching_events
Find events that match your active brief — the events Momentra discovers FOR
you.
- Input:
limit(number, optional, 1–100, default 25). - How: embeds your brief as the query, ranks the indexed events by similarity, applies your standards facet filters + freshness window + exclude rules, and honors your accept/reject curation. Scoped to organizations you’re entitled to.
- Returns:
{ status: "ok", briefId, count, matches: [{ id, score, title, url, orgId, startEpoch, facets }] }. Requires an active brief (elseno_active_brief). - Auth: oauth2. Annotations:
title: "Find Matching Events", read-only.
matching_orgs
Find organizations that match your active brief — the same brief-driven ranking
over the organization index.
- Input:
limit(number, optional, 1–100, default 25). - Returns:
{ status: "ok", briefId, count, matches: [{ id, orgId, score, name, domain, categories?, inclusivity? }] }. Requires an active brief. - Auth: oauth2. Annotations:
title: "Find Matching Organizations", read-only.
Curation (overrides that feed matching)
Accept/reject decisions are per-account overrides.reject drops an item from
future matching regardless of similarity; accept pins it in even if similarity
is low.
accept_event / reject_event
- Input:
id— a single event id (event:<orgId>:<eventId>) or an array (batch). - Returns:
{ status: "ok", decision, kind: "event", count, ids }. - Auth: oauth2. Annotations:
title: "Accept Event"/"Reject Event", write (not destructive).
accept_org / reject_org
- Input:
id— a single org id (org:<orgId>) or an array (batch). - Returns:
{ status: "ok", decision, kind: "org", count, ids }. - Auth: oauth2. Annotations:
title: "Accept Organization"/"Reject Organization", write (not destructive).
Evaluation (certify a single item)
evaluate_event / evaluate_org
Evaluate whether item(s) fit your active brief — applies your exclude rules +
facet gate, then similarity to the brief.
- Input:
id— a single id or an array (batch). - Returns: per item
{ status, id, verdict, similarity?, rulesPass, facetPass, reasons[] }whereverdict∈fit | weak | reject(reject= a hard rule/facet failure;weak= passes rules/facets but low similarity;fit= passes all). Requires an active brief. - Auth: oauth2. Annotations:
title: "Evaluate Event Fit"/"Evaluate Organization Fit", read-only.
Seed (learn a brief from an aggregator)
seed_brief
Learn an editorial brief automatically from a trusted aggregator org.
- Input:
orgId(string, optional — an indexed aggregator) orwebsite(string, optional — resolved to an orgId). One is required. - Returns:
{ status: "seeding", jobId, orgId, offDomainPct, totalEvents }on success, or{ status: "not_aggregator", orgId, offDomainPct, totalEvents }when the org’s events don’t mostly link off-domain (>25% required). On success a background job converges a brief and sets it active. - Auth: oauth2. Annotations:
title: "Seed Brief from Aggregator", write (not destructive).
seed_status
Poll a seed_brief job.
- Input:
jobId(string, required). - Returns:
{ status, jobId, orgId, iteration, maxIterations, fitPct, residualCount, totalEvents, briefId?, message }wherestatus∈seeding | reviewing | ready | failed | not_aggregator.fitPctis the percent of the aggregator’s events the current brief admits;briefIdis set when ready. - Auth: oauth2. Annotations:
title: "Seed Brief Status", read-only.
seed_review
Pull the next batch of borderline events to review while (or after) a
seed_brief job runs — events near your brief but not clearly on it. Safe to
call repeatedly; already-decided items are excluded and it re-ranks against the
latest brief.
- Input:
jobId(string, required),limit(number, optional, 1–50, default 25). - Returns:
{ status, jobId, seedState, count, candidates: [{ id, title, orgId, domain, score, reason }] }. - Auth: oauth2. Annotations:
title: "Seed Brief Review Queue", read-only.
seed_reject
Submit the events you reject as off-brief during a seed_brief review.
- Input:
jobId(string, required),ids(array of event ids, required). - Returns:
{ status: "ok", jobId, rejectedCount, curationWritten, proposedPatch, rationale[], questions[], droppedForGuard[] }. The rejections are recorded as durable negatives and analyzed into a proposed brief tightening (proposedPatch) with reasoning and clarifying questions. Apply the parts you agree with viaupdate_brief. The patch is guarded so it never blocks the aggregator’s own events. - Auth: oauth2. Annotations:
title: "Seed Brief Reject", write (not destructive).
