Using Tools in Prompts with OpenClaw (Web Search, APIs, etc.)
Clawpedia · For Humans
Enable your OpenClaw agent to use external tools like web search and APIs directly from prompts.
Using Tools in Prompts with OpenClaw (Web Search, APIs, etc.)
OpenClaw agents become truly powerful when they can reach beyond their training data and interact with the real world through tools. This guide covers how to equip your agent with web search, API access, and other capabilities.
What Are Tools?
Tools are functions that your OpenClaw agent can call during a conversation. Instead of relying solely on its training data, the agent can search the web, query APIs, run code, and interact with external services.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ User │ ──→ │ OpenClaw │ ──→ │ Tool │
│ "What's the │ │ Agent │ │ (web search) │
│ weather?" │ │ decides to │ │ │
│ │ ←── │ use a tool │ ←── │ returns data │
└──────────────┘ └──────────────┘ └──────────────┘
Built-in Tools
OpenClaw ships with several tools out of the box:
| Tool | Description | Use Case |
|---|
web_search | Search the internet | Current events, facts, documentation |
|---|
web_browse | Read a specific URL | Scraping content, reading docs |
|---|
run_code | Execute code snippets | Calculations, data processing |
|---|
file_read | Read local files | Config files, logs, data |
|---|
file_write | Write to files | Reports, exports, configs |
|---|
shell | Run shell commands | System tasks, DevOps |
|---|
In your configuration:
# config.yaml
agent:
tools:
- web_search:
enabled: true
max_results: 5
- web_browse:
enabled: true
timeout: 10000
- run_code:
enabled: true
languages: [javascript, python]
sandbox: true
- shell:
enabled: false # Disabled by default for security
Prompting with Tools
Tell the Agent About Available Tools
system_prompt: |
You have access to these tools:
1. **web_search(query)**: Search the web. Use for current
information, facts you're unsure about, or real-time data.
2. **run_code(language, code)**: Execute code. Use for
calculations, data processing, or testing code snippets.
3. **web_browse(url)**: Read a webpage. Use when you need
specific content from a known URL.
Guidelines:
- ALWAYS search before answering questions about current events
- Use code execution for any math beyond basic arithmetic
- Cite your sources when using web search results
- If a tool call fails, explain what went wrong and try an alternative
When to Use Which Tool
system_prompt: |
Tool selection guide:
USE web_search WHEN:
- Question involves dates, prices, or current information
- You're less than 90% confident in your answer
- User asks "what is the latest..." or "current..."
USE run_code WHEN:
- Any mathematical calculation is needed
- Data needs to be transformed or analyzed
- You need to validate a code approach
USE web_browse WHEN:
- User provides a specific URL to analyze
- You need detailed content from a search result
- Documentation needs to be read in full
DO NOT USE TOOLS WHEN:
- The answer is well-known and stable (e.g., "What is HTTP?")
- User is making casual conversation
- The question is about your own capabilities
Custom Tool Integration
Creating a Custom Tool
// tools/weather-tool.js
module.exports = {
name: "get_weather",
description: "Get current weather for a location",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "City name or coordinates"
},
units: {
type: "string",
enum: ["celsius", "fahrenheit"],
default: "celsius"
}
},
required: ["location"]
},
async execute({ location, units = "celsius" }) {
const apiKey = process.env.WEATHER_API_KEY;
const response = await fetch(
`https://api.weatherapi.com/v1/current.json?key=${apiKey}&q=${location}`
);
const data = await response.json();
return {
location: data.location.name,
temperature: units === "celsius"
? data.current.temp_c
: data.current.temp_f,
condition: data.current.condition.text,
humidity: data.current.humidity
};
}
};
Registering Custom Tools
# config.yaml
agent:
custom_tools:
- path: ./tools/weather-tool.js
- path: ./tools/database-tool.js
- path: ./tools/notification-tool.js
API Integration Patterns
REST API Tool
// tools/api-tool.js
module.exports = {
name: "call_api",
description: "Make HTTP requests to external APIs",
parameters: {
type: "object",
properties: {
url: { type: "string" },
method: { type: "string", enum: ["GET", "POST", "PUT", "DELETE"] },
headers: { type: "object" },
body: { type: "object" }
},
required: ["url", "method"]
},
async execute({ url, method, headers = {}, body }) {
// Allowlist check
const allowedDomains = ["api.github.com", "api.slack.com"];
const domain = new URL(url).hostname;
if (!allowedDomains.includes(domain)) {
return { error: `Domain ${domain} is not in the allowlist` };
}
const response = await fetch(url, {
method,
headers: { "Content-Type": "application/json", ...headers },
body: body ? JSON.stringify(body) : undefined
});
return response.json();
}
};
Tool Chaining
Combine multiple tools in sequence:
User: "Compare our GitHub repo stats with our top 3 competitors"
Agent thinking:
1. web_search("top competitors for [product]") → identifies competitors
2. call_api(github API for our repo) → gets our stats
3. call_api(github API for competitor 1) → gets their stats
4. call_api(github API for competitor 2) → gets their stats
5. call_api(github API for competitor 3) → gets their stats
6. run_code(comparison analysis) → generates comparison table
7. Present formatted results
Security Best Practices
Input Validation
async execute(params) {
// Validate URL format
try {
const url = new URL(params.url);
if (url.protocol !== "https:") {
return { error: "Only HTTPS URLs are allowed" };
}
} catch {
return { error: "Invalid URL format" };
}
// Rate limiting
if (rateLimiter.isExceeded(params.url)) {
return { error: "Rate limit exceeded. Try again later." };
}
// Proceed with the call
}
Domain Allowlisting
agent:
tool_security:
web_browse:
allowed_domains:
- docs.openclaw.org
- github.com
- stackoverflow.com
blocked_domains:
- "*.onion"
- localhost
shell:
allowed_commands:
- ls
- cat
- grep
blocked_commands:
- rm
- sudo
- chmod
Debugging Tool Calls
# View tool call logs
openclaw logs --filter tools
# Example output:
# [10:32:15] Tool call: web_search("OpenClaw latest version")
# [10:32:16] Tool result: 3 results found (took 1.2s)
# [10:32:17] Tool call: web_browse("https://docs.openclaw.org/changelog")
# [10:32:18] Tool result: Page content retrieved (2.4KB)
Error Handling in Tool Prompts
system_prompt: |
When a tool call fails:
1. Tell the user what you tried and what went wrong
2. Try an alternative approach if available
3. If no alternative exists, explain what the user can do manually
NEVER silently ignore a tool failure.
NEVER fabricate data that should have come from a tool.
Tips for Effective Tool Usage
- Be specific in tool descriptions — the LLM uses them to decide when to call
- Set reasonable timeouts — slow APIs can hang the agent
- Cache results — same query in same conversation should reuse results
- Log everything — tool calls are the most common source of debugging needs
- Fail gracefully — always have a fallback when tools are unavailable
- Minimize tool calls — each call adds latency; batch when possible
Related Articles
- Automation Tools Compared: Zapier, IFTTT, and OpenClaw — See how OpenClaw stacks up against no-code automation tools like Zapier and IFTTT for workflow automation.
- Using Prompts Inside Skills: Tips and Techniques — Optimize the prompts within your OpenClaw skills for consistent, high-quality agent responses.
- Skill Dependencies: Managing Libraries and APIs — Handle external libraries, API keys, and third-party dependencies in your OpenClaw skills effectively.
- Debugging Unwanted Behavior: When Prompts Go Wrong — Diagnose and fix unexpected agent behavior caused by ambiguous, conflicting, or poorly structured prompts.
- Examples of Effective Prompts for Common Tasks — Ready-to-use prompt templates for everyday tasks like summarization, research, and content creation.