add_tag_to_meeting
ChatGPTApply a tag to a meeting. Tags are org-level and apply at the physical-meeting (recorded event) level, so all participants' views of the same meeting share the same tags. Specify the target by meetingId. Specify the tag by tagId (obtain from list_meeting_tags). Deduplicates: if the tag is already applied, no error is returned.
analyze_firm_context
ChatGPTAnalyze how a topic or discussion relates to the firm's services and existing client agreements, cross-referenced with actual meeting and email data for the client. Use this when: - User asks "Is this in scope for [client]?" - User asks "Are we being asked to do something outside our agreement?" - User asks "What services might apply to this situation?" - User asks "What service needs does [client] have?" - User asks "Identify opportunities for [client]" - You detect a potential scope creep or upsell opportunity in a conversation This tool returns services, agreements, AND relevant meeting/email context to help you: 1. Identify if the topic matches existing service offerings 2. Check if it's within scope of a client's current agreement 3. Suggest upsell opportunities grounded in actual client discussions 4. Reference specific meetings/emails where needs were discussed Provide a description of the topic/discussion and optionally a client name.
check_email_connection
ChatGPTCheck if the user has a connected email account (Gmail/Outlook). Do not call this preemptively — just attempt search and handle connection errors.
client_email_search
ChatGPTClient Email Search: meaning-based search over a client's email history across EVERY connected mailbox in the firm, not just yours. Scope is the client's current contacts; each physical email appears once with who (from, to, cc, whose mailbox), what (subject), when (sentAtLocal, already in the user's timezone) and a url that opens the message in Ping; content is the cleaned full message. Use for conceptual questions ("what did they decide about the restructuring"), for "latest / most recent on X" (set orderBy=recent), for date windows (since/until), and whenever the answer may sit in a teammate's inbox. Use search_emails (with clientId) instead for exact identifiers or subjects in your own mailbox. Requires a client selected via @mention. Results are Ping rows, not provider messages: never pass pingEmailId to get_email_detail.
combined_search
ChatGPTEmail & Meeting Search — searches both meeting transcripts AND email in parallel. Use when the user wants to search across both sources, or doesn't specify a particular source. Do NOT use when the user explicitly asks to search only email or only meetings — use the source-specific tools instead. - You already have meeting context in the conversation (answer directly) This tool runs meeting and email search IN PARALLEL for speed. Pass clientId/contactId/personName/personEmail from resolve_person when a person was resolved.
export
ChatGPTExport ALL of the user's meetings from Ping — their accounting-firm assistant that captures client interactions from meetings and emails. Builds a zip with one folder per meeting (meeting.md + transcript.txt) plus an index.json, and returns a short-lived URL to download it. Building it reads the whole corpus and can take a few minutes; a built export is then reused for ~2h. Calling it again while a build is running joins that build rather than starting another.
fetch_email_preferences
ChatGPTGet the user's email drafting preferences (tone, length, custom instructions) and meeting participants. Required before drafting emails.
filtered_meeting_search
ChatGPTSemantic search with metadata filters. Combines vector similarity with precise filtering. Use when you need to narrow search by: - Date range - Specific speaker - Specific meeting ID
format_timestamp_links
ChatGPTConvert timestamp references into clickable links for meeting recordings. Handles multiple meetings.
get_client_details
ChatGPTGet client details including contacts, meeting history, and the client summary. Search by name (partial match) or client ID. clientSummary.text holds the summary with a markdown link to the source at each citation. Keep those links when quoting the summary. A citation without a link is an edit or a source the user can't open. clientSummary.sources lists each cited source once with the url its inline link uses and the IDs other tools take: - meeting: meetingId for get_meeting_transcript, and startSeconds with meetingId for format_timestamp_links. - email: mailboxMessageId for get_email_detail. Null when the email sits in a teammate's mailbox. - footprint, edit, restricted: no ID to pass. clientSummary is null when the client has no summary or the user can't access it.
get_email_detail
ChatGPTFetch the full body of a specific email by ID (from a previous search result). Returns sanitized plain text content. The ID must be the provider message ID that search_emails returns. combined_search doesn't return email IDs. If you only have a subject line, run search_emails first.
get_meeting_transcript
ChatGPTFetch the full raw transcript of one meeting by exact meeting ID or by title. Prefer the meeting ID from a search_meetings or list_meetings result. A title lookup returns the most recent meeting whose title contains the text, which can be the wrong meeting when several share a name. For questions about what was discussed across meetings, use search_meetings instead.
get_org_agreements
ChatGPTGet the list of client agreements/engagements. Use this when: - User asks "What agreements do we have with [client]?" - User asks about active engagements - You need to check scope of work for a specific client - You need to detect if a discussion is outside the agreed scope Can filter by: - clientName: Filter to a specific client's agreements - stage: 'proposed', 'active', or 'inactive' Returns agreement name, client link, stage, contact info, and effective date.
get_org_services
ChatGPTGet the list of services/service templates that this firm offers. Use this when: - User asks "What services do we offer?" - User asks about pricing or service details - You need to understand what the firm can provide to recommend upsells - You need to check if a discussed topic aligns with existing services Returns service name, description, billing type, and pricing info.
get_ping_help
ChatGPTFetch help articles by exact title or keyword search. Call list_help_articles first to get titles. Answer only from the content this tool returns.
get_recent_slack_messages
ChatGPTRetrieve recent Slack messages from channels linked to a client, grouped by thread. Use when the user asks about recent client activity, team discussions, what was said in a channel, or 'what's going on with X'. Returns messages from the last 30 days by default. Includes internal team chatter (firm-side commentary) flagged with authorRole='internal' — treat it as the firm discussing the client, not the client themselves. Standalone messages (no thread) are returned as single-message threads with threadTs=null so the response shape is consistent.
get_slack_thread
ChatGPTRetrieve all messages in a specific Slack thread by threadTs. Use when you have a threadTs from a previous get_recent_slack_messages call and need the full thread context (e.g., to summarize a conversation, find an answer to a specific question). Returns messages in chronological order. Author roles are flagged ('internal' = firm staff, 'contact' = client-side participant, 'unknown' = unresolved sender).
get_support_contact
ChatGPTGet Ping support contact information (email, bug reports, billing).
list_action_items
ChatGPTList action items the user can see, newest first, with an optional status filter (pending, completed, overdue, etc.). Read-only. Use update_action_item to change an item. Scope: - meetingId: items from that meeting only. Each meeting row belongs to one physical meeting, and the result includes items from every attendee's row. When set, meetingId replaces any pinned meetings or pinned client. - clientId: items from meetings with that client. Pass resolve_person.searchContext.clientId or the selected client. - Neither: the pinned meetings or the single pinned client, if any are in context, or else every meeting the user can see. Paging: results return limit items per call. When hasMore is true, call again with offset set to nextOffset. Each item carries meetingId, recordedEventId, and effectiveMeetingId. Use effectiveMeetingId to open the source meeting.
list_client_meetings
ChatGPTList all meetings for this client that you can actually search (have embeddings indexed). Use this FIRST when a user asks: - "Can you see meeting X?" - "Do you have access to [meeting title]?" - "Which meetings do you have?" - "What meetings are available?" This returns a list of meeting titles and dates - NOT the content. For content, use search_meetings with a clientId after confirming the meeting exists.
list_help_articles
ChatGPTList all available Help Center articles with titles, categories, and previews. Call this first to find relevant articles, then use get_ping_help to fetch full content.
list_meeting_tags
ChatGPTList the organization's custom (non-system) tags available for meetings. Returns tag id, name, and color for each. Use this before calling add_tag_to_meeting to discover available tag IDs.
list_meetings
ChatGPTList meetings with titles, dates, and metadata. Use timeframe="upcoming" for next/upcoming scheduled meetings; those may not be searchable yet because future meetings do not have transcripts. Does not return transcript content — use search_meetings to search completed meeting content.
reference_timestamps
ChatGPTConvert meeting timestamp references to numerical seconds and filter invalid entries before responding to the user.
resolve_person
ChatGPTIdentify which person the user means by fuzzy-matching name or email against contacts and clients. Call before searching meetings, emails, or client data when a person is mentioned by name. For questions about one known meeting, read it with get_meeting_transcript first and resolve speaker names from its transcript, title, and participants. If several people match, returns the candidates for the user to choose from.
search_client_meetings
ChatGPTSemantic search scoped to a specific client's meetings only. Automatically filters to meetings involving the client's contacts. Client ID is provided from context.
search_contacts
ChatGPTSearch contacts by name or email address. Returns contact details and associated client.
search_emails
ChatGPTEmail Search: search the user's own connected mailbox (Gmail/Outlook) by keyword query. Automatically expands queries with synonyms for better recall. Returns subject, sender, date, and snippet.
search_meetings
ChatGPTSemantic search across meeting transcripts. Pass the user's question in 'userQuery' for best results — the system automatically generates optimized search queries. Pass clientId or contactId to scope to that entity's accessible recorded events. Returns matching excerpts with speaker names, dates, and timestamps.
search_recent_meetings
ChatGPTSearch meetings from the past 7 days only. A shortcut for recent/latest queries — use filtered_meeting_search for custom time ranges.
search_service_alignment
ChatGPTSearches meetings for service alignment by using actual firm service names to find discussed needs. USE WHEN: User asks which services to recommend based on meeting discussions: - "Which of our services should we propose to @Client?" - "What services align with what @Client needs?" - "Based on the meeting, what should we recommend?" - "What are their pain points related to our services?" WHY THIS EXISTS: Standard search fails on "which services align with their needs" because generic queries don't match how people talk. This tool uses actual service names to search. DO NOT USE FOR: - Simple service catalog questions -> use get_org_services / analyze_firm_context - General meeting search -> use search_meetings
update_action_item
ChatGPTUpdate an existing action item. Provide only the fields to change: - status — "mark that as done/complete", "set it to in progress", "waiting on client", "cancel that task" - title / description — "rename it", "add ABC123 to it", "update the description to say ..." - dueDate — "push it to Friday", "make it due July 30" Updates one item per call. Never invent field values the user did not ask for.