Planning and answers
plannergoogle/gemini-3.5-flash
Understanding each request, choosing and batching tools, and writing the final grounded response.
The AI assistant who is always rooting for founders.
Root is a conversational AI assistant built into the Foundations community. He lives in Slack and email — and your own AI agents can reach him too, through a member REST API and MCP server. He talks in first person, uses your name, and keeps things friendly. Root is not just another app. He works where you work and you just tell him what you need and he takes action: booking office hours, updating your profile, synthesizing the collective knowledge of the community, finding the right person in the network, managing your membership, answering questions about how Foundations works, or catching you up on current events when freshness matters. He remembers your preferences across conversations, handles multiple requests in a single message, and if something goes wrong he tells you what happened and what to try next.
Straight from the system prompt.
Under the hood of every conversation.
Root uses different models for different kinds of work. This list comes from the live deployment configuration, so it stays current as the model stack changes.
google/gemini-3.5-flash
Understanding each request, choosing and batching tools, and writing the final grounded response.
google/gemini-3.8-flash
Classification, extraction, parsing, fuzzy matching, and other high-volume structured decisions.
google/gemini-3.8-flash
Reranking directory results and synthesizing answers from knowledge, Slack, and other retrieved content.
openai/gpt-5.6-sol
Emails, bios, descriptions, reply drafts, and other prose where voice and polish matter.
anthropic/claude-opus-5
Offline judgment-heavy work such as application analysis and longer-form community analysis.
google/gemini-3.8-flash
Understanding shared images and screenshots, camera scenes, and visual comparisons.
google/gemini-3.1-flash-image-preview
Creating artwork for Foundations calendar and community events.
perplexity/sonar-pro-search
Research and enrichment that needs current information from the open web.
Root is conversation-first in Slack and email. Ask naturally, and when a workflow is better on the web, Root can send you a secure private /root link for the right page.
Anonymized conversations showing the range of things people ask Root to help with.
Can I sign up for Member Demo Showcase this coming Friday?

Yes, you can apply to present at the Member Demo Showcase this coming Friday, February 27th.
To sign up, you need to fill out the application form here: Member Demo Application.
Event Details
• Date: Friday, Feb 27, 2026
• Time: 12:00 PM - 1:30 PM
• Format: Four members will each deliver a 15-minute demonstration of their current projects.
• Perks: 🍕 will be provided!
Please note that this is a Foundations Members Only event. If you want richer event browsing or to request a new event, I can send a secure /root/calendar link.
Keep me posted on the next time that Jane Smith has office hours.

I can do that.
I'll check every day at 9am and only DM you when Jane Smith has office hours coming up, with the dates and times.
If there aren't any office hours, I'll stay quiet and check again on the next run.
Who should I talk to about soc2 compliance?

Getting SOC2 compliant is a big milestone, John! 🛡️ Based on recommendations from the Foundations community, here are the best people and tools to talk to:
Service Providers & Tools
• Strike Graph: Highly recommended for SOC2 compliance. (shared by John Doe - read more)
• Sprinto: Recommended for achieving SOC2 Type 1 quickly. (shared by John Doe - read more)
• Moss Adams: Used by members as an auditor for those who prefer a direct approach without automated software like Vanta or Drata. (shared by John Doe - read more)
• Vanta/Drata: Popular automation platforms, though some members noted they still require significant manual documentation. (shared by John Doe - read more)
Community Strategy Tips
• Focus on the Customer: Members suggest that SOC2 is often about satisfying customer process requirements. Talk to your prospective clients first to see which specific controls they require. (shared by John Doe - read more)
• Type 1 vs. Type 2: You can usually get a Type 1 in a few weeks to satisfy immediate needs, while a Type 2 takes 6–12 months of data collection. (shared by John Doe - read more)
• Cost Expectations: Members have reported paying around $10k for a Type 1 audit and up to $19k for bundled Type 2 and ISO 42001 compliance. (shared by John Doe - read more)
If you want broader browsing or exports, I can also send a secure /root/providers link. 🚀
What members should I talk to about selling to SMBs?

Hi John! Selling to SMBs is such a specific beast—it's all about high velocity and finding that perfect balance between CAC and LTV. 📈
I searched the community and found some incredible members you should definitely chat with. Here are a few standouts:
• Nalin Vahil: He’s currently the CRO at Address Guard, but more importantly, he has a background scaling sales at Asana and Zapier. Those are the gold standards for "bottom-up" SMB adoption models!
• Aaron Bird: As the founder of Bizible and Inflection.io, Aaron is a pro at cost-effective distribution and product-led growth (PLG), which is usually the secret sauce for SMB success.
• Manoj Pinna: His company, Pebble Health, sells benefits specifically to small businesses, so he’s deep in the trenches of that exact sales motion right now.
• Jonathan Tice: He’s a fractional CRO who specializes in helping founders move from founder-led sales to a repeatable SMB/Mid-market engine.
If you want to browse more people or export results, I can also send a secure /root/members link.
Are you looking for advice on a specific part of the funnel, like lead gen or self-service onboarding? I'm rooting for you! 🚀
Does Charles still have open office hours this week?

Hi Dan! 👋 Yes, Charles Fitzgerald still has open office hours this week!
Here are his available slots:
Charles Fitzgerald
Charles led MSFTs Platform Strategy for decades. Seriously. He has forgotten more than you'll ever know about building platforms and scaling infrastructure. He also hates IBM.
Tuesday, January 27:
✅ 2:00 PM - Available (30 min)
✅ 2:30 PM - Available (30 min)
To book a slot, just let me know which time you'd like! 😊
Remember for everyone: the Glowforge is in the third-floor south kitchen, and people should contact Matt or Rebekah to get access.

Saved — that is now durable, member-attributed community knowledge I can retrieve when someone asks about the Glowforge later.
What’s going on in the main room?

It looks like a lively social gathering or networking event is in full swing in the main room right now, John! 🍕👯♂️
Based on the live feeds, here’s what’s happening:
• Activity: There are about 45–50 people in the space, mostly standing and chatting in small groups. It seems like a very informal, social atmosphere.
• Food: There's a long table in the center with several open pizza boxes, and people are lining up to grab a slice.
• Presentations: I don't see any active speakers or presentations happening at the moment—just lots of networking!
I'm sharing the views from the Main Room (Front) and Main Room (Back) cameras so you can see the action for yourself! 📸🏢
This catalog is generated from Root's live tool surface — the platform's built-in capabilities plus everything Foundations connects through its integration — so it always reflects exactly what Root can do right now. Click a category to expand it.
cancel_action_alert
Cancel an event-driven action alert so it stops firing. Members can cancel their own alerts; admins can cancel any. Use list_action_alerts first if the user doesn't provide a specific alert_id.
The ID of the action alert to cancel
create_action_alert
Create an event-driven alert that fires the MOMENT a matching action happens through the agent, instead of polling on a schedule. Use this when a user asks to be notified 'when/whenever X happens' and X is something the agent itself performs — e.g. someone scheduling office hours or booking a room. The agent watches the specified tools across ALL conversations (Slack and email); when one runs successfully, an LLM checks whether the alert's condition is satisfied and sends an immediate Slack DM. Prefer this over create_follow_up for 'alert me when...' requests — a follow-up polls on a schedule and can miss or delay the event. watch_tool_names must be exact tool names from your own tool list (e.g. schedule_hosted_office_hours for a mentor scheduling office hours by email). MEMBERS can only watch community-visible action tools (office hours scheduling/booking, event RSVPs, community events, studio/conference room bookings, service provider recommendations, VC network changes, member/company profile updates) and the alert always DMs the member themselves. ADMINS can watch any tool (or ['*'] for all) and can direct the DM to someone else.
Natural-language condition and notification content, e.g. 'Notify me when Kat Duncan from Fenwick schedules office hours — include the date, time, and available slots.' Be specific about names/companies so unrelated actions don't trigger it.
Exact tool names to watch (from your available tools), e.g. ['schedule_hosted_office_hours', 'reschedule_hosted_office_hours']. Admins only: ['*'] to watch all tools.
Admins only: Slack user ID of a different person to DM when the alert fires. Defaults to the requesting user. Use search_members first if you only have a name.
Display name of the recipient, for listings.
list_action_alerts
List configured event-driven action alerts (condition, watched tools, recipient, trigger history). Members see their own alerts; admins see everyone's. Use when a user asks what alerts they have or before cancelling one.
add_my_slack_contribution
Add one existing PUBLIC-channel Slack message authored by the current member to the agent's search index, from its Slack permalink. The platform re-fetches the source message and verifies the Slack author matches the member — someone else's message, private channels, and DMs are refused. Use when a member shares a permalink to something they wrote and wants the agent to know/index it. This never posts or modifies anything in Slack.
Permalink to the member's own public Slack message (…slack.com/archives/…).
create_my_knowledge_entry
Create a durable, attributed, members-only knowledge entry owned by the current member. Use when a member explicitly wants to add their expertise, advice, or reusable guidance to Root's knowledge base. Do not save secrets, credentials, door codes, private personal information, tentative ideas, or one-off requests. Duplicate coverage is detected before creation. The member can later list, update, or delete this entry.
delete_my_extracted_knowledge_entry
Permanently delete one knowledge page auto-extracted from the current member's own Slack activity, removing it from the agent's knowledge base and search index. The source Slack message is untouched and the page will NOT be re-extracted. Use list_my_extracted_knowledge first when the slug is unknown. To withdraw the underlying Slack message itself from the index, use remove_my_slack_contribution instead; member-shared entries are deleted with delete_my_knowledge_entry. Community admins removing ANOTHER member's entries use delete_member_extracted_knowledge_admin.
Slug from list_my_extracted_knowledge.
delete_my_knowledge_entry
Permanently delete one member-shared knowledge entry owned by the current member. Use list_my_knowledge_entries first when the slug is unknown. This removes the entry from Root's knowledge base and search index; it cannot delete official, Slack-extracted, admin-authored, or another member's content.
get_knowledge_page_link
Issue a link to a specific knowledge base page (e.g. /kb/<slug>). Use this whenever a user pastes a /kb/... URL, asks for ACCESS to a specific knowledge page, says they cannot open a knowledge page, or asks for a direct link to a particular knowledge entry. Do NOT use this for general questions or to summarize page content — use search_knowledge_base for that. Public pages return a bare URL anyone can open; private pages return a one-click URL with a token bound to this user.
The knowledge page identifier — accepts a slug (e.g. 'vc-fund-psl'), an 8-char public_id, or a full /kb/<id> URL. The tool extracts the identifier automatically.
list_my_extracted_knowledge
List the knowledge pages the agent's pipelines AUTO-EXTRACTED from the current member's own public Slack activity, including the slugs needed to update or delete one and how often each page has informed the agent's replies. These are distinct from member-shared entries the member wrote directly. Use when a member asks what the agent has extracted/learned from their Slack activity, or before editing/removing an extracted insight whose slug is unknown. When the user is correcting a stale or wrong extracted insight, listing is only the first step — after you find the matching slug you MUST call update_my_extracted_knowledge_entry or delete_my_extracted_knowledge_entry in this conversation. Do not stop after listing and do not treat a team notification as the update.
list_my_knowledge_entries
List the current member's own member-shared knowledge entries, including slugs needed for update or delete actions. This never lists entries owned by another member.
list_my_slack_contributions
List the current member's own public Slack messages that are indexed in the agent's Slack search. Use when a member asks what of theirs the agent has indexed, wants to review/manage their contributions, or before refreshing/withdrawing one (the returned id is what those tools take). These are the agent's indexed copies — not permission to edit anyone's Slack history.
get_slack_message_reactions
Get the list of users who reacted with emoji to a specific public Slack message, including the people who reacted to any reply in the same thread by default. Use this whenever a member asks who reacted to a Slack post (with emojis), wants the contact info or emails of reactors, wants a tally of which emojis a thread received, or wants to know who participated in a thread (reactions plus replies). Requires a full Slack message permalink. Returns each unique reactor with their Slack display name, member name and email if they're a Foundations member, the emojis they used, and a per-emoji summary.
Full Slack message permalink URL (e.g. https://yourworkspace.slack.com/archives/C123/p1234567890123456). Required — the tool can't search by topic, only resolve a specific message.
read_google_sheet
Read the contents of a PUBLIC Google Sheet from its URL (or spreadsheet ID) and return the rows as structured data — headers plus data rows — so the sheet can be summarized, listed, or analyzed. Use this when the user asks about the contents of a Google Sheets link ('who's in this spreadsheet?', 'summarize this sheet'), including links mentioned earlier in the conversation. Works for sheets shared as 'anyone with the link can view' and published-to-web links; restricted sheets are reported with a clear explanation of how the owner can open access. Reads one worksheet per call — the tab in the link's gid by default, or a specific tab by name or gid. Do NOT use this for non-Google-Sheets URLs.
The Google Sheets URL (docs.google.com/spreadsheets/d/...) or bare spreadsheet ID. A gid in the URL selects that worksheet automatically.
refresh_my_slack_contribution
Re-fetch one of the current member's indexed Slack messages from Slack and refresh the agent's copy — the edit flow: the member edits their ORIGINAL message in Slack first, then this syncs the index. Use after a member says they've corrected/updated a message the agent has indexed. The agent cannot edit a human-authored Slack message itself. Get the contribution id from list_my_slack_contributions.
Id from list_my_slack_contributions.
remove_my_slack_contribution
Withdraw one of the current member's indexed Slack messages from the agent's search index, including knowledge that was extracted from it. Use when a member wants something they said excluded from the agent's answers (outdated, wrong, or they just want it gone). The source Slack message is NEVER deleted — only the author can do that in Slack; this removes the agent's indexed copy. Get the contribution id from list_my_slack_contributions. Community admins removing ANOTHER member's messages from the index use remove_member_slack_contribution_admin.
Id from list_my_slack_contributions.
save_knowledge_entry
Save durable community knowledge that an authenticated member shares in a Slack DM, so it can be retrieved and used for other members later. Use when the member explicitly asks you to remember/share information for the community OR clearly gives reusable operational guidance for future members (for example: who to contact for equipment access, where things are, or a standing how-to). This writes an attributed, members-only knowledge-base entry — conversation context alone does NOT persist knowledge for anyone else. Preserve the member's facts faithfully; do not infer missing details. Do NOT use for personal preferences (use remember_user_preference), secrets, credentials, door codes, personal/private information, one-off requests, tentative ideas, or facts found in public Slack channels (those are ingested automatically). If the member is correcting their own prior member-shared entry and its slug is known, pass update_slug. Duplicate information is detected and not re-created.
A concise, factual title for the reusable knowledge.
The durable facts to save, faithfully restated from what the member shared. Include useful links, locations, contacts, and caveats they supplied; do not add assumptions.
Optional short topic for organization and the slug, e.g. office-equipment or building-access.
Slug of an existing member_share page to update. Only the original author (or an admin) may update it.
search_current_events
Answer questions about recent news, current events, breaking developments, or fast-moving topics using Perplexity Sonar Pro with live web search. Use this when freshness matters or the question is about the outside world beyond Foundations. IMPORTANT: when the Foundations knowledge base tool is available, use this in parallel with search_knowledge_base and never as the only research source. Do not use this for Foundations policies, member data, or Slack discussion history when the structured internal tools are a better fit.
The news or current-events question to answer, such as 'What happened with Figma this week?'
Optional recency filter when the user explicitly wants breaking news or a defined recent time window
search_slack_messages
Search public Slack messages that the agent has ingested from community channels, and resolve exact public Slack message permalinks live when the user includes them. Returns the top raw matches (with speaker, channel, date, text excerpt, and permalink) for you to synthesize directly. Use this when the user explicitly wants to know what members said in Slack, wants recent discussion history, wants examples or sentiment from public-channel conversations, wants help understanding a specific Slack link, or when knowledge-base results are too thin and Slack discussion would add supplemental context. Do not use this as the primary source of truth when search_knowledge_base or another structured tool can answer the question.
Natural-language search query, like 'what have people said about SOC 2?' or 'recent threads about pricing'. Can include a Slack message permalink to inspect that exact public Slack post. Include any relevant context like channel names, people, or timeframes directly in the query.
search_knowledge_base
Search the community knowledge base for information about membership, policies, events, office space, community resources, and curated community recommendations. Returns the top retrieved knowledge chunks (with title, author, URL, and excerpt) for you to synthesize into a direct answer. Use this as the default source for general questions before falling back to Slack-message search. Do NOT use this tool when the user is asking for ACCESS to a specific knowledge base page (e.g. they pasted a /kb/... URL or asked for a link to a specific page) — use get_knowledge_page_link for that.
update_my_extracted_knowledge_entry
Rewrite the title and content of one knowledge page auto-extracted from the current member's own Slack activity — for fixing a stale, wrong, or badly-worded extracted insight. THIS is the tool that actually changes what the agent will say later; listing the page or reporting a mistake does not. Use it immediately when the member says an extracted insight misstates their view, recommendation, or experience. The page stays attributed to the member and remains an extracted insight. Use list_my_extracted_knowledge first when the slug is unknown. Strictly author-scoped: official docs, member-shared entries (use update_my_knowledge_entry), and other members' pages are refused.
Slug from list_my_extracted_knowledge.
update_my_knowledge_entry
Update the title and content of one member-shared knowledge entry owned by the current member. Use list_my_knowledge_entries first when the slug is unknown. Ownership is enforced server-side; entries from Slack extraction, official docs, admins, or other members cannot be changed.
list_my_community_offers
List products and offers submitted by the current member, including IDs for editing/removing. Use for 'what have I shared?' or to find the offer_id before an update/removal. If multiple listings could match, ask which one. Continue with next_offset while has_more is true.
remove_community_offer
Permanently remove one of the current member's own products/offers from the directory when they ask to delete or unlist it. Get offer_id from list_my_community_offers; ask which listing if ambiguous. Only the submitting member can remove it. To end only a discount while keeping the product listed, use update_community_offer instead.
search_community_offers
Search or browse the community directory of member-built products and offers. Use when members ask what others have built, for a product that solves a problem, or for community discounts/coupon codes. Use short keywords (all words must match across product, description, offer, builder or company), or omit query to browse. discounts_only returns listings with discount details or codes. Results include product URL, description, builder attribution, discount code and redemption instructions where provided. Do not invent discounts or terms. Results are paginated: use next_offset while has_more is true; showing is a page count, not a directory total.
submit_community_offer
Publish a new product or offer for the current member in the community offers directory. Members can have multiple independent offers, including for the same product URL; give each a distinct name. Use when a member wants to share something they built or offer a community discount. Ask for the product or offer name, what it does (description), and its http(s) URL if missing. A discount is optional: record the member's exact discount_details (benefit, eligibility and any expiry), discount_code and redemption_instructions when supplied. Never invent a discount. Listing is immediately searchable by members, attributed to the submitting member; no linked company is required. Root automatically announces offers created with this tool in #shill. New member product/offer posts in #shill are also captured automatically without an @mention; those receive only a brief thread confirmation. To change an existing listing use update_community_offer.
submit_community_offer_for_member_admin
Admin only. Publish a community product or offer on behalf of another active member, attributed to that member so they can edit/remove it in My offers. Use for requests like 'add Hitesh's offer to the offers database'. Supply exactly one owner identifier: member_id from search_members (preferred), or slack_user_id from their Slack mention. Never guess an owner; resolve ambiguous names first. Include product_name, product_url (HTTP/S), and description; ask for missing required details. Copy only supplied offer_details, discount_code and redemption_instructions from the member's post or the admin's request; never invent a discount or infer a code from a URL. Publication is immediate and Root automatically announces the offer in #shill. A linked company and a discount are optional. To publish the admin's own offer use submit_community_offer.
update_community_offer
Edit a product or offer submitted by the current member. Get offer_id from list_my_community_offers or search_community_offers; never guess an ID. Only the submitting member can edit, including within the same company. Pass only fields requested for change; an empty string clears discount_details, discount_code or redemption_instructions. Name, description and product URL cannot be cleared. When a discount ends, clear its code and details and update redemption instructions as appropriate; the product can remain listed. Changed details are automatically announced as a new post in #shill; unchanged saves are not.
submit_demo_application
Submit an application for the member to present at an upcoming Foundations Member Demo Showcase. Use when a member says they want to demo, present, share what they're building, or sign up to present at the next member demo event. Each presenter gets ~15 minutes (about 10 minutes of presentation plus 5 minutes of Q&A). Confirm with the member what they want to share before submitting if it's not already clear from the conversation. Do NOT use this for other event types — only for member demo presentations.
What the member will be sharing during their ~10 minute demo. Should be a clear, specific summary in the member's own voice — not a one-word topic.
submit_conference_room_booking
Book a Foundations conference room for the current member. BOTH offices have a conference room named Huddle 1 — Seattle (1605 Boylston Ave) and San Francisco (142 Minna St) — each the first conference room on the left as you enter, with its own tablet display, and each ALSO the default office-hours room for that office. Use this for general meetings, 1:1s, interviews, brainstorm sessions, calls, and small workshops. Conference room bookings are AUTO-CONFIRMED — there is no admin approval step. Do NOT use this tool for the studio (podcast room, Seattle only) — use submit_studio_booking instead. Do NOT use for office hours (use the office-hours tools). The booking will fail with a clear error if it overlaps with another conference room booking OR an existing office hour at that office (members can never double-book the room). You MUST know which office: if the member hasn't made it clear (an explicit 'SF'/'Seattle', the office they work from, or earlier context in the conversation), ASK which office before submitting — never guess. Confirm the date and start/end times with the member before submitting if anything is unclear.
Which office's Huddle 1 to book: 'seattle' (1605 Boylston Ave) or 'sf' (142 Minna St, San Francisco). Ask the member if this isn't clear from the conversation.
Short title for the booking, e.g. 'Founder 1:1 with Sara' or 'Customer interview'.
Date of the booking in YYYY-MM-DD format. If the member only mentioned a relative date, confirm the specific date with them first.
Start time in 24-hour HH:MM format (e.g. 13:00 for 1pm). If the member did not specify a time, ask before submitting.
End time in 24-hour HH:MM format (e.g. 14:00 for 2pm). If the member did not specify a time, ask before submitting.
submit_studio_booking
Book the Foundations studio room (also called the podcast room). Use this when a member wants to record, host an interview, run a workshop, take a private call, or otherwise reserve the studio. Bookings are AUTO-CONFIRMED — no admin approval needed — as long as the slot doesn't conflict with an existing booking, and a calendar invite is sent immediately. NEVER use create_fulfillment_request or submit_event_request for studio bookings — use this tool. Confirm date and start/end time before submitting if not already clear. Do NOT use for events at Foundations that don't need the studio room (use submit_event_request) or for office hours (use the office-hours tools).
Short title for the booking, e.g. 'Podcast recording with Jane' or 'Sales discovery call'.
Date of the booking in YYYY-MM-DD format. If the user only mentioned a relative date, confirm the specific date with them first.
Start time in 24-hour HH:MM format (e.g. 13:00 for 1pm). If the member did not specify a time, ask before submitting.
End time in 24-hour HH:MM format (e.g. 14:00 for 2pm). If the member did not specify a time, ask before submitting.
cancel_approved_event_request
Cancel one of the current member's APPROVED Foundations event requests — the event is removed from the calendar, attendee calendar invites are cancelled (for members-only events), any visitor door-access pass for the event is revoked, and the Foundations team is notified. Use this when a member wants to cancel an event of theirs that has already been approved and is on the schedule; for requests still in PENDING status, use cancel_event_request instead. Only future events can be cancelled — past events are read-only. Because this removes a live event that people may have RSVP'd to, confirm with the member that they really want to cancel before calling this. If the member doesn't clearly identify which event, run list_my_event_requests first.
The ID of the approved event request to cancel.
cancel_conference_room_booking
Cancel one of the current member's confirmed conference room (Huddle 1, Seattle or SF) bookings. Cancelling also cancels the calendar invite that was sent. Already-cancelled bookings can't be cancelled again, and past bookings are read-only. If the member doesn't clearly identify which booking, run list_my_conference_room_bookings first.
The ID of the conference room booking to cancel.
cancel_event_request
Cancel one of the current member's PENDING Foundations event requests. Only pending requests can be cancelled here; for a request that has already been APPROVED, use cancel_approved_event_request instead. If the member doesn't clearly identify which request, run list_my_event_requests first.
The ID of the pending event request to cancel.
cancel_studio_booking
Cancel one of the current member's studio bookings. The booking's calendar invite is cancelled too. Already cancelled bookings can't be cancelled again. If the member doesn't clearly identify which booking, run list_my_studio_bookings first.
The ID of the studio booking to cancel.
check_conference_room_availability
Check whether Huddle 1 in Seattle or SF is available for a specific date and time range, without creating a booking. Checks ALL confirmed room bookings and active office-hours blocks, including fully booked office hours. Use for availability questions before claiming a room is free; list_my_conference_room_bookings only lists the asking member's reservations and cannot prove availability. A conflict with the asking member's own reservation returns its booking ID and title for updates. Does not reserve the room; submit_conference_room_booking rechecks availability when booking.
Which office's Huddle 1: seattle or sf. Ask if unclear.
Date in YYYY-MM-DD format.
Start time in Pacific time, HH:MM.
End time in Pacific time, HH:MM, on the same day.
check_event_rsvps
Check who has RSVP'd or signed up for a Foundations calendar event. Works for BOTH event types: (1) Members-only one-off events and recurring event instances use Google Calendar invite responses (accepted/tentative/declined). (2) Public events don't get a mass calendar invite, so 'RSVPs' there are the email addresses people entered through the public Add to Calendar button on the event's /event/<token> page — treat those as RSVPs/sign-ups when answering the member. With an event_id or event_name, returns the attendee list and counts for that event along with whether the current user is signed up. With no arguments, returns all upcoming members-only events the current user has an RSVP record for. For public events, only the event's organizer (the member who requested it) and admins see individual attendee emails; everyone else gets just the count. Use this when someone asks who is attending an event, whether they (or someone) are signed up, what events they're registered for, or how their own hosted public event is doing.
get_calendar_event_details
Get detailed information about a specific calendar event.
list_calendar_events
List upcoming or future calendar events at Foundations. Supports natural-language queries over upcoming events, not historical or past-event searches.
list_community_events
List upcoming community events in Seattle that are NOT hosted at Foundations. These include member-submitted events and events auto-synced from Luma and AI Tinkerers Seattle.
list_my_conference_room_bookings
List the current member's conference room (Huddle 1, Seattle or SF) bookings — confirmed or cancelled — with status, office, and details. Use when the member asks about a conference room booking they previously made, wants to know what they have on the schedule, or needs the booking ID before editing or cancelling. Do NOT use this for studio bookings (use list_my_studio_bookings) or office hours.
list_my_event_requests
List the current member's Foundations event requests (pending, approved, and denied) with status and details, plus — for approved public events — how many people have RSVP'd by clicking 'Add to Calendar' on the public event page. Use when the member asks about a request they previously submitted, asks for the status of a pending event, wants to know what they have on the calendar awaiting approval, or asks how their hosted public event is doing (e.g. 'how many people are coming to my talk?'). For a per-attendee breakdown of who RSVP'd to a specific event, follow up with check_event_rsvps using the event_id from this tool. Do NOT use this for community events (those go through submit_community_event / list_community_events) or for bookings (office hours, studio room, conference room).
list_my_studio_bookings
List the current member's studio (podcast room) bookings with status and details. Use when the member asks about a booking they previously made or wants to know what they have on the studio calendar. Do NOT use this for Foundations event requests (use list_my_event_requests) or for community events.
list_public_events
List upcoming PUBLIC Foundations events that anyone can attend. Use this for non-member visitors asking what's coming up, what events Foundations is hosting, or whether there's anything they can attend. Returns event name, date, time, location (Seattle or SF), the public registration/details link, and the hosting member/company. Does NOT include members-only events.
lookup_event_access
Match the email sender's address against the RSVP / sign-up records of upcoming PUBLIC Foundations events, and — if one of those events is happening right now — return the exact door access instructions (the 'success message', including any event door code — the Seattle UniFi PIN or the SF ButterflyMX PIN). Use this whenever a non-member visitor asks about an event they registered for, whether they're signed up, or how to get into the building for an event. It only ever uses the sender's own email; it cannot look up anyone else.
submit_event_request
Submit a request to host a new event AT A FOUNDATIONS OFFICE — either Seattle (1605 Boylston Ave) or San Francisco (142 Minna St). Use this when a member wants to host, organize, or run an event in a Foundations space — talks, fireside chats, demos, dinners, mixers, workshops, partner events, etc. Default to the Seattle office unless the member clearly says the event is at the SF office. A public event URL (Luma, Partiful, Eventbrite, or any other event page) is STRONGLY RECOMMENDED for PUBLIC events so Root can scrape the title, description, date, and time and keep the event in sync (Luma guest list, 6-hour details refresh, /event page redirect) — ask once if they have a page, then proceed without it if they don't. Do NOT invent a title when the member already has a URL. Without a URL, public events need a name, date, and start/end time, same as members-only events (a URL is optional there too; a Luma URL on a members-only event also gets the 6-hour details refresh). When the member wants the event kept OFF the Foundations website, member calendar, weekly email, or other promo surfaces ('don't post this', 'keep it unlisted', 'don't blast it', attract an outside audience rather than the community), pass unlisted=true — that sets is_unlisted on the calendar row. Do NOT only mention unlisted in the description, and do NOT claim you flagged it for the team unless the tool result's is_unlisted is true. Unlisted is independent of visibility: a public Luma event can still be unlisted so Foundations does not promote it. The request is created in the calendar in pending status and the Foundations team is notified to review and approve it. Custom event images cannot be attached in chat — if the member wants to upload artwork that overrides the auto-generated image, send them a /root/calendar link after submitting. NEVER use create_fulfillment_request for hosting an event at Foundations — use this tool instead. Do NOT use this tool for events happening elsewhere (use submit_community_event for those), for booking the studio room (that has its own /root/studio flow), for office-hours coordination, or for member demo presentations at the Member Demo Showcase (use submit_demo_application).
rsvp_to_event
Record the current member's RSVP / attendance response for a Foundations calendar event (or recurring event instance). Use this whenever a member tells you whether they're going to an event — e.g. replying 'yes'/'no'/'maybe' to an RSVP request email, saying 'count me in', 'sign me up', 'put me down as attending', or 'I can't make it'. Map natural language to a response: yes / attending / coming → accepted, no / can't make it / not coming → declined, maybe / might / tentatively → tentative (defaults to accepted). For members-only events this writes the member's calendar RSVP record; for public events it records them through the same 'Add to Calendar' sign-up signal the event page uses (public events have no decline option, so declines can't be recorded there). Members-only events hosted on our own Luma sync both ways in the background (hourly): accepts recorded here are registered on the Luma guest list and declines cancel the Luma registration, so the member never needs to respond in both places. ALWAYS call this tool before telling a member you've marked their RSVP — never claim to have signed them up without it. Confirm the event and the resulting status back to the member afterward.
search_past_calendar_events
Search previous calendar events that have already happened. By default this covers ALL past community events — it does NOT indicate the asking user attended them. Set attendee_scope to 'me' when the user asks about events THEY attended, RSVP'd to, or signed up for (e.g. 'what events did I go to last month?'). Supports natural-language queries over historical events such as 'what events happened last month?' or follow-up searches by name/date range.
send_calendar_invite
Email a calendar invite (.ics attachment) for a specific Foundations calendar event to the requesting member's inbox. Use this when a member asks Root to send/email them a calendar invite or .ics file for an event — e.g. when the web 'Add to Calendar' button on the event page doesn't work with their calendar app (Proton Calendar, Outlook, Apple Calendar, etc.). The attachment is a standards-compliant ICS invitation that works with any calendar client. Accepts the event's ID, its public event page URL or token (the uuid in https://app.fndtns.org/event/<uuid>), a recurring event instance ID, or an event name to look up. The invite goes to the member's own email on file; only admins may direct it to a different address. For public events this also records the member as signed up (the same 'Add to Calendar' signal the event page records), so RSVP counts stay accurate.
set_calendar_invite_preference
Set which AUTOMATED community calendar invites the current member receives: 'all' (both offices, the default), 'seattle_only', 'sf_only', or 'opt_out' (no automated event invites at all). Use this — NOT remember_user_preference — whenever a member asks to stop receiving calendar invites for one office's events (e.g. 'I moved to San Francisco, stop sending me Seattle event invites' → sf_only), to opt out of automated event invites entirely, or to turn them back on ('all'). This is the only way to actually change invite delivery; a free-text preference has no effect on it. Members can also change this on their /root/account page, and admins can change it on the member detail page. The preference applies to the broadcast Google Calendar invites for members-only community events (one-off and recurring series), and Root also reconciles already-scheduled future events in the background: invites for newly excluded offices are removed from the member's calendar, and re-allowed offices are re-invited. It does NOT affect cancellation notices for events they already accepted, invites they explicitly ask for (send_calendar_invite), their ability to RSVP or browse events, or office-hours/studio/conference-room booking invites.
'all' = invites for events at both offices (the default). 'seattle_only' = only Seattle events. 'sf_only' = only San Francisco events. 'opt_out' = no automated community event invites at all.
submit_community_event
Submit a community event happening in Seattle that is NOT hosted at Foundations. Any member can submit without approval. Use when someone wants to share an event, meetup, or gathering they know about or are hosting outside of Foundations.
Name of the event
Date of the event in YYYY-MM-DD format
update_conference_room_booking
Update one of the current member's confirmed conference room (Huddle 1, Seattle or SF) bookings. Any field can change — office (move the booking to the other office's Huddle 1), title (name), date, start/end time, purpose, attendees, external guests, calendar guests (the invite is refreshed for everyone), description. Cancelled or past bookings are read-only. Time and office changes are checked for conflicts with other conference room bookings AND existing office hours at that office, and the calendar invite is automatically refreshed when the booking has been emailed already. Only pass the fields the member wants to change. If unsure which booking, run list_my_conference_room_bookings first.
The ID of the conference room booking to update.
update_event_request
Update one of the current member's Foundations event requests in place. Pending requests can have any field changed — name, date, start/end time, description, event URL, visibility, unlisted, or office (Seattle vs SF). A public event URL is strongly recommended for PUBLIC events so details stay in sync, but it is optional and can be cleared. Changing that URL re-scrapes title/description/date/time from the page. Once a request has been approved or denied, the name, description, URL, office, and unlisted flag can still be changed (date, time, and public-vs-members-only visibility are locked UNLESS the event URL itself changes — then the page is treated as the source of truth). Use unlisted=true when the member wants the event kept off the Foundations website, member calendars, and weekly email; unlisted=false to list it. Do NOT only mention unlisted in the description. Custom event images cannot be changed in chat — if the member wants to upload or replace artwork, send them a /root/calendar link. Only pass the fields the member wants to change; omitted fields stay as-is. If the member doesn't clearly identify which request, run list_my_event_requests first.
The ID of the event request to update.
update_studio_booking
Update one of the current member's studio (podcast room) bookings in place — title (name), date, start/end time, purpose, attendees, external guests, calendar guests, description. Date/time changes are checked against the studio calendar for conflicts, and the booking's calendar invite is refreshed for everyone on it. Cancelled bookings can't be edited. Past bookings are read-only. Only pass the fields the member wants to change. If you're not sure which booking they mean, run list_my_studio_bookings first.
The ID of the studio booking to update.
cancel_follow_up
Cancel an existing follow-up. Use list_follow_ups first if the user does not provide a specific follow_up_id.
The ID of the follow-up to cancel
create_follow_up
Schedule the agent to look up information and send a private DM to the user later. IMPORTANT: Follow-ups can ONLY send a private DM to the user who created it. They CANNOT post in channels, send messages to other people, or take actions like booking or updating. If the user asks to post in a channel or message someone else, explain this limitation. Use for personal reminders, recurring info check-ins, scheduled lookups, or criteria-based alerts like 'only tell me if Jane Smith has office hours.' NOTE: when the user asks to be alerted 'whenever X happens' and X is an action performed through the agent (e.g. someone scheduling office hours, booking a room), prefer create_action_alert instead — it fires the moment the event happens rather than polling on a schedule.
What the agent should do later and send to the user via private DM
The user's schedule wording exactly as they said it (e.g. 'in 2 hours', 'tomorrow at 3pm', 'every weekday at 9am', 'the first Monday of every month at 8am')
list_follow_ups
List the user's active, paused, processing, or failed follow-ups. Use when they ask what follow-ups they have scheduled.
pause_follow_up
Pause an active follow-up without deleting it. Use when the user wants it to stop running for now.
The ID of the follow-up to pause
resume_follow_up
Resume a paused follow-up so it starts running again.
The ID of the follow-up to resume
update_follow_up
Update a follow-up's instruction, schedule, or both. Use when the user wants to edit an existing follow-up.
The ID of the follow-up to update
Updated instruction for what the agent should do later
Updated schedule wording exactly as the user said it
cancel_fir_graduation_admin
Admin only. Cancel a pending Founder in Residence graduation for one member (by name, email, or member id). They stay a FIR; no type change or plan-selection email is sent.
Member name, email, or member id whose graduation should be cancelled.
graduate_firs_admin
Admin only. Schedule Founder in Residence graduations in bulk. Pass member names or emails, and/or a company name (every active FIR at that company). Each person gets a graduation notice email immediately (what graduating means, a link to the next FIR event, and that a Glowforge plaque is coming) and is flipped from FIR to Member on the graduation date (default 7 days from today, Pacific), which then triggers the usual plan-selection email. Per-person results are always returned — never silently dropped. Use list_scheduled_fir_graduations_admin / cancel_fir_graduation_admin to inspect or undo.
list_scheduled_fir_graduations_admin
Admin only. List every pending Founder in Residence graduation (who, when, whether the notice email was sent). Use before graduating more people or to confirm what's already queued.
add_vc_partner
Add a partner/contact to an existing VC fund. The VC fund directory is community-shared, so call this only when the member is the source of truth for the partner (e.g. they're identifying the GP they raised from, or recording a friendly contact they personally know). Do NOT use this to record speculative or third-hand partner info, and do NOT use it to fix or overwrite contact details on an existing partner — that's an admin-only correction.
create_vc_fund
Add a new VC fund to the database without linking the user to it.
link_vc_fund
Connect the current user to a VC fund. Use relationship_type 'investor' when the fund invested in the user's company, or 'friendly' when they know someone at the fund. Auto-creates the fund if it doesn't exist.
list_my_service_providers
List the service provider recommendations the current member has added to the community directory. Use when a member asks things like 'what providers have I recommended?', 'show my recommendations', or before editing/removing one so they (and Root) can see the exact names and ids.
list_my_vc_connections
List the current user's VC fund connections - which funds they've raised from or are connected to.
query_vc_connections
Find which community members have raised from or are connected to a specific VC fund.
recommend_service_provider
Add a new service provider recommendation to the community directory on behalf of the current member. Use when a member wants to recommend, add, vouch for, or share a vendor/consultant/firm they've worked with (e.g. 'add my accountant', 'I want to recommend our law firm'). An initial rating (1-5) and a short review describing their experience are required — if the member hasn't given them, ask before calling. The provider is attributed to the member as the recommender.
The service provider's name (person or firm)
Category for the provider. Must be one of: Legal Services, Accounting & Tax, Banking & Finance, Insurance, HR & Recruiting, Marketing & PR, Design & Branding, Software Development, Real Estate & Office, Compliance & Regulatory, Sales & Business Development, Content & Copywriting, Video & Photography, Events & Community, Intellectual Property, Other Services. Common shortcuts are normalized automatically (e.g. "lawyer" -> "Legal Services").
The member's rating of the provider, 1 (poor) to 5 (excellent)
A short review describing the member's experience with the provider
remove_service_provider
Remove (delete) one of the current member's OWN service provider recommendations from the community directory. Members can only remove recommendations they added, and this also deletes all reviews on that provider, so confirm with the member before calling. Identify the target by `provider_id` when known, otherwise by `provider_name`.
search_service_providers
Search community-recommended service providers (accountants, lawyers, HR, marketing, etc.) that Foundations members have reviewed. Use this whenever a user asks for recommendations, referrals, 'who do you recommend for X', or 'who recommended <provider name>'. Each result includes `recommended_by` — the Foundations member who added that provider to the directory — so this is the right tool for identifying who vouched for a given provider. Query supports natural language, multiple names in one call (e.g. 'Claire and Marsha'), category words, or descriptions; hybrid vector + keyword search is used under the hood. IMPORTANT: the returned count is a lower bound — hybrid retrieval looks at a pre-filtered candidate set, not the entire provider directory. Phrase counts to the user as 'at least N'.
search_vc_funds
Search the VC fund directory semantically. Use for broad discovery queries like 'early stage AI funds', 'who invests in climate tech', or 'seed stage funds in Seattle'. Returns ranked results with relevance explanations. For looking up connections to a specific known fund, use query_vc_connections instead. IMPORTANT: the returned count is a lower bound — hybrid retrieval looks at a pre-filtered candidate set, not the entire fund directory. Phrase counts to the user as 'at least N'.
Natural-language search query about VC funds, investment stages, sectors, or themes
unlink_vc_fund
Remove the user's connection to a VC fund.
update_my_provider_review
Update the current member's star rating and/or written review for a service provider — either one they recommended or any provider in the directory they've used. Use when a member wants to change how they rated a provider or revise their review text (e.g. 'change my rating for Acme to 3 stars', 'update my review of our accountant'). Identify the provider by `provider_id` when known, otherwise by `provider_name` (matched against the member's own recommendations).
update_service_provider
Edit one of the current member's OWN service provider recommendations — change its name, category, URL, or description. Members can only edit recommendations they added. Identify the target by `provider_id` when known (e.g. from list_my_service_providers), otherwise by `provider_name`. Only pass the fields the member wants to change. To change your star rating or written review of the provider, use update_my_provider_review instead.
update_vc_partner_email
Admin only. Update a VC partner's email address in the shared community VC directory. Members who notice incorrect partner contact info should log a fulfillment request via create_fulfillment_request and an admin will correct it — direct rewrites are gated to prevent contact-record tampering across founders.
book_calendly_meeting
Book the CURRENT requesting user into an available Calendly slot with a connected member. The invitee name and email come from their verified Root identity, never a supplied third party. First resolve the member and allowed meeting type, read availability, and collect required answers and location. Only execute when the user has requested booking this host, meeting type, and time (or explicitly authorized you to choose within their stated constraints). Otherwise present options and ask them to choose. Do not infer booking permission from merely asking about availability. Rechecks the slot and prevents duplicate submissions. Confirm a booking only on success and return its time, timezone, and cancel/reschedule links. On an uncertain result, tell the user to check their calendar; do not try another time automatically.
book_admin_meeting
For members found by search_calendly_members, use book_calendly_meeting instead. This legacy team-calendar tool books the current member directly into the requested admin’s individual Calendly event. Calendly sends the invitation and notifications. Use after the member chooses a specific time (or explicitly requests that exact time); first look up availability to get valid slots and required questions/location. The member’s name and primary email come from their account; cannot book another person. Never guess a slot, answer, or location. Honor an unconfirmed result: do not retry at a different time to work around an uncertain booking. Use list_my_admin_meetings to check. Cancellation and rescheduling use the private Calendly links in the result or invitation.
The requested admin’s member ID (preferred), name, Slack mention, or email. Use list_bookable_admins if unclear.
ISO date/time with Z or an explicit UTC offset. Use a start_time returned by availability when booking.
get_admin_meeting_availability
For personal member connections, first use search_calendly_members and the member Calendly tools. This legacy team-calendar tool finds live Calendly meeting times for a specific Foundations admin (e.g. Aviel or Peter). Returns available slots, duration, timezone, meeting locations, and required booking questions. Use when members ask to schedule time with an admin; do not book a room or mentor office-hours slot instead. Default search is the next seven days. Offer a few matching times; collect the member’s chosen slot and required answers. Empty availability means no open slots in this range, not that booking is unsupported.
The requested admin’s member ID (preferred), name, Slack mention, or email. Use list_bookable_admins if unclear.
ISO date/time with Z or an explicit UTC offset. Use a start_time returned by availability when booking.
ISO date/time with Z or an explicit UTC offset. Use a start_time returned by availability when booking.
list_my_admin_meetings
Check the current member’s upcoming/recent admin meetings requested through Root, including attempts awaiting confirmation. Refreshes Calendly event status and returns private cancellation/rescheduling links (DM/email/API only). Does not list other members’ meetings or unrelated events on admin calendars. Use the returned links to change meetings; never claim Root has canceled/rescheduled a meeting just by sharing a link.
connect_calendly
Create a private link for the CURRENT user to connect or manage their own Calendly account, choose meeting types Root may book, or disconnect. Use when they ask to link their Calendly or change its booking permissions. Never ask for API tokens in chat. Share the returned link only with this user in a private conversation. Linking alone does not enable bookings: the member selects meeting types on the page.
list_bookable_admins
List active Foundations admins whose individual Calendly event link is configured on their member record. Use when a member wants time with an admin (such as Aviel or Peter) or asks who they can book. These are personal admin meetings, separate from mentor office hours and room reservations.
get_calendly_availability
Get live available times for an enabled Calendly meeting type belonging to a member. Date range must be in the future and at most seven days; query additional windows for longer searches. Use ISO timestamps with explicit offsets, and present slots in the requester's timezone. These are the host's available times; Root has not checked the requester's calendar.
list_calendly_meeting_types
List the meeting types a connected member allows Root to book, including duration, locations, and required questions. Use a member_id returned by search_calendly_members. Do not guess event type URIs or offer types absent from this list.
search_calendly_members
Find community members who connected Calendly and enabled meeting types for Root. Search by name, email, Slack user ID, or member ref. Resolve ambiguous names before choosing a host. No matches means Root cannot book that member yet; do not claim to know their availability.
auto_update_company_description
Research and auto-generate or refresh the current user's company description from the company's name, website, and public web data. Use ONLY when the user explicitly asks Root to write, regenerate, refresh, or auto-update their own company description.
auto_update_member_bio
Research and auto-generate or refresh the current user's member bio from their LinkedIn profile and known company context. Use ONLY when the user explicitly asks Root to write, regenerate, refresh, or auto-update their own bio.
set_fde_opt_in
Opt the current member into or out of FDE (Foundations Design and Engineering). Opting in makes them eligible to be considered for projects, with no obligation to accept work, and invites them to the FDE Slack channel. Opting out stops eligibility and removes them from the FDE Slack channel. Act only on an explicit request from the current member; never opt in someone else or infer consent from their skills or interests. Also editable on /root/account. Use get_member_profile to check current participation.
True to opt into FDE projects; false to opt out. Must reflect the member’s explicit choice.
create_company
Create a NEW company in the Foundations directory on behalf of the current member and link them to it (they become the company's billing/management contact). Use when a member says their company isn't in the directory yet and wants to add it. If a company with the same name already exists, this fails and suggests join_company instead. Only for members without an existing company link.
The company name
create_job_posting
Publish a new job listing on the Foundations job board on behalf of the current member's company. Use when a member wants to post an opening, share a role they're hiring for, or add a job to the board (e.g. 'post a job for a founding engineer', 'add this role to the job board'). The listing goes live immediately on the community job board (/root/jobs). Requires a job title; a description and an application/job-post URL are optional but strongly recommended so other members can learn more and apply. The member must have a company linked to their profile — listings belong to companies.
The job title, e.g. 'Founding Engineer' or 'Head of Growth'
delete_job_posting
Remove (delete) one of the current member's OWN company's job listings from the Foundations job board — use when a role is filled or no longer open. Members can only remove their own company's listings, and removal is permanent, so confirm with the member before calling. Identify the target by `job_id` when known, otherwise by `job_title`.
who_knows
Find community members with demonstrated knowledge or experience on a topic, based on what they've actually said in public Slack channels. Returns a ranked list of people with per-person evidence (messages, dense discussion runs, and threads they drove, with dates and permalinks). Use this when the user asks 'who knows about X?', 'who has experience with Y?', 'who should I talk to about Z?', or wants an introduction to someone with specific expertise. Prefer this over search_slack_messages when the QUESTION is about people/expertise rather than about the content of the discussion itself. Rankings favor recent, substantive contributions over passing mentions.
The topic, skill, or domain to find knowledgeable people for, e.g. 'SOC 2 compliance', 'fundraising from angels', 'React Native'.
Max people to return (default 5).
forget_user_preference
Deactivate a previously saved user preference so it stops applying in future conversations. Use when the user says to forget, remove, undo, or stop using a remembered preference. If the exact preference is unclear, use list_user_preferences first.
The ID of the saved preference to forget or deactivate.
get_company_info
Get the current user's company profile information including name, URL, and description.
get_member_profile
Get the Foundations member profile of the person you are talking to — includes their bio, LinkedIn, FDE project opt-in (fde_opt_in), and directory status (Founder in Residence, FIR Alumni, Alumni, or Member). FDE opt-in means eligibility for consideration, with no obligation to accept projects. This returns THEIR information, not yours.
get_mention_leaderboard
The community mention leaderboard: active members ranked by how many of Root's human-facing replies mention them — a proxy for the community's most valuable mentors and contributors. Use when someone asks who the most-mentioned, most active, or most helpful members are, where they rank, or about the leaderboard itself. Only content-grounded mentions count: replies that drew on public Slack discussion or the knowledge base. Operational mentions (badge-ins, event rosters, office-hours listings) and automated member API traffic are excluded. The public page at /root/leaderboard shows aggregate counts; signed-in members can click a name to browse that member's stored contributions — their knowledge entries and indexed public Slack messages — never any conversation excerpt.
join_company
Link the current member to an EXISTING company in the Foundations directory. Self-joining is only allowed when the member's email domain matches the company (its website domain or a current member's email domain) — public email providers like gmail.com never count. On a domain mismatch, offer to log a fulfillment request so the Foundations team can link them manually. Use create_company instead when the company isn't in the directory yet.
The company to join — its exact name (preferred), directory ID, or slug
link_member_email_alias
Link a SECONDARY email address (an alias) to the Foundations member profile of the person you are talking to, so all of their email identities resolve to the same account. Use when a member says they have multiple email addresses/identities to tie together, or wants Root to recognize them when they write from another address. The primary email on the profile is unchanged — billing, mailing lists, calendar invites, and building access keep using it (use update_member_email to change the primary). After linking, Root recognizes the member when they email from the alias, and person lookups by that address resolve to them. An address that already belongs to another member profile (as primary or alias) cannot be linked. ONLY pass an email address the member explicitly provided. Admins may pass `member` to link an alias on another member's profile; for everyone else this acts on the CURRENT user's own profile.
The secondary email address to link, exactly as provided (e.g. jane@sideproject.com)
list_job_postings
Browse job listings on the Foundations job board. Use when a member asks who's hiring, what jobs are posted, whether a specific company has openings, or wants to see their own company's listings before editing/removing one. With no parameters it returns the whole board grouped by company; pass `company_name` to see one company's openings, or set `mine_only` to list just the current member's own company's listings (with ids, for chaining into update/delete).
list_member_email_aliases
List the email addresses on the Foundations member profile of the person you are talking to: the primary email plus any linked secondary addresses (aliases). Use when a member asks which email addresses are tied to their account. Admins may pass `member` to view another member's linked addresses.
list_space_rentals
Look up desk and office rentals in SEATTLE (1605 Boylston Ave): which companies and members rent which desks/offices, rental status (active or upcoming) and start dates, and optionally which desks/offices are currently available. This directory has NO San Francisco inventory and cannot establish SF availability. Pass the office the user asked about; SF requests return an explicit unsupported scope instead of Seattle results. Use for Seattle rental occupants or vacancies. NEVER returns pricing or billing details — rental rates are deliberately excluded, so do not use it (or guess) for questions about what a rental costs.
list_user_preferences
List the explicit preferences and remembered instructions previously saved for the current user. Use when they ask what you remember, what preferences you have stored, or to review saved nicknames, aliases, formatting rules, or recurring instructions.
invite_to_slack_channel
Add or re-add the requesting active member to a Slack channel. Use for 'invite me back to the Seattle office channel' (#office-sea), the SF office channel (#office-sf), or another public community channel. Accepts a channel ID, #name, or Slack channel mention. Only adds the requester, never another person. Other private channels and external shared channels require an admin. Does not create/reactivate Slack accounts or grant building access. Available in Slack and the member API, not email.
Channel ID, #channel-name, or <#ID|name>. Seattle office = office-sea; SF office = office-sf.
remember_user_preference
Save an explicit user preference, alias, nickname, formatting rule, or recurring workflow instruction for future conversations. Use when the user clearly asks you to remember something, says 'from now on', 'treat X as Y', 'call me', 'prefer', 'always respond', or otherwise gives a durable instruction for future interactions. Only save preferences the user explicitly states or clearly requests. EXCEPTIONS (do NOT use this tool for these — a free-text preference only applies when talking to this user and will not actually change the behavior): Slack DM reply delivery → set_dm_reply_style; channel auto-replies → set_auto_reply_preference; stop/resume @-mentioning or tagging them when Root attributes their advice in other people's conversations → set_slack_mention_preference.
The durable instruction to remember for future conversations, written plainly and specifically.
The kind of preference: nickname_alias, formatting, tone, workflow, naming, or custom.
Optional phrase or wording that should trigger this preference, like 'handsome man'.
Optional canonical meaning or target value for the trigger phrase, like 'Bryan'.
Use 'all' only if the user clearly wants this to apply across Slack and email. Otherwise, prefer the current channel.
remove_member_email_alias
Unlink a secondary email address (alias) from the Foundations member profile of the person you are talking to. Use when a member no longer wants an address tied to their account. The primary email cannot be removed this way — use update_member_email to change it. Admins may pass `member` to act on another member's profile.
The linked secondary email address to remove
search_companies
Search the Foundations company directory using AI. Use this when the user asks about specific companies, wants to find companies by industry, product, market, or status, wants to compare or count companies by attribute, or wants to know which company matches a natural-language description. Do not use this for the current user's own company profile when get_company_info or update_company is the better fit. IMPORTANT: `totalFound` is a lower bound — hybrid retrieval looks at a pre-filtered candidate set, not the entire directory. Phrase counts to the user as 'at least N' rather than exact totals, especially for broad queries.
What the user is looking for — can be a company name, market, industry, product area, team, status, or any natural language query
search_members
Search the Foundations member directory using AI. Pre-filters member profiles (names, bios, companies, roles, expertise, member types, directory status such as actual Founder in Residence vs Alumni vs Member, and VC connections) via hybrid embedding + keyword + fuzzy text search, then uses an LLM to rank the most relevant members for any query — including semantic/conceptual searches like 'who knows about SMBs' or 'fintech founders'. Use this whenever someone asks about finding people, who has experience with something, member lookups, counting members by attribute (e.g. 'how many members are FIRs'), or looking up a specific member's contact info (e.g. 'what's Matt's email?', 'how do I reach Sarah?'). Each match comes back with the member's email and LinkedIn so you can answer contact-info questions directly — sharing this info is expected in the community. ALSO COVERS COMPANY EMPLOYEES: a person's name/email that matches no member is automatically checked against company employees (non-member seats at member companies — people who work in the building without a member record) and returned in `employee_matches` with their role and company, clearly labeled as a non-member; an employee_id is NOT a member_id and must never be passed to member-only tools. TWO MODES: (1) `query` — ranked semantic search for open-ended questions; (2) `names` — exact list correlation: when the user provides a LIST of specific people (from a message, spreadsheet, or document), pass them as the `names` array instead of packing them into `query`. Every name is resolved individually and gets an explicit outcome (matched member / matched employee / ambiguous / not found) with NO result cap — ranked search would silently drop names past its top-K. IMPORTANT: in query mode the `totalFound` count is always a lower bound (we look at a pre-filtered candidate set, not the entire directory) — phrase counts to the user as 'at least N' rather than exact totals, especially for broad queries like 'all healthcare founders'.
set_auto_reply_preference
Control whether the agent jumps in on THIS USER's top-level messages in monitored Slack channels without being @-mentioned (auto-replies). Use this — NOT remember_user_preference — when the user asks the agent to stop answering their channel messages uninvited, to only chime in when very sure, or to re-enable auto-replies. 'off' = never auto-reply to them; 'high'/'medium'/'low' = personal confidence bar overriding the community default (high = only when very confident); 'default' = follow the community setting. Only affects auto-replies in channels — @-mentions, DMs, and threads always get replies.
'off' to never auto-reply to this user, 'default' to follow the community setting, or a personal minimum confidence level ('high' = most conservative, 'low' = most eager).
set_dm_reply_style
Set how replies are delivered in Slack DMs with this user: 'direct' posts replies straight into the DM conversation (the default), 'thread' posts replies as threads on the user's message. Use this — NOT remember_user_preference — whenever the user asks to stop replying in threads, reply directly in DMs, or conversely to keep DM replies in threads. This is the only way to actually change delivery; a free-text preference has no effect on it. Applies only to top-level DM messages — when the user writes inside an existing thread, the reply always stays in that thread.
'direct' to reply straight in the DM conversation, 'thread' to reply in a thread on the user's message.
update_company
Update the current user's company profile. Provide only the fields to update. Includes stealth status: stealth companies are hidden from the public fndtns.org company directory (but stay visible internally to members) — set is_stealth to false when a member says their company shouldn't be in stealth or asks why it isn't showing on the public website, or true when they want it hidden. Visibility on the public directory updates automatically.
update_job_posting
Edit one of the current member's OWN company's job listings on the Foundations job board — change its title, description, or application URL. Members can only edit their own company's listings. Identify the target by `job_id` when known (e.g. from list_job_postings with mine_only), otherwise by `job_title`. Only pass the fields the member wants to change; pass an empty string to clear the description or application URL.
update_member_email
Update the primary email address on the Foundations member profile of the person you are talking to. Use when they ask to change, update, or correct their email address. This changes their email everywhere Root uses it — their member record, the mentors table, mailing lists, and email-based identity resolution — so ONLY pass an email address the member explicitly provided in their message. This always acts on the CURRENT user's own profile; it cannot change someone else's email.
The new primary email address, exactly as the member provided it (e.g. jane@company.com)
update_member_profile
Update the Foundations member profile of the person you are talking to. Use when they provide or share their bio text or a LinkedIn URL — including in reply to being asked for it. ONLY pass values that appear in the member's message. NEVER generate content yourself — if the member only sent a URL, only update that field. Do not use this for the member's display/full name — use update_member_name. This is the member's ONE bio: if they host office hours, the bio shown on their office-hours listings is updated to match automatically.
update_member_name
Update the primary full/display name on the Foundations member profile of the person you are talking to. Use when they ask to change, correct, or fix a misspelling of their name on their member record or in the directory. This updates the official directory name and syncs it to the mentors table, mailing lists, and member search — so ONLY pass a name the member explicitly confirmed. Pass the COMPLETE display name as it should appear (first and last). If they only corrected one part, keep the rest of their current name. This always acts on the CURRENT user's own profile; it cannot change someone else's name. Do not use this for Slack display names, bios, or email — those are separate.
The member's full display name as it should appear in the directory (e.g. Dmitri Zorine). Must include first and last name.
add_company_employee
Add an employee (a non-member teammate seat) to the user's company. Use this whenever a member asks to add a teammate/employee to building access or the #office-sea channel — it works for any member whose company has an active desk/office rental, a company-billed plan with seats, a Founder in Residence (up to 2 employees), or a regular member (up to 1), and for a company employee granted management access by a member of their company. Employees get automatic UniFi (Seattle) building access and a #office-sea Slack invite. To replace the person currently on a seat, remove them first then add the new teammate (or point the member at /root/company — changing the seat's email there is a full swap: previous access revoked, new person gets their own UniFi invite). (For San Francisco access, use request_sf_access_for_teammate after adding them. If their Seattle UniFi setup email never arrived, use request_unifi_access with their employee_id.)
cancel_membership
Cancel the user's membership subscription. Billing stops immediately, but the member keeps full member access (building + Slack) through the end of their current paid billing period — their account is then deactivated automatically on that date (the result includes the exact date as access_until; relay it to the member). Re-selecting a plan before then cancels the scheduled deactivation automatically.
cancel_scheduled_employee_removal
Cancel a pending scheduled employee removal for the user's company, by schedule id (from list_scheduled_employee_removals) or by the employee's email. The employee's seat and building access stay active.
change_membership_plan
Change the user's membership plan OR billing cycle (monthly <-> yearly). Works for new selections and for changes to an existing membership — an active membership stays active through the change, and any member of a company may adjust their company's plan or billing cycle. Switching to a COMPANY plan automatically consolidates overlapping individual memberships at the company (the user's own and colleagues': never-activated ones close, paid ones run through their paid-through date) and the result lists what was folded in — so use this directly for 'move us to the company plan' requests instead of escalating a 'Membership Conflict'. The only conflict that still needs a human is replacing an ACTIVE company plan that covers other people with an individual plan. Specify the target plan name and optional billing period. If a payment method is still needed, the result includes a personal payment-setup link to pass along.
request_employee_slack_access
Check, send, or resend the #office-sea Slack Connect invitation for an EXISTING active company employee. Use when a teammate hasn't received their Slack invite or cannot find the office channel. Members and manager employees can act only for their own company's employees; admins can act for any employee. Resolve by employee_id, name, or email on the employee roster. action=check only inspects; invite repairs missing/expired invitations; resend explicitly resends a pending invitation. Reports actual channel membership separately from an invitation awaiting acceptance. Does not grant full workspace membership, invite arbitrary emails, or reactivate deactivated Slack accounts. Available in Slack and the member API, not email.
check reads current status; invite sends if missing/expired; resend explicitly sends again even when pending.
check_building_access
Check whether the current user (or one of their company's employees, or — for admins — any person by email) ACTUALLY has building access, by querying the door-access system directly. ALWAYS use this before making any claim about whether someone has building/door access — membership plan or billing status NEVER determines door access, and an empty door-event history only means they haven't badged in, NOT that they lack access. Members and manager employees can check an active employee of THEIR OWN company (pass employee / employee_id, or email). Admins can check anyone by email. Covers both offices: 'seattle' (default — UniFi account status, instant; every active member and company employee is entitled to Seattle access automatically) and 'sf' (ButterflyMX tenant status at 142 Minna St; SF access is request-based, so not having it yet is normal — this check drives a browser automation and takes 1-2 minutes, so only use it when the user specifically asks about SF access). Returns the authoritative account status plus recent badge activity.
create_guest_door_pass
Create a temporary guest door code for EITHER office — a UniFi PIN for the Seattle front-door keypad, or a ButterflyMX code that works on every keypad at the SF space (142 Minna St, street entrance and interior doors) — so a member's guest can let themselves in during a time window. Physical keycards are retired; this door code IS guest access — never tell a member to ask the team for a keycard. Use when a member asks for a door code for a guest ('send my guest a code for this afternoon', 'my cofounder's visiting the SF office tomorrow 9-5, can she get in?') or when guest policy / bringing a guest comes up and they may need entry. Also the right tool when a guest is at the door RIGHT NOW ('buzz my guest in', 'let them in downstairs') — Root has NO remote unlock/buzz-in capability at either office, so mint a pass starting now and have the member relay the PIN; the member can also open the door themselves from the UniFi Endpoint app (Seattle) or the ButterflyMX app (SF), or escalate_to_admin for a human. SF guest passes ALWAYS cover one FULL Pacific calendar day, 12:00 AM–11:59 PM. Use visit_date for 'tomorrow' or a named day, and never invent business hours such as 8 AM–8 PM. Legacy SF start/end timestamps select a single Pacific date and are expanded to the full day; shorter SF windows are not supported. Seattle defaults to now until the end of today (Pacific) and supports chosen windows up to 24 hours. Visits must start within the next 7 days; for multi-day access, use escalate_to_admin so the team can arrange it. Creating an SF code drives the ButterflyMX dashboard and can take a minute or two. The code comes back exactly once and cannot be retrieved later, so ALWAYS include it in your reply along with the validity window — except in a public Slack channel, where the code is automatically withheld and DM'd to the requester; follow the result's public_channel_note. After creating a pass you can tell the member you'll DM them when their guest first uses the code.
Which office the guest is visiting: 'seattle' (1605 Boylston Ave, UniFi front-door PIN) or 'sf' (142 Minna St, ButterflyMX code valid on all keypads). If the member didn't say and it isn't clear from context, ask rather than guessing.
The guest's name — shown on the pass and in the door audit log.
get_membership_info
Get the current user's membership plan details, billing info, status, any active desk/office rentals (price, billing method, start date), and their recent invoice history with per-invoice payment status. Billing info includes the card on file (brand + last 4) for Stripe auto-billed plans/rentals, or notes when payment is by manual invoice. Use this for questions about their plan, dues, rental billing, or past/existing invoices — monthly invoices are generated automatically and their PDFs are viewable/downloadable on the member's secure account page (/root/account), so 'send me my invoices' is answered by pointing there, never by escalating to the team.
get_membership_plan_options
Get billing-plan options and pricing for the current member's existing Foundations account. Use with get_membership_info when they want to choose a plan, change their own billing, or start paying dues (including an FIR graduating to a paid plan); use change_membership_plan / get_payment_link for the self-serve path instead of sending them through the public membership application again. Do not assume every 'new membership' question is about their own billing: a question about another person, an office location, renting private space, or who to contact should be answered as asked. These billing plans do not establish SF private-office availability or rental terms.
get_payment_link
Generate and resend the user's personal membership payment link. Use when a member asks for a link to pay for, buy, or set up their membership, says they lost or never got their payment link, or their link expired. Returns a plan-selection link if they have no active membership yet, or a payment-setup link if they do. The link is personal to the requesting member and expires in 7 days.
get_reactivation_link
Generate a personal reactivation link for a DEACTIVATED Foundations member. Use when the sender says their membership was deactivated, cancelled, or removed and they want to reactivate, rejoin, or restore their account/access. Matches ONLY the sender's own email address against the member records — it cannot look up or reactivate anyone else. The link takes them to plan selection; picking a plan and completing payment automatically reactivates their membership, building access, and Slack account.
request_sf_access_for_teammate
Grant San Francisco (ButterflyMX) building access to a TEAMMATE — either another Foundations member of your company OR one of your company's employees (non-member seats). Use this when a member (or a company employee with management access) asks to give SF door access to someone else at their company (e.g. 'give SF access to my teammate' or 'add my employee to SF'). For your OWN SF access, use request_butterflymx_access instead. Only works for teammates that belong to the same company as the requester. The result usually includes a confirmationLink — the teammate's personal ButterflyMX registration link. In a DM or email, ALWAYS include that link in your reply so the requester can pass it to their teammate, since ButterflyMX's own invite emails frequently don't arrive. In a public Slack channel the link is automatically withheld and DM'd to the requester instead — follow the result's public_channel_note and never paste a registration link into a public channel.
Email of the teammate (a member or an active company employee) to grant SF access to.
grant_employee_management_access
Grant one of the user's company EMPLOYEES (a non-member seat) management access — 'COO mode'. Use when a member asks to let an employee manage the company through Root (e.g. 'give Maddie management access', 'let our office manager handle visitors and employees'). With management access the employee can DM Root to: create guest door passes for visitors at either office, view/update the company profile, manage the employee roster (add/remove/schedule removals), grant SF access to teammates, and send/check UniFi access or fix an SF door profile for other employees. MEMBER-ONLY: employees (even managers) cannot grant or revoke management access. The person must already be an active employee of the member's company (add_company_employee first if not).
Email of the active company employee to grant management access to.
list_scheduled_employee_removals
List the pending scheduled employee removals for the user's company — who is scheduled to be removed (and lose building access), when, and each schedule's id (needed to cancel one).
manage_company_seats
View the company's employee roster and seat info. Works for any member whose company is eligible to have employees — a company-billed plan with seats, an active desk/office rental (no fixed cap), a Founder in Residence (up to 2 employees), or a regular member (up to 1). Also works for a company employee who has been granted management access by a member of their company.
sync_unifi_intercom_directory
Refresh individual people on the Seattle (UniFi Access) entry intercom/callbox at 1605 Boylston RIGHT NOW. The directory is already KEPT IN SYNC AUTOMATICALLY: every 15 minutes Root lists every person at a company with an active desk or office rental — each person is their OWN selectable entry (Company — Name), so a visitor at the door rings one person, never the whole company. Building Admins stays at the top of the list. New renters and hires appear within about 15 minutes; people and companies that leave are dropped; renames follow along. Having employees is not enough — no rental means no listing. The Foundations company itself is never listed here (those people stay on the hand-made Building Admins entry). Hand-made intercom entries are never touched. When someone asks whether their company/new hire is on the callbox, the honest answer is that it happens on its own within ~15 minutes — use this tool to push the update immediately, or when they explicitly ask to sync/refresh/check. A member refreshes THEIR OWN company's people. Admins can target any company by name, or refresh the FULL directory (replace mode: also removes stale listings the sync created earlier). Seattle only. The result reports per-person status and anyone the callbox can't ring yet (no UniFi account / deactivated); a listing the door system rejects — or the whole sync when the door system is unreachable — is handed to the Foundations team. Report exactly what happened.
remove_company_employee
Remove an employee (non-member teammate seat) from the user's company by their email, effective IMMEDIATELY. Works for any member whose company is eligible to have employees (rental, company plan, FIR, or regular member), and for a company employee granted management access by a member of their company. Revokes their building access and removes them from #office-sea. To remove someone at a future date/time instead ('remove them Wednesday at 5pm'), use schedule_employee_removal.
request_butterflymx_access
Grant the current Foundations member access to the San Francisco space in ButterflyMX, or resend their ButterflyMX registration invite when they say their SF door access invite/login is missing. Use this only for the current user, not to grant access to someone else. The result usually includes a confirmationLink — the person's personal ButterflyMX registration link. In a DM or email, ALWAYS include that link in your reply, since ButterflyMX's own invite emails frequently don't arrive. In a public Slack channel the link is automatically withheld and DM'd to the requester instead — follow the result's public_channel_note and never paste a registration link into a public channel.
request_unifi_access
Send a UniFi building access setup email (the 'invite') to the current user OR to one of their company's employees. Use this for first-time Seattle building access AND whenever someone asks to reset a UniFi password or regain/re-setup building access — re-sending it lets them set up their login again. When a member (or a manager employee) asks to send/resend the UniFi invite to a teammate who is a company employee — e.g. 'send Brayden the UniFi email', 'resend my employee's door access invite' — pass employee / employee_id (prefer employee_id from search_members employee_matches). Works for both Foundations members and company employees (non-members with company building access). ALWAYS relay the result's what_to_expect guidance — the email never says 'invite' in its subject and people routinely miss it or get stuck on the app's 'domain' prompt. For San Francisco access for a teammate, use request_sf_access_for_teammate instead.
retry_failed_invoice
Retry the charge on one of the user's OWN failed/overdue invoices using the card on file. Use when a member says an invoice payment failed, their card was declined, or they ask to retry/re-run a failed charge — often right after updating their payment method. Without an invoice_id it finds the member's retryable invoices: exactly one is retried immediately, several are returned so the member can pick. Never generates new invoices (those are created automatically each billing cycle); invoice history and PDFs live on the member's secure account page (/root/account), which also has a Retry charge button.
revoke_employee_management_access
Revoke a company employee's management access ('COO mode'), returning them to the basic employee surface (own building access + community search). Use when a member asks to remove an employee's management permissions. MEMBER-ONLY. The employee keeps their seat and building access — to remove them entirely use remove_company_employee.
Email of the company employee whose management access should be revoked.
schedule_employee_removal
Schedule the removal of a company employee (non-member teammate seat) — and the revocation of their building access — for a specific FUTURE date/time, e.g. 'remove Andres' access on Wednesday at 5pm'. The employee keeps full access until then; at the scheduled time the removal runs automatically through the same path as remove_company_employee (seat deactivated, UniFi/Seattle access revoked, SF/ButterflyMX revoked if granted, removed from #office-sea). Works for any member whose company is eligible to have employees (rental, company plan, FIR, or regular member). A new schedule for the same employee replaces any earlier one, and removing or re-adding the employee before the scheduled time clears it. For an immediate removal use remove_company_employee instead.
The employee's email (as listed on the company roster).
When to remove them: 'YYYY-MM-DD HH:mm' (24h, interpreted as Pacific time) or full ISO 8601 with an offset. A bare 'YYYY-MM-DD' schedules for 5pm Pacific that day. Convert relative phrasing like 'Wednesday at 5pm' to a concrete date first.
update_payment_method
Generate a link for the user to update their payment method.
update_butterflymx_tenant
Update or sync an SF door-access (ButterflyMX) profile so the door system shows current details — use this when someone says SF office access / the door entry log shows an OLD company, a wrong/outdated name, or SF access still registered under an OLD email address. ButterflyMX does not sync profile changes after the initial setup, so this rewrites the tenant profile in place: the display name (defaults to the current Foundations name), when the ButterflyMX form has a company field their company (defaults to the current Foundations company), and — when old_email is provided — re-keys the tenant record from that old address to the current Foundations email. Note that a member changing their email through Root (update_member_email) already gets this email re-key automatically; pass old_email only when the SF profile is stuck under an address that predates their current records. Registration state and door access are untouched. Works on the current user's own profile, OR — when a member or manager employee passes employee / employee_id — on an active employee of THEIR OWN company (e.g. 'SF still shows Prarabdh's name for Brayden'). Prefer employee_id from search_members employee_matches. Report honestly what the result says changed — if the result says ButterflyMX has no separate company field, the display name is the only text the door system shows.
close_survey_admin
Admin only. Close an open survey so it stops accepting new responses (including passive collection). Use this when an admin asks to close, pause, or stop a survey. Existing responses are preserved.
The id of the survey to close.
list_surveys_admin
Admin only. List surveys (open, closed, draft, or all) with their question counts and response counts so an admin can quickly see what's running and what's been answered.
send_slack_channel_message_admin
Admin only. Post a single Slack message AS the agent into a public OR private channel (not a DM). Use this when an admin asks to post/announce in a channel like #general. Accepts a channel id (C0123ABCD), a #name, a mention link (<#C0123ABCD|general>), or an archive permalink. Public channels the agent isn't in are auto-joined; private channels require the bot to have been invited first. For DMs use send_slack_dm_admin. Pass thread_ts to reply inside an existing thread.
The channel to post to — id, #name, mention link, or archive permalink.
The message body to post. Slack mrkdwn is supported.
Optional Slack message timestamp (ts) to reply inside an existing thread instead of posting at the top of the channel.
resolve_member_audience_admin
Admin only. Resolve a Foundations audience into Slack user IDs for the platform's send_slack_dm_admin tool. Audiences: all members, FIRs, founders, specific member emails/Slack IDs you already have, or a natural-language profile query like 'members who went to Vanderbilt' (evaluated against every active member profile). Use this FIRST when an admin wants to DM a group described by membership data, then pass the returned slack_user_ids to send_slack_dm_admin. Not needed when the admin already gave you explicit Slack IDs or emails.
send_email_admin
Admin only. Send an email now. Use this when the admin clearly wants the message sent without a review step. Recipients can come from all members, FIRs, founders, a specific list you already resolved, external email addresses, or a natural-language audience query like 'members who went to Vanderbilt'.
The email subject line
The email body content to send. HTML is allowed.
send_office_hours_reminder_admin
Admin only. Send an office-hours reminder DM now. Use this when the admin clearly wants the reminder sent without a review step. Recipients can be a list you already resolved or a natural-language audience query.
send_slack_dm_admin
Admin only. Send a Slack direct message AS the agent to one or more people — anyone in the Slack workspace, not just known community members. Provide recipients as Slack user ids (or <@U…> mentions) and/or email addresses (resolved against Slack workspace profiles, then known people). Use this when an admin clearly wants a DM delivered. For posting into a channel use send_slack_channel_message_admin instead. Large recipient lists are queued and fan out in the background at Slack's rate limit.
The message body to send. Slack mrkdwn is supported.
Slack user ids (U…/W…) or <@U…> mentions of the recipients.
Email addresses of recipients — resolved to Slack accounts via workspace profile lookup, then known-person bindings.
send_survey_admin
Admin only. Create and send a structured survey now (no review step). Provide a title, an ordered list of questions (text, single_choice, or yes_no), and optionally a `collection_topic` so Root can also passively capture answers when members mention them in normal conversation. Recipients are OPTIONAL when collection_topic is set — omit them to create a passive-only survey that nobody is DMed about; answers come solely from regular conversation captures while the survey is open.
Short title for the survey (used in lists and admin views).
Ordered list of questions. Most surveys have 1-3 questions. Use yes_no or single_choice when possible — they aggregate cleanly in stats.
list_costco_basket
List the current Costco shopping basket for an office (or both): pending member recommendations and approved items waiting to be ordered. Use when someone asks what's on the Costco/grocery list, whether their recommendation was added, or what's being ordered for the office.
recommend_costco_item
Recommend an item to add to an office's Costco shopping basket (groceries, snacks, drinks, kitchen/office supplies bought on Costco Same-Day). Use when a member asks for something to be stocked/ordered for the office, e.g. 'can we get more sparkling water', 'add paper towels to the Costco order', 'we're out of coffee in SF'. Root matches the request to the most likely product from past orders or a live Costco search, and admins review and submit the actual order. This does NOT place an order — it adds the item to the basket for admin review. If the user doesn't say which office, infer it from context (their usual office) or ask.
What the member wants, as specifically as they said it (brand, size, flavor if given)
Which office basket: 'sf' (142 Minna St) or 'seattle' (1605 Boylston Ave)
remove_costco_recommendation
Remove one of the current user's OWN pending Costco basket recommendations (e.g. 'never mind about the sparkling water'). Admins can remove any item. Use list_costco_basket first if the item isn't clearly identified.
The basket item id to remove
submit_costco_order_admin
ADMIN ONLY: Submit the office's Costco basket as a REAL order (spends real money on the designated card). Sends the approved basket items through checkout with the office's saved delivery address and the designated credit card. By default only APPROVED items are ordered — pending recommendations must be approved first on /admin/costco (or pass include_recommended=true to order everything in the basket). Use dry_run=true to walk the whole checkout without placing the order. Takes several minutes (a live browser automation).
Which office basket to order
sync_costco_catalog_admin
ADMIN ONLY: Refresh Root's Costco product catalog from the account's order history on sameday.costco.com (a browser automation, ~1-2 minutes). The catalog is what member recommendations are matched against. A scheduled job also does this daily — use this for an immediate refresh.
add_booking_guests
Add one or more guests to the calendar invite for an existing office hours booking the user owns, without moving the slot. Use this when a member says 'add my co-founder to my office hours', 'invite Jane to my session with Donald', or reports that Google Calendar will not let them edit the system-owned invite. This updates the Root-owned invite directly; never tell the member to edit or forward the invite themselves when this tool can do it. Existing attendees are preserved, member names/Slack IDs/emails are accepted, and non-member guests automatically get a day-long front-door code in the updated invite.
People to add. Each entry can be a Slack user ID, email address, or member name.
book_office_hours
Book an office hours time slot for the user. This is also how meetings at Foundations are booked. Provide a specific slot_id for direct booking, or mentor_name with time_preference to find a matching slot.
cancel_booking
Cancel an existing office hours booking. Provide a booking_id for direct cancellation, or use mentor_name/date/time to find the booking. Set cancel_all to true to cancel all bookings.
cancel_hosted_office_hours
Cancel an office-hours block that the email sender is hosting or has been explicitly authorized to manage as a copied delegate. Use this for requests like 'cancel my office hours on April 7' or 'please remove that hosted session'.
cancel_office_hours_waitlist
Stop your own office-hours slot availability alert. Use list_office_hours_waitlist first to find the subscription ID. Does not cancel an office-hours booking.
close_hosted_office_hours_slots
Close one or more unbooked slots in the resolved mentor's hosted office-hours block by email, including today's upcoming slots. Use for 'close the 10:30 slot', 'block out the middle slot', or 'cap my session at the existing bookings / stop further sign-ups'. Hosts and authorized delegates copied on that block can do this without admin escalation. Select exact slot_ids or Pacific start_times, or explicitly set all_unbooked=true to close all remaining open slots. Existing booked appointments are always preserved; a specific selection containing a booked slot fails without changing anything. The block's date, time, calendar invite and host door code stay unchanged even if no open slots remain. Use list_hosted_office_hours when the block or slot times are unclear. This does not cancel attendee bookings or the entire hosted session.
Hosted block ID from list_hosted_office_hours, preferred when known.
Pacific YYYY-MM-DD date to select a single hosted block if its ID is unknown.
Specific slot IDs to close. Use exactly one of slot_ids, start_times, or all_unbooked.
Exact slot start times in Pacific 24-hour HH:MM (or HH:MM:00), e.g. ["10:30"].
True only when the host explicitly asks to close all remaining open slots / stop further sign-ups. Keeps booked appointments.
coach_mentor_intro
Coach the member on a crisp, under-a-minute spoken introduction for a mentor office-hours session, using the CVFB method (Customer, Value Proposition, Feature Set, Business Model). Use when a member is preparing for office hours or a mentor meeting and wants help introducing themselves or pitching their company concisely — 'help me prep my intro for my session with TA', 'how should I introduce my company to a mentor?', 'polish this intro: ...' — or when they accept the intro-prep offer made after booking office hours. Root ALREADY pulls the member's linked directory company (name, description, website), their profile bio, and the CVFB answers they confirmed in earlier sessions, and pre-fills what it can from those — so call it even when the member has given you nothing yet; it returns a first-pass script with the inferred components flagged for confirmation plus the follow-up questions to refine it. Pass along whatever the member says in this conversation (a draft intro and/or individual CVFB answers) — those override everything on file. Present the returned intro script, the coaching feedback, and the follow-up questions to the member, and call the tool again with their answers to iterate. Do NOT use this for booking sessions (book_office_hours), updating a booking's topic (update_booking_topic), or general pitch-deck/fundraising advice unrelated to a mentor intro.
create_office_hours_block_admin
ADMIN ONLY: Create and schedule a hosted office-hours block ON BEHALF OF a designated host — an external mentor/advisor or a member — without the host having to email Root themselves. Use when an admin asks to set up office hours FOR someone else (e.g. 'create office hours for Kevin Penner on Aug 20 from 1 to 3pm'). The host is identified by host_email: an existing mentor profile is reused, an active member gets a host profile provisioned automatically, and a brand-new external mentor is created from host_name (plus optional title/bio/linkedin — always provide these when the admin shared them, so the host's listing reads well to members). The block is created in the office-hours schedule with bookable slots, the host receives the Google Calendar block invite at host_email, and non-member hosts of Seattle/SF sessions automatically get a day-of door code. Location defaults to Seattle (Huddle 1) unless an SF/offsite scheduling window covers the requested date — when one does, the tool refuses to assume and asks you to confirm the location with the admin (dates outside every open window schedule as Seattle without asking, since SF/offsite would be rejected for them anyway). Set location to 'sf' or 'offsite' when the admin asks for the SF office or a mentor-chosen San Francisco location (offsite blocks are always assumed to be in San Francisco) — those require an admin scheduling window (override_schedule_checks also bypasses the window and the location clarification). For offsite, pass offsite_location (address) and offsite_instructions whenever the admin or host shared arrival details — those instructions go on the calendar invite. For multiple hosts/dates, call this tool once per block. Do NOT use this for a member booking an attendee slot (book_office_hours) or for a host emailing Root about their own block (schedule_hosted_office_hours).
Email address of the person who will HOST the block. The calendar invite — and, for non-member hosts, the day-of door-code email — is sent here.
Office-hours date in YYYY-MM-DD format. Same-day scheduling is allowed as long as the block starts later than the current time.
Start time such as "13:00", "1pm", or "1:30 PM" (Pacific).
get_mentor_profile
View the office-hours host (mentor) profile of the mentor this email conversation is acting for: the name, LinkedIn, and bio members see next to their name on office-hours listings. Use when the host (or their delegate) asks what their bio says, how they appear to members, or wants to check the profile before changing it. Only ever returns the resolved mentor's own profile.
get_office_hours_registrants
List who has signed up for a hosted office-hours block the email sender is allowed to manage (as host or authorized delegate). Returns each registrant's name, email, company, booked slot time, and topic. Use this for questions like 'who is signed up for my office hours?' or 'is anyone booked for my session today?'. Pass office_hours_id from list_hosted_office_hours when known; otherwise a date (or nothing, if the sender has only one active block) also works.
list_hosted_office_hours
List upcoming hosted office-hours blocks the email sender is allowed to manage, whether they are the host or an authorized delegate copied on the calendar invite. Use this before cancelling or rescheduling when the specific hosted session is unclear, and when a host asks about setting up a new block — the result includes any open SF/offsite scheduling windows plus a location_intake_note (when the listing is filtered to a date, only windows covering that date are reported); when that note is present, your reply collecting block details MUST also ask where they want to host (Seattle Huddle 1, Foundations SF, or offsite in San Francisco).
list_office_hours
List upcoming or future available office hours sessions. Also use this when a user asks to book or schedule a meeting at Foundations — meetings are booked through office hours. Sessions may be in Seattle (Huddle 1), at the Foundations SF office, or offsite — each result includes location, and offsite sessions include any arrival instructions the host supplied (buzz code, floor, parking) so you can tell the member how to get there. Use the office filter when they ask specifically about SF or offsite. The result also includes currently open admin scheduling windows for SF and offsite so you can answer 'when can I book SF office hours?'. Use for booking availability only, not for historical or past-session questions. Do NOT use this when the user is offering times that they themselves could HOST as a mentor or advisor.
list_office_hours_waitlist
List your own office-hours availability subscriptions and their IDs, preferences, and active/notified/cancelled/expired status. Use before cancelling a subscription when its ID is unknown.
refer_office_hours_host
Hand office-hours hosting off to a COLLEAGUE of the resolved mentor, on the mentor's say-so. Mentors are invited to host 'or someone from your firm' — this is the sanctioned path when the email says someone else from the mentor's firm/team will host instead of (or in addition to, as their own separate block) the mentor: 'I can't that week, but my partner Jane (cc'd) will host', 'Adding Sam, who will run the session', 'Jane and I will each do a block'. It registers the colleague as an office-hours host — reusing their existing profile, provisioning a host profile for an active member, or creating a new external mentor profile from host_name (+ optional host_title/host_bio/host_linkedin; use the Cc display name or the body for the name) — records that the resolved mentor referred them, and, when the colleague's date and start time are already known, schedules THEIR hosted block in the same call under the same rules as schedule_hosted_office_hours (Seattle default, SF/offsite scheduling windows, location clarification when a window covers the date). Once referred, the colleague can email Root from their own address to schedule or manage their own block, so when their availability isn't known yet, call this tool WITHOUT date/start_time to register them, then reply asking THEM for a date, start/end time, and — when SF/offsite windows are open — where they'd like to host (address them directly when they're on the thread; otherwise ask the sender to loop them in). Authorization is enforced deterministically inside the tool: the resolved mentor themselves (or an admin acting as them) may refer anyone at any address; a DELEGATE sender (assistant, CC'd coordinator) may only refer themselves or a colleague when BOTH the sender and the colleague share the mentor's corporate email domain — otherwise the tool refuses and tells you to ask the mentor to confirm on the thread. A colleague who is merely JOINING the mentor's own session is NOT a hand-off — use schedule_hosted_office_hours with additional_calendar_emails for that. Never use this for members booking attendee slots, and never invent a colleague's email address — it must appear on the thread or in the body.
The colleague's email address, exactly as it appears on the thread (Cc/To) or in the body. Never guessed.
update_office_hours_calendar_invite
Refresh an already-issued office-hours booking invite with YOUR current member bio, company, primary email and LinkedIn, or an exact user-approved booking-specific mentee_bio. Use after a profile/email correction or when a member says existing invites show stale or oversharing mentee information. No admin escalation needed. Get booking ids from view_my_bookings; for multiple sessions call once per booking and report each result. Patches the existing Google event without moving the slot or changing the topic; preserves all existing invitees and RSVPs and includes the current primary email (does not remove old invitees). This does not edit your member profile: use update_member_profile/update_member_email first when requested, then refresh each invite. Never use this to edit another member’s booking or a hosted block.
reschedule_booking
Reschedule an existing office hours booking to a new time slot. Requires the original booking ID and the new slot ID. If the user is keeping the same slot and only changing the topic/agenda, prefer the dedicated `update_booking_topic` tool — but if `reschedule_booking` is called with the same slot and a new topic, it will perform the topic update automatically.
reschedule_hosted_office_hours
Move or update an office-hours block that the email sender is hosting or has been explicitly authorized to manage as a copied delegate. Use this for email requests like 'move my office hours to April 8 at 1pm'. Everyone already on the block's calendar invite (copied assistants/delegates) is carried over automatically and included on preserved and future booked slot invites. To add a colleague to an EXISTING hosted block without moving it, pass additional_calendar_emails with the block's existing date, start/end times, and slot duration; the block invite and every preserved booked slot invite are updated in place, keeping existing attendees and RSVPs. Check booked_slot_guest_delivery and report any failed slot updates instead of claiming all invites were updated. Can also update an offsite block's address or arrival instructions (offsite_location / offsite_instructions) with the same date and times.
New office-hours date. Prefer YYYY-MM-DD when possible. Same-day rescheduling is allowed as long as the block starts later than the current time.
New start time such as "13:00", "1pm", or "1:30 PM".
schedule_hosted_office_hours
Schedule an office-hours block where the RESOLVED MENTOR (see the CONTEXT block in the system prompt) is the host. Use this for email requests like 'can I do Wednesday from 9 to 11' or 'I'd like to host office hours next week' when the resolved mentor is the intended host. Any ACTIVE member emailing as themselves may host — a member who has never hosted before gets a host profile provisioned automatically, so never refuse a member for 'not being a mentor'. Location defaults to Seattle (Huddle 1) unless an SF/offsite scheduling window covers the requested date — when one does, the tool refuses to assume a location and returns a clarification asking where the block should be hosted; relay that question to the host (dates outside every open window schedule as Seattle without asking, since SF/offsite would be rejected for them anyway). When you are ASKING a host for their block details (date/time) before scheduling, include the location question in the same message unless the location is already known (list_hosted_office_hours reports whether windows are open). If they want SF office hours or to host at their own office, set location to 'sf' or 'offsite' (and offsite_location — offsite blocks are always assumed to be in San Francisco). When they host offsite, also pass offsite_instructions whenever they gave arrival/access details (buzz code, floor, parking, how to find them) — those go on the calendar invite, not just the address. SF and offsite blocks can overlap other mentors but MUST fall inside an admin-set date-range window — if the date is outside a window, tell them the currently open windows from the tool result. The host is ALWAYS the resolved mentor — never a third party named in the email body, never the actual sender when the actual sender is a delegate of a different person. This tool has NO on-behalf-of mode. If the mentor is handing hosting to a COLLEAGUE from their firm — 'I can't that week but my partner Jane (cc'd) will host', 'adding Sam who will run the session' — do NOT call this tool for them: use refer_office_hours_host, which registers the colleague as a host on the mentor's say-so and can schedule the colleague's block in the same call. A colleague who is merely JOINING the mentor's own session (co-hosting, sitting in) is NOT a hand-off: schedule the mentor's block here and put the colleague in additional_calendar_emails so they get the calendar invite (they can then help manage the block by email). additional_calendar_emails copies people onto the resolved mentor's OWN block and its booked slot invites, including future bookings; it does not transfer hosting and it cannot make a non-mentor the host. Do NOT use this to book the sender into someone else's existing slot.
Office-hours date. Prefer YYYY-MM-DD when possible. Same-day scheduling is allowed as long as the block starts later than the current time.
Start time such as "09:00", "9am", or "9:30 AM".
search_past_office_hours
Search previous office hours sessions that have already happened. By default this covers the ENTIRE community's history (all members), so set attendee_scope to 'me' when the user asks about their OWN past sessions as an attendee (e.g. 'what advisors have I met with?', 'who have I had office hours with?'), or to 'hosted' when an office-hours HOST/mentor asks about sessions they hosted (e.g. 'which entrepreneurs have I met with in my office hours?', 'who attended my past sessions?'). Supports historical lookups by mentor, date, time, or a natural-language query. Always include the user's original wording in query for broad, comparative, or follow-up questions like 'has Sam done office hours before?', 'what about Charles?', or 'who has done the most office hours?'.
list_office_hour_bookings
For office-hours HOSTS: list who has booked slots on the asking user's OWN hosted office-hours sessions — each attendee's name, email, company, LinkedIn, slot time, and topic — for a specific day or window. Use this when a host asks about their session roster, e.g. 'who was in my office hours today?', 'who's signed up for my session tomorrow?', 'do I have anyone booked next week?'. Covers today's sessions (even after they've ended), upcoming sessions, and specific past dates. Do NOT use this for sessions the user attends as a member (view_my_bookings covers those), and prefer search_past_office_hours with attendee_scope 'hosted' for broad history questions like 'which entrepreneurs have I met with over the years?'.
subscribe_office_hours_waitlist
Notify the requesting active member by Slack DM once an office-hours slot is available. Use for "tell me if a slot opens with Mike Smith", including fully booked sessions and cancellations from calendar declines, web/admin, or chat. Provide exactly ONE of office_hours_id, mentor_id, or mentor_name; omit or set the other two to null. For a general request for openings with a mentor, use mentor_id alone, or mentor_name alone if no ID is known. Use office_hours_id alone only when the user explicitly requests that session/date; finding an existing session does not narrow a general mentor request to that session. Optional Pacific dates and time bounds filter matching slots. One-time notification only: does not reserve or auto-book. Repeating an active subscription updates its preferences. Prefer this to create_action_alert for slot availability. Members only; always alerts yourself.
update_hosted_office_hours_title
Change the calendar invite title for an existing office-hours block hosted by the resolved mentor, including requests to use their firm/company name instead of their personal name. Hosts and authorized delegates copied on that block can rename it by email. Updates the existing invite in place, preserving its date, time, location, guests and RSVPs; does not rename the mentor profile or individual attendee bookings. The title persists through reschedules and resends. Use list_hosted_office_hours to identify the block if needed. Pass null to restore the default mentor-name title. No admin escalation is needed.
Exact invite title, 1–200 characters; null restores the default title.
update_mentor_profile
Update the office-hours host (mentor) profile of the mentor this email conversation is acting for — the bio and/or LinkedIn URL members see next to their name on office-hours listings. Use when the host (or their delegate) asks to change, rewrite, or add their bio, or shares bio text / a LinkedIn URL. ONLY pass text the host actually provided or explicitly approved — never invent a bio. If the host is also a Foundations member, their member profile bio is updated to match, so they have one bio everywhere.
The new bio, exactly as the host provided or approved it (max 1500 characters). Replaces the current bio. Pass null when only the LinkedIn URL is changing.
The host's LinkedIn profile URL. Pass null when only the bio is changing.
update_booking_topic
Update only the topic/agenda for an existing office hours booking the user owns, without moving the time slot. Use this when the member wants to change what they want to talk about with the mentor (e.g. 'change my topic with Bill to fundraising strategy', 'update the agenda for my Maria meeting'). The Google Calendar event keeps the same time but its title and description are refreshed in place so the mentor sees the new topic.
New topic or agenda for the office hours session. Required. Must be a non-empty string describing what the member wants to discuss.
view_my_bookings
View all current office hours bookings for the user. Each booking includes location (Seattle Huddle 1, Foundations SF, or the offsite address) and, for offsite sessions, any arrival instructions the host put on the calendar invite.
search_sent_email_logs
Search previously sent emails in email_logs using metadata only. Use this when someone asks what emails were sent, whether a message went out, who it went to, when it was sent, or what the subject/status was. NEVER use this tool to disclose, quote, paraphrase, or summarize email body content. ACCESS: non-admin members can only see emails addressed to themselves — recipient_email is automatically forced to the caller's own email and any other value is rejected. Admins can search globally across all recipients.
analyze_space
Analyze what is happening in the Foundations physical spaces using live camera feeds. Covers BOTH offices — Seattle (1605 Boylston Ave) and San Francisco (142 Minna St); camera names are suffixed with '(Seattle)' or '(SF)'. Both offices ALWAYS have cameras installed — if the result reports zero cameras for an office (see camera_system_status), that office's camera system is down, so say its cameras appear to be offline rather than implying the office has none. Use this when a user wants a live REMOTE look at the space — what's happening right now, whether someone is at the front desk, how busy it is — i.e. they clearly want a camera view (they mention cameras, feeds, snapshots, or checking on the space from elsewhere). Do NOT use camera tools when the user is asking to visit, find, or get into a room in person ('can I see the speakeasy', 'where's the studio', 'can I check out the 3rd floor') — especially when they are already AT the office (e.g. they recently badged in or their message implies they're on-site). Those questions want the room's location, what it is, or whether they can use it — answer from the knowledge base or what you know, and offer a camera view only if they explicitly ask for one. Sending surveillance snapshots to someone who wanted directions is a bad experience for them AND for anyone who happens to be on camera. If the user mentions a specific office, include that office in user_request so the right cameras are selected; if they don't mention an office but the context makes clear which one they mean, include it too — don't share the other office's cameras (and the people visible on them) unprompted. This tool can confirm visible occupancy, activity, clothing, and approximate location, but it does NOT identify specific people, members, or company affiliation. If the user wants to know WHO is visible, or whether a named person is on camera, use identify_people_in_space instead — it compares the cameras against member profile photos. If the user provided a clear visual description (clothing, build), this tool can say whether someone matching that description appears visible, but only as a description match, not confirmed identity. The camera images will be automatically shared with the user after analysis — do NOT try to embed images in your response. If the user asked for a camera view (e.g. 'show me the cameras'), use ONLY this tool — do not also call get_space_images, since this tool already shares the same images.
The question to answer about the physical space
request_human_intervention
Log a tracked request for the community team when the user asks for something that needs a HUMAN to follow through — a physical/offline task, real-world coordination, or anything no other tool handles that the team must act on. The team sees it on their dashboard and the user is notified when it's done. NEVER say you have 'noted' or 'logged' something for the team without actually calling this. NOT for digital communications (messages, emails, reminders) — and for reporting a problem or passing a message to an admin, use escalate_to_admin instead.
Short, specific summary of what the team needs to do
Everything the team needs to act: context, quantities, locations, deadlines, exact user wording where useful
cancel_human_intervention
Cancel/withdraw a request the user previously logged for the team, when they ask to remove, delete, or retract it. If the specific request is unclear, list their requests first.
The id of the request to cancel (from list_my_human_interventions)
get_space_images
Get live camera snapshot images from the Foundations physical spaces WITHOUT analyzing them. Covers BOTH offices — Seattle and San Francisco; camera names are suffixed with '(Seattle)' or '(SF)'. Both offices ALWAYS have cameras installed — if the result reports zero cameras for an office (see camera_system_status), that office's camera system is down, so say its cameras appear to be offline rather than implying the office has none. Only for users who clearly want a live camera view of the space from elsewhere. Do NOT use this when the user is asking to visit, find, or get into a room in person ('can I see the speakeasy') — especially when they are already at the office; answer with the room's location or details instead. If the user mentions a specific office, include that office in user_request so only its cameras are returned; if the context makes their office clear, include it too rather than sharing the other office's cameras unprompted. Use this ONLY when a user wants to see camera images and you are NOT also going to call analyze_space — for example, a pure 'show me the cameras' request where no question about the space needs answering. If you also need to answer a question about what's happening in the space, call analyze_space INSTEAD; analyze_space already shares the same images, so calling both is redundant and uploads duplicate images. The images will be automatically uploaded and shared with the user — do NOT try to embed them in your text response. Just mention which cameras you're sharing.
get_survey
Look up a single survey by id, including its title, description, collection topic, status, and full question list. Use this when you have a survey id (for example from list_open_surveys or from another tool) and need to know the questions before submitting answers.
identify_people_in_space
Try to identify WHO is visible in the Foundations spaces by comparing live camera snapshots against member Slack profile photos. Use this when a user asks who is in the space, who is at the front desk, or whether a SPECIFIC named person is visible on camera right now. Candidates come from members who badged in recently plus any names the user mentioned, so pass person_names whenever the user asks about specific people. Matches are visual suggestions, never certainties — always relay them with hedged language ('appears to be', 'may be') and the stated confidence, and never as confirmed identity. For 'is X in the office' questions where seeing them on camera isn't required, query_door_access_events (badge data) is more reliable — use this tool when the user wants a camera-based check or asks who is visibly present. The camera images are automatically shared with the user after analysis — do not also call analyze_space or get_space_images for the same request.
The user's full original message. Used to select relevant cameras (e.g. a specific office) and to focus the comparison.
list_my_human_interventions
List the requests this user has logged for the community team (open and recently closed). Use when they ask what requests they have pending, whether something was already logged, or the status of a previous request.
Also include resolved/dismissed/cancelled requests (default false)
list_open_surveys
List the open surveys this user can respond to right now, including the questions on each survey, which questions the user has already answered, and the survey's collection topic if it has one. Use this when the user asks about open surveys, asks to fill one out, or you want to verify the question list before submitting answers.
escalate_to_admin
Escalate to a human admin when the user needs something you cannot do with your tools, asks you to pass a message to the team, or reports a problem you cannot resolve. Always available — never dead-end a user. Your reply to the user must also explain WHY you escalated (the substance of escalation_reason), not just confirm the hand-off.
notify_member
Privately notify people at Foundations by Slack DM that this non-member visitor is here or trying to reach them. Covers members AND company employees (non-members who work at a member company in the building). Use when a visitor says things like 'I'm here for Aviel', 'can you let Jane know I arrived?', 'please tell Sam I'm downstairs', 'I'm here to see Sam from Acme' — or when they reference a member COMPANY instead of a person ('I'm a meeting guest of AZX', 'here for my meeting with Acme'). Pass the human-readable name the sender supplied as person_name, and/or the company they mentioned as company_name: a company alongside a person picks the right person; a company alone (or a person who can't be matched) has the company researched in the directory internally and its linked members and employees notified instead. All lookups happen internally and never return member/employee/company profile, email, Slack ID, or directory data. When a person name matches more than one person, delivery is still attempted to every plausible match (each recipient is told the match was ambiguous). The DM faithfully includes the inbound sender, subject when available, and latest message, labels the sender as unverified, and escapes Slack mentions/markup. This does NOT grant door access, unlock a door, or confirm that anyone is present. At most one notification attempt is allowed per inbound public message.
query_door_access_events
Answer questions about office access using door event data. Use this for access history, door/badge activity, who entered, busiest days, busiest doors, visit counts, access trends, and office access patterns over time. Also use this when a user asks who from a specific company or member set is likely in the office now and identity matters — camera images can show occupancy, but door data is the grounded source for who badged in. Also use this when a member is trying to recall or identify someone they met in person but can't name ('I met someone at the office but forgot their name') — cross-reference the asker's own badge-in days with who else badged in at the same times to build a grounded candidate list of people they could actually have crossed paths with, then narrow it with directory tools. This tool can internally generate custom read-only SQL for grounded analytics. Company and people lookups include both members and company employees, labeled separately. For today's activity, current presence, or the latest badge-in, call this tool again in the CURRENT turn even if an earlier reply answered the same question: door events change throughout the day. IMPORTANT: Per-person door-access statistics (days present, visit counts, attendance frequency, rankings) may only be attributed to people whose name appears explicitly in the returned `rows`. Do NOT infer or invent attendance stats for anyone not in the result rows, even if they were surfaced by another tool like search_members, and even if the result is truncated.
The full user question about office access, door events, member access history, or access trends. First-person questions ('how often have I been in?') can be passed verbatim — the asker's identity is attached automatically.
report_root_mistake
Notify the team so they can investigate WHY a mistake happened — a bad prompt, a stale record, or a misread. This does NOT update knowledge pages, recommendations, reviews, or any other stored data. If write/update/delete tools can apply the user's correction (extracted knowledge, a provider recommendation/review, a preference), you MUST call those first and only use this afterwards. Do NOT treat a successful report as the fix, and do not tell the user the underlying record was updated unless a write tool succeeded. Still use this whenever a user says the assistant is wrong, corrects a factual error, or complains that an answer/booking/message was incorrect — after applying any correction you can apply yourself. Do NOT use this for feature requests or missing capabilities (those are handled elsewhere), for normal clarifying follow-ups where the assistant simply needs more detail, or for the user being rude without pointing to an actual error. Still apologize and correct yourself in your reply to the user.
What the user said was wrong, in their own framing — the specific error or correction they raised (e.g. 'the mayor's name is Lurie, not Laurie').
The assistant's own concise summary of what went wrong and, if you can tell, the likely cause (e.g. a phonetic misspelling that originated in an admin-provided draft, stale data, a wrong tool result, or a misread of the request). Be specific and honest.
The correct information or outcome, if it is known — what the answer/action should have been.
submit_feature_request
Capture an EXPLICIT feature request for the Foundations team's feature pipeline. Requests are batched per conversation: shortly after the conversation goes quiet (~5 minutes), everything requested in it is consolidated into ONE plan, the team is notified with full context, and (when configured) a coding agent drafts a pull request implementing it — so if the user keeps refining or extending the idea, call this again with the new details and the requests merge into a single plan. Use this when the user explicitly asks Root to BUILD, ADD, or SUPPORT a new capability, tool, integration, or behavior it doesn't have today — e.g. 'build an admin override for that', 'you should be able to send calendar invites to guests', 'add a tool that does X'. Do NOT use it for: requests your existing tools can already handle, bug reports about existing tools (report_root_mistake), general messages to the team (escalate_to_admin), or vague wishes the user hasn't actually asked to be built — when unsure whether they want it built, ask first. You do not need this for ordinary failed requests: a background classifier already detects those gaps automatically after the exchange. In your reply, be honest about what happened: the request was CAPTURED and will be forwarded to the team as one consolidated plan shortly after this conversation wraps up — do NOT claim the team has already been notified or that a PR is already being drafted, and the capability is NOT live until the team reviews and ships it.
A clear 1-3 sentence summary of the capability the user wants built, grounded in what they actually asked for and the conversation context (e.g. 'An admin-only override so admins can delete another member's author-scoped knowledge entries').
submit_survey_response
Submit one or more answers to an open survey on behalf of the current user. Use this both (a) when the user is explicitly answering a survey you sent them, and (b) when the user's natural conversation already answered a question on an OPEN survey that has a `collection_topic` — for example, if a survey is collecting RSVPs for the May 30 demo night and the user mentions in passing that they'll be there with a guest, capture that information here without asking again. Set `source` to `agent_passive` for those opportunistic captures and `agent_active` when the user is directly responding to the survey. You may submit a partial answer (one question now, more later) — the response is upserted per (survey, member) and only marked complete once every required question has been answered.
The id of the survey being answered.
One entry per question being answered in this turn.
search_all_conversations_admin
Admin only. Search across ALL members' past conversations with Root at once — every Slack, email, and API exchange in the database, not scoped to any one member. Use this when an admin wants to find who talked to Root about something ('who asked about credits recently?', 'has anyone complained about the printer?') or to locate a conversation without knowing which member it was. Free-text query matches message content, subjects, and member names/emails; filterable by channel and date range. Returns matching exchanges newest first, each with the associated member's name and email. When the admin already knows WHICH member they're interested in, prefer search_conversation_history with member_email instead.
search_conversation_history
Search the user's own past conversations with Root across Slack, email, and the API. Use this when someone asks what they previously discussed with Root ('what did we talk about last week?', 'what did I ask you about X?', 'did I already request that?'). Returns past exchanges (their message + Root's reply) newest first, filterable by free-text query, channel, and date range. For EXISTENCE questions ('did I already ask/request X?'), ALWAYS pass a query — without one you only see the newest page and cannot conclude something was never discussed. ACCESS: non-admin members only see their OWN conversations. Admins can pass member_email to look up another member's history.
find_channel_for_community_post
Research which PUBLIC Slack channel is the best place to start a community conversation about a topic. Returns ranked candidate channels with evidence: where the topic has actually been discussed (from ingested Slack history), channel name/topic/purpose matches, member counts, and recent activity. Use this when a user in a DM agrees they'd like you to bring their question or topic to the broader community — research first, then propose ONE channel and a full draft message, and only post via start_community_conversation after the user explicitly confirms both.
The topic or question to take to the community, e.g. 'hiring a fractional CFO' or 'experiences with SOC 2 auditors'. This must be the topic the user MOST RECENTLY discussed with you — when they say 'post it', they mean the question you just answered, not an earlier topic from higher up in the conversation.
Max candidate channels to return (default 8).
read_web_page
Fetch and read the text content of specific public web pages by URL — published Google Sheets/Docs, blog posts, member sites, shared resources. Use this whenever the user asks about the CONTENTS of a link ('who's in that spreadsheet?', 'summarize that article'): first locate the exact URL (from the current message, thread history, or a search_slack_messages result), then read it with this tool. Only works for publicly accessible pages — it cannot log in, so private documents fail or return a login page; say so if that happens. This is not a web search: for open-ended news or current-events questions use search_current_events instead.
Up to 3 full http(s) URLs to read, copied exactly from where they were shared
set_slack_mention_preference
Control whether Root @-mentions THIS USER in Slack when attributing their advice, quoting them, or cc'ing them into a thread. This is an account-level setting (default ON) that applies in EVERY conversation — not only chats with this user — so 'stop tagging me' actually stops the pings when someone else asks about a topic they commented on. Use this — NOT remember_user_preference — when the user asks to stop being tagged/pinged/@-mentioned, or to turn tagging back on. The setting is all-or-nothing (not per-topic): Root will still use their plain name. Does not affect other people mentioning them by hand.
'off' to never @-mention this member (use their plain name instead); 'on' to restore the default and ping them when attributing their advice.
start_community_conversation
Post a message into a PUBLIC Slack channel on behalf of the user you are DMing with, to start a community conversation about their question or topic. Only use this after (1) the user agreed they want the conversation taken to the community, (2) you settled on a public channel (via find_channel_for_community_post, or channel evidence already in this conversation's tool results), and (3) the user explicitly confirmed the exact channel, the full message text, and who will be cc'd, in this conversation. The post opens by mentioning the requesting user, and the members whose advice/expertise prompted the question can be cc'd so they're pinged into the thread. Never use this for announcements, admin broadcasts, private channels, or messages the user has not confirmed verbatim — for admin posting use send_slack_channel_message_admin.
The public channel to post in — id (C0123ABCD), #name, or mention link. Should come from find_channel_for_community_post results or the user's own choice.
The full message to post, exactly as the user confirmed it. Slack mrkdwn is supported. Write it in YOUR OWN voice on the user's behalf — open by naming the user with their REAL Slack id mention (<@U…>, from requester_slack_user_id on find_channel_for_community_post or another tool result) and what they're looking into, then invite the community's input (e.g. "<@U123> is researching X and would love recommendations — …"). NEVER put a display name inside <@…>, and NEVER write the message in first person as if the user authored it.
Slack user ids (U…/W…) or <@U…> mentions of the members whose advice, comments, or expertise prompted this conversation — typically the people you recommended to the user earlier (e.g. from who_knows or Slack message search). They are cc'd at the end of the post so they get pinged into the thread and can weigh in. CRITICAL mention grounding: only include an id that a tool result in THIS conversation attached to that exact person — never guess or borrow ids.
Must be true, and may only be set to true after the user explicitly confirmed the exact channel, message text, and cc list in this conversation.
DM @Root in the Foundations Slack workspace, email root@fndtns.org, or connect your own AI agent through the member API and MCP server. No commands to learn — just say what you need.