Native Tools
Tools are Vercel AI SDK tool() definitions with Zod schemas for parameter validation. They are factory functions that accept a ToolContext and return the tool definition — this allows tools to be dynamically composed per-request based on the user's connected integrations.
Tool Context
Every tool receives this context:
interface ToolContext {
userId: string;
agentId: string;
agentEmail?: string;
integrations: {
google?: string; // decrypted OAuth access token
notion?: string;
slack?: string;
github?: string;
};
}
Tool Registry
buildToolset(ctx) in tools/index.ts composes the toolset dynamically:
- Always available:
knowledge_search,knowledge_store,manage_todos - If
BRAVE_API_KEYset:web_search - If
FIRECRAWL_API_KEYset:web_scrape - If agent has email +
RESEND_API_KEY:send_email,read_inbox - If Google OAuth connected:
read_emails,read_calendar,create_event - If Notion OAuth connected:
notion_read,notion_write
This means an agent whose user hasn't connected Google won't see email/calendar tools at all — no "tool not available" errors, just clean scoping.
Tool Reference
knowledge_search
Search the user's personal knowledge base using Pinecone vector similarity.
Parameters: query (string), limit (number, default 5)
Backing: searchUserKnowledge() from knowledge.ts
knowledge_store
Save a new piece of knowledge about the user.
Parameters: content (string), type (fact/preference/knowledge/note), importance (0-1)
Backing: storeUserKnowledge() from knowledge.ts
manage_todos
List, create, complete, or update todos.
Parameters: action (list/create/complete/update), title, todoId, description, priority, dueDate
Backing: Direct Supabase CRUD on todos table
web_search
Search the web for information via Brave Search API.
Parameters: query (string)
Returns: Top 5 results with title, URL, and description
web_scrape
Extract content from any URL as markdown.
Parameters: url (string)
Backing: scrapeUrl() from scraper.ts via Firecrawl API
send_email
Send an email on the agent's behalf via Mailgun.
Parameters: to (email), subject (string), body (string)
Backing: sendAgentEmail() from agent-mail.ts
read_emails
Read the user's Gmail inbox.
Parameters: query (Gmail search query, optional), maxResults (number, max 10)
Backing: Gmail API with automatic OAuth token refresh
read_calendar
Read upcoming events from Google Calendar.
Parameters: days (number, default 7)
Backing: Google Calendar API
create_event
Create a new Google Calendar event.
Parameters: summary, startTime (ISO), endTime (ISO), description, location
Backing: Google Calendar API
notion_read
List available Notion pages or read a specific page's content.
Parameters: action (list/read), pageId, query
Backing: listAccessiblePages(), readNotionPage() from notion.ts
notion_write
Create a new page or append content to an existing page in Notion.
Parameters: action (create/append), title, parentPageId, pageId, content
Backing: createNotionPage(), appendToNotionPage() from notion.ts
browser_navigate
Navigate to a URL in the browser. Returns the page content. Use this for JavaScript-rendered pages, dashboards, or any site that needs a real browser.
Parameters: url (string)
Backing: Stagehand + Browserbase cloud browser. Sessions persist so agents keep login state.
browser_act
Perform an action in the browser using natural language — click buttons, fill forms, scroll, select options. Stagehand translates natural language into DOM interactions.
Parameters: action (string — e.g. "click the Sign In button", "type hello@example.com into the email field")
Backing: stagehand.act() — AI-native DOM interaction
browser_extract
Extract specific information from the current browser page using natural language.
Parameters: instruction (string — e.g. "get the product name and price", "list all meeting times")
Backing: stagehand.extract() — AI-powered data extraction
browser_observe
Observe the current page — see what elements are visible and what actions are possible. Use this to understand a page before acting on it.
Parameters: instruction (string, optional)
Backing: stagehand.observe() — returns list of interactive elements
Adding New Tools
- Create a new file in
web/lib/agent-runtime/tools/(e.g.slack.ts) - Export a factory function that takes
ToolContextand returns atool()definition - Register it in
tools/index.tsinsidebuildToolset()with the appropriate condition - The tool will automatically appear in agents' available tools when the condition is met