Built-in Tools
Reference for the 26 built-in tools that ship with @cogitator-ai/core, the environment variables they read, and the tool factories next to them.
Overview
Cogitator ships with 26 built-in tools covering math, data processing, the file system, network, databases, email and GitHub. Every tool has a Zod schema (the runtime validates the model's arguments against it) and returns structured results; most failures come back as { error } data the model can read instead of a thrown exception.
import { Agent, builtinTools, calculator, fileRead, httpRequest } from '@cogitator-ai/core';
const assistant = new Agent({
name: 'assistant',
model: 'openai/gpt-6.1-sol',
instructions: 'You are a helpful assistant.',
tools: [calculator, fileRead, httpRequest],
});
const everything = new Agent({
name: 'power-user',
model: 'openai/gpt-6.1-sol',
instructions: 'You are a helpful assistant.',
tools: builtinTools,
});builtinTools is a Tool[], so pass it as tools directly or spread it next to your own tools. Prefer picking the tools an agent needs: builtinTools includes exec, file_delete and send_email.
| Export | Tool name | Export | Tool name |
|---|---|---|---|
calculator | calculator | fileRead | file_read |
datetime | datetime | fileWrite | file_write |
uuid | uuid | fileList | file_list |
randomNumber | random_number | fileExists | file_exists |
randomString | random_string | fileDelete | file_delete |
hash | hash | httpRequest | http_request |
base64Encode | base64_encode | exec | exec |
base64Decode | base64_decode | webSearch | web_search |
sleep | sleep | webScrape | web_scrape |
jsonParse | json_parse | sqlQuery | sql_query |
jsonStringify | json_stringify | vectorSearch | vector_search |
regexMatch | regex_match | sendEmail | send_email |
regexReplace | regex_replace | githubApi | github_api |
Environment Variables
| Variable | Read by |
|---|---|
TAVILY_API_KEY, BRAVE_API_KEY, SERPER_API_KEY | web_search (first one set wins when provider is omitted) |
DATABASE_URL | sql_query, vector_search when no connectionString is passed |
OPENAI_API_KEY, OLLAMA_BASE_URL / OLLAMA_URL / OLLAMA_HOST, GOOGLE_API_KEY | vector_search embeddings (auto-detected in that order) |
RESEND_API_KEY, RESEND_FROM_EMAIL | send_email via Resend |
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM | send_email via SMTP |
GITHUB_TOKEN | github_api |
Variables are read on each call. On runtimes without process.env (Cloudflare Workers without nodejs_compat, Deno without --allow-env) they count as unset.
Optional Packages
| Package | Needed by |
|---|---|
pg | sql_query on PostgreSQL, vector_search |
better-sqlite3 | sql_query on SQLite |
nodemailer | send_email via SMTP |
They are optional peer dependencies of @cogitator-ai/core; a tool that needs a missing one returns an error telling you what to install.
Math & Utilities
calculator
Evaluates mathematical expressions without eval. Supports +, -, *, /, ^ (power), parentheses, and functions: sqrt, sin, cos, tan, log, abs, round, floor, ceil. Constants: pi, e.
| Parameter | Type | Description |
|---|---|---|
expression | string | Math expression, e.g. "2 + 3 * 4" |
uuid
Generates UUID v4 identifiers with crypto.randomUUID.
| Parameter | Type | Description |
|---|---|---|
count | number | Number of UUIDs to generate (1 - 100, default 1) |
random_number
Generates a random number within a range.
| Parameter | Type | Description |
|---|---|---|
min | number | Minimum value (default: 0) |
max | number | Maximum value (default: 1) |
integer | boolean | Return integer (default: false) |
random_string
Generates a cryptographically secure random string using crypto.randomBytes.
| Parameter | Type | Description |
|---|---|---|
length | number | String length (1 - 1000) |
charset | enum | alphanumeric | alpha | numeric | hex (default: alphanumeric) |
hash
Computes cryptographic hashes.
| Parameter | Type | Description |
|---|---|---|
data | string | String to hash |
algorithm | enum | md5 | sha1 | sha256 | sha512 (default: sha256) |
encoding | enum | hex | base64 (default: hex) |
sleep
Pauses execution for a specified duration. Maximum 60 seconds.
| Parameter | Type | Description |
|---|---|---|
ms | number | Milliseconds to sleep (0 - 60000) |
datetime
Returns the current date and time in various formats and timezones.
| Parameter | Type | Description |
|---|---|---|
timezone | string | IANA timezone, e.g. "America/New_York" (default: system zone) |
format | enum | iso | unix | readable | date | time (default: iso) |
Data Processing
json_parse
Parses a JSON string into an object. Returns { result, valid: true } on success, { error, valid: false } on failure.
| Parameter | Type | Description |
|---|---|---|
json | string | JSON string to parse |
json_stringify
Converts a value to a JSON string with optional pretty-printing.
| Parameter | Type | Description |
|---|---|---|
data | unknown | Data to serialize |
pretty | boolean | Enable indentation (default: false) |
indent | number | Spaces for indent (0 - 8, default 2) |
base64_encode / base64_decode
Encode strings to Base64 or decode Base64 back to plain text. Both support the URL-safe variant.
| Parameter | Type | Description |
|---|---|---|
data | string | Input string |
urlSafe | boolean | URL-safe Base64 variant (default: false) |
regex_match
Finds matches of a regular expression in text, returning match strings, indices, and named groups.
| Parameter | Type | Description |
|---|---|---|
text | string | Text to search |
pattern | string | Regular expression pattern |
flags | string | Regex flags (default: "g") |
regex_replace
Replaces regex matches in text. Supports $1, $2 capture group references.
| Parameter | Type | Description |
|---|---|---|
text | string | Input text |
pattern | string | Regex pattern |
replacement | string | Replacement string |
flags | string | Regex flags (default: "g") |
Both regex tools reject texts over 1,000,000 characters and stop matching after 5 seconds. They run on the host event loop; for untrusted patterns prefer the WASM regex tool, which runs in a worker that the timeout terminates.
File System
file_write and file_delete declare sideEffects: ['filesystem']. None of the file tools restricts paths — they act with the permissions of your process, so give them only to agents you trust or put the agent behind approvals.
file_read
Reads file contents. Use base64 encoding for binary files.
| Parameter | Type | Description |
|---|---|---|
path | string | Path to the file |
encoding | enum | utf-8 | base64 (default: utf-8) |
file_write
Writes content to a file. Creates parent directories by default.
| Parameter | Type | Description |
|---|---|---|
path | string | File path |
content | string | Content to write |
encoding | enum | utf-8 | base64 (default: utf-8) |
createDirs | boolean | Create parent dirs (default: true) |
file_list
Lists directory contents with file names, paths, types, and sizes.
| Parameter | Type | Description |
|---|---|---|
path | string | Directory path |
recursive | boolean | Recurse into subdirectories (default: false) |
includeHidden | boolean | Include dotfiles (default: false) |
file_exists
Checks if a file or directory exists and returns its type and size.
| Parameter | Type | Description |
|---|---|---|
path | string | Path to check |
file_delete
Deletes a file or directory. Use recursive: true for non-empty directories.
| Parameter | Type | Description |
|---|---|---|
path | string | Path to delete |
recursive | boolean | Delete contents recursively (default: false) |
Network & Web
http_request
Makes HTTP requests with custom headers, body, and timeout. Response bodies longer than 100,000 characters are truncated (truncated: true).
| Parameter | Type | Description |
|---|---|---|
url | string | Request URL |
method | enum | GET | POST | PUT | PATCH | DELETE | HEAD | OPTIONS (default: GET) |
headers | Record<string, string> | Request headers |
body | string | Request body (for POST/PUT/PATCH) |
timeout | number | Timeout in ms (1000 - 60000, default: 30000) |
web_search
Searches the web via Tavily, Brave Search, or Serper. Without provider it uses the first of TAVILY_API_KEY, BRAVE_API_KEY, SERPER_API_KEY that is set.
| Parameter | Type | Description |
|---|---|---|
query | string | Search query |
provider | enum | tavily | brave | serper |
maxResults | number | Max results (1 - 20, default: 5) |
page | number | Page of results (1 - 10, Brave and Serper only) |
topic | enum | general | news (default: general) |
recency | enum | day | week | month | year: only results from that period |
dateRange | { from: string, to?: string } | Only results published within these days (YYYY-MM-DD, to defaults to today) |
includeDomains | string[] | Search only these domains, e.g. ["reuters.com"] |
excludeDomains | string[] | Leave out results from these domains |
country | string | Favour results from a country, ISO 3166-1 alpha-2 (us, de) |
language | string | Favour results in a language, ISO 639-1 (en, pt-br) |
searchDepth | enum | ultra-fast | fast | basic | advanced (Tavily only) |
includeAnswer | boolean | Include AI summary (Tavily only) |
includeRawContent | boolean | Full page content as markdown in each result (Tavily only) |
The filters work on every provider, each through its own parameters: Tavily's topic, time_range, start_date, include_domains, country and language, the news endpoints, freshness, country and search_lang of Brave, and the news endpoint, tbs, gl and hl of Serper. Domain filters become site: operators for Brave and Serper. A filter a provider cannot apply comes back as an error instead of being dropped: Tavily has no result pages, and it favours a country only in general searches.
Results carry publishedAt (ISO 8601) when the provider reports a date, Serper's relative dates ("3 hours ago") resolved at the time of the search, source for Serper news, and content with includeRawContent.
createWebSearchTool({ provider, apiKeys }) builds the same tool with a default provider and keys passed in code instead of the environment:
import { createWebSearchTool } from '@cogitator-ai/core';
const search = createWebSearchTool({ provider: 'tavily', apiKeys: { tavily: config.tavilyKey } });web_scrape
Fetches an HTML page and extracts its content as text, markdown or raw HTML, optionally limited to a CSS selector, with link and image collection.
| Parameter | Type | Description |
|---|---|---|
url | string | URL to scrape |
selector | string | CSS selector to extract (e.g. "article") |
format | enum | text | markdown | html (default: text) |
maxLength | number | Max content length (100 - 100000, default: 50000) |
timeout | number | Request timeout in ms (1000 - 60000, default: 30000) |
includeLinks | boolean | Extract links (default: false) |
includeImages | boolean | Extract image URLs (default: false) |
Non-HTML responses return an error.
Database & Search
sql_query
Executes SQL queries against PostgreSQL (pg) or SQLite (better-sqlite3). Supports parameterized queries and is read-only by default.
| Parameter | Type | Description |
|---|---|---|
query | string | SQL query |
database | enum | postgres | sqlite (auto-detected from the connection string) |
connectionString | string | Postgres URL or SQLite file path (defaults to DATABASE_URL) |
params | unknown[] | Parameterized query values |
maxRows | number | Max rows returned (1 - 1000, default: 100) |
readOnly | boolean | Only allow read queries (default: true) |
In read-only mode the query must be a single SELECT/WITH/SHOW/DESCRIBE/EXPLAIN statement. On PostgreSQL it additionally runs inside a BEGIN TRANSACTION READ ONLY block that is always rolled back, so side-effecting functions (for example nextval()) are rejected by the database itself; SQLite databases are opened with readonly: true. With readOnly: false, statements that return no rows (INSERT, UPDATE, DELETE) return rows: [] and the number of affected rows in rowCount.
vector_search
Performs semantic similarity search with pgvector: embeds the query via OpenAI, Ollama, or Google, then finds similar rows in PostgreSQL.
| Parameter | Type | Description |
|---|---|---|
query | string | Search query (converted to embedding) |
collection | string | Table name (default: "documents") |
topK | number | Number of results (1 - 100, default: 5) |
threshold | number | Minimum similarity 0 - 1 (default: 0.7) |
filter | Record | Metadata filter as key-value pairs |
embeddingProvider | enum | openai | ollama | google |
embeddingModel | string | Embedding model override |
connectionString | string | PostgreSQL URL (defaults to DATABASE_URL) |
The provider is auto-detected from OPENAI_API_KEY, then OLLAMA_BASE_URL/OLLAMA_URL/OLLAMA_HOST (the first one set is also the Ollama URL; default http://localhost:11434), then GOOGLE_API_KEY. Default models: text-embedding-3-small (OpenAI), nomic-embed-text (Ollama), gemini-embedding-001 (Google). The embedding dimension must match your pgvector column.
Communication & Dev
send_email
Sends email via the Resend API or SMTP (nodemailer). Declares sideEffects: ['network', 'external'].
| Parameter | Type | Description |
|---|---|---|
to | string | string[] | Recipient(s) |
subject | string | Email subject |
body | string | Email body (plain text or HTML) |
html | boolean | Treat body as HTML (default: false) |
from | string | Sender (default: RESEND_FROM_EMAIL / SMTP_FROM) |
replyTo | string | Reply-to address |
cc | string | string[] | CC recipients |
bcc | string | string[] | BCC recipients |
provider | enum | resend | smtp (auto-detected) |
Auto-detection picks Resend when RESEND_API_KEY is set, otherwise SMTP when SMTP_HOST and SMTP_USER are set. Resend sends from onboarding@resend.dev when no sender is configured. SMTP needs SMTP_PASS too, uses port SMTP_PORT (default 587, TLS on 465) and falls back to SMTP_USER as sender.
github_api
GitHub REST API access with GITHUB_TOKEN. One tool, 12 actions: get_repo, list_issues, get_issue, create_issue, update_issue, list_prs, get_pr, create_pr, get_file, list_commits, search_code, search_issues.
| Parameter | Type | Description |
|---|---|---|
action | enum | One of the actions above |
owner, repo | string | Repository |
number | number | Issue or PR number (get/update) |
title, body | string | For new issues and PRs |
state | enum | open | closed | all (default: open) |
labels, assignees | string[] | For issues |
path, ref | string | File path and ref for get_file |
base, head | string | Branches for create_pr |
query | string | For the search actions |
perPage, page | number | Pagination (1 - 100, default 30; default page 1) |
import { Agent, githubApi } from '@cogitator-ai/core';
const agent = new Agent({
name: 'github-bot',
model: 'openai/gpt-6.1-sol',
tools: [githubApi],
instructions: 'You help manage GitHub repositories.',
});exec
Executes shell commands and returns stdout, stderr and the exit code. Declares sideEffects: ['process', 'filesystem', 'network'] and requiresApproval: true, so every call waits for a decision (see Approvals).
| Parameter | Type | Description |
|---|---|---|
command | string | Shell command to execute |
cwd | string | Working directory |
timeout | number | Timeout in ms (100 - 300000, default: 30000) |
env | Record | Additional environment variables |
exec declares a Docker sandbox (cogitator/sandbox:base, 256 MB, 100 PIDs, no network). Inside a Cogitator the command runs in that container through @cogitator-ai/sandbox. When the sandbox package is not installed or Docker is unreachable, the runtime logs a warning and runs the command on the host, unless sandbox.allowNativeFallback: false on the Cogitator makes the call fail. See Sandbox.
Multimodal Tool Factories
Image and audio tools are created with factories rather than shipped in builtinTools. See Vision & Audio for parameters and results.
| Factory | Tool | Default model |
|---|---|---|
createAnalyzeImageTool | analyzeImage | gpt-6.1-sol on the llm backend you pass in |
createGenerateImageTool | generateImage | gpt-image-2.5-flare; returns base64 imageBase64, size / quality default to auto |
createTranscribeAudioTool | transcribeAudio | gpt-transcribe; whisper-1 when word timestamps are requested without an explicit model |
createGenerateSpeechTool | generateSpeech | gpt-4o-mini-tts |
Other Tool Factories
These build tools around state you provide; they are not part of builtinTools.
| Factory | Tools | Notes |
|---|---|---|
createMemoryTools({ graphAdapter, agentId, coreFacts?, embeddingFn? }) | remember, recall, forget | Long-term memory in a knowledge graph — see Smart Memory |
createSchedulerTools({ store, defaultChannel?, defaultUserId? }) | schedule_task, list_tasks, cancel_task | Delayed, dated or cron tasks in a workflows TimerStore — see Scheduler |
createCapabilitiesTool(doc) | lookup_capabilities | Searches a capabilities document line by line |
createDeviceTools() | clipboard_read, clipboard_write, system_info, screenshot | Clipboard via pbpaste/pbcopy (macOS) or xclip; screenshot is macOS only |
createSelfTools({ toolsDir, onToolsChanged? }) | create_tool, test_tool, list_custom_tools, delete_tool | Lets the agent write .mjs tools into toolsDir; create_tool requires approval |
loadCustomTools(toolsDir) | the tools in toolsDir | Loads the .mjs default exports createSelfTools wrote |
Tools created with createSelfTools run with full Node.js access in your process.
Public hosts only
A model chooses the URLs web_scrape and http_request fetch, and the audio URL transcribe_audio reads, so a page it read or a prompt it was given can point it at http://169.254.169.254/ (a cloud's credentials), http://localhost:8080/admin or a database on the internal network. These tools reach only the public internet: a URL on a loopback, private, link-local, carrier-grade NAT, multicast or documentation address, localhost, *.local, *.internal or a metadata host is refused, every redirect target is checked again, and a hostname is checked by the address it resolves to when the request connects, so a name that resolves elsewhere a moment later (DNS rebinding) is refused too. A refused URL comes back to the model as an error naming it.
An agent meant to work on a trusted network opts in, or brings its own client:
import { createHttpRequestTool, createWebScrapeTool } from '@cogitator-ai/core';
const intranet = createWebScrapeTool({ allowPrivateNetwork: true });
const api = createHttpRequestTool({ fetch: proxiedFetch });A fetch of your own is trusted with every URL, so it should apply your network policy. createTranscribeAudioTool takes the same two options.
The guard is yours to use too: fetchPublic is a fetch for public hosts, createPublicFetch({ allowPrivateNetwork, maxRedirects, resolver, isBlocked }) builds one to your rules, assertPublicUrl(url) checks a URL up front, assertPublicHost(url) checks the addresses its host resolves to as well and isPrivateAddress(ip) classifies an address. They run on node:http, in Node and Bun alike, and a refusal throws a PrivateNetworkError.
With robots, the tool checks a URL and the addresses its host resolves to before it reads the site's robots.txt. RobotsPolicy reads robots.txt with the global fetch unless given another: new RobotsPolicy({ userAgent, fetch: fetchPublic }) keeps those reads on public hosts too.
Requests carry DEFAULT_USER_AGENT and Accept: */* unless the caller sets its own headers.
Polite crawling with robots.txt
RobotsPolicy reads and caches a site's robots.txt and answers whether a URL may be fetched, by RFC 9309: the groups that name your product token (else *), longest match wins with * and $ patterns, a 4xx robots.txt allows everything, a 5xx or a network failure allows nothing until the cache (one hour by default) expires. It implements RobotsChecker, which WebLoader in @cogitator-ai/rag and BrowserSession in @cogitator-ai/browser take as robots:
import { RobotsPolicy } from '@cogitator-ai/core';
const robots = new RobotsPolicy({ userAgent: 'NewsBot/1.0 (+https://example.com/bot)' });
await robots.allows('https://example.com/news/today'); // true or falseThe token defaults to the User-Agent's first word (NewsBot); pass token to match another. robotsRulesFor(text, token) and robotsAllowsPath(rules, path) expose the parser for robots.txt files you already have.
createWebScrapeTool({ userAgent, robots }) builds a web_scrape tool with your User-Agent and a robots.txt check on every hop, redirects included (a disallowed page comes back as an error). The plain webScrape keeps the default User-Agent and checks nothing.