Connecting Claude to Your Data
Tools are how Claude reaches your database and APIs — safely, through code you control.
Tools are the bridge between Claude and the real systems behind your app: your database, internal APIs, and third-party services.
Common web-app tools
search_orders— look up a customer's orders in your database.check_inventory— query stock levels from an internal API.create_ticket— file a support ticket.
Safety first
Because your code runs the tool, you decide what is allowed. Validate every input, restrict what each tool can touch, and gate risky actions (deleting data, sending emails, taking payments) behind confirmation.
Example
// The tool runner (SDK helper) executes your functions automatically.
async function runTool(name, input) {
switch (name) {
case "search_orders": {
// Validate before touching the database
const userId = String(input.user_id || "").trim();
if (!userId) return "Error: user_id is required.";
const orders = await db.orders.findByUser(userId); // your DB call
return JSON.stringify(orders);
}
default:
return `Unknown tool: ${name}`;
}
}When to use it
- Connect Claude to your PostgreSQL database via a queryOrders tool so it can answer live order questions.
- Expose a Stripe-backed chargeCustomer tool that Claude can invoke after confirming the user's intent.
- Wire a sendEmail tool to Resend so Claude can draft and send follow-up emails on behalf of a sales agent.
More examples
Database query tool handler
Maps the tool name to a handler that runs a parameterised SQL query and returns JSON for Claude to read.
const toolHandlers = {
async search_orders({ customer_id, status }) {
const rows = await db.query(
"SELECT id, total, status FROM orders WHERE customer_id=$1 AND status=$2",
[customer_id, status]
);
return JSON.stringify(rows.rows);
},
};
// In the tool loop:
const result = await toolHandlers[toolBlock.name](toolBlock.input);Third-party API tool handler
Wraps the Resend SDK in a handler so Claude can trigger real email sends through the tool-use loop.
const toolHandlers = {
async send_email({ to, subject, body }) {
const res = await resend.emails.send({
from: "[email protected]",
to, subject, html: body,
});
return JSON.stringify({ sent: true, id: res.id });
},
};Guard tool calls with validation
Adds a safety gate that returns an error message instead of executing destructive operations without explicit confirmation.
async function safeHandle(name, input) {
if (name === "delete_user" && !input.confirmed) {
return JSON.stringify({ error: "confirmation required before deleting a user" });
}
return toolHandlers[name](input);
}
// Claude will read the error and ask the user to confirm before retrying
Discussion