Creating Custom Tool Definitions
Building a custom tool for an AI is like teaching a chef how to use a new kitchen appliance. The chef knows how to cook, but they need clear instructions on how to operate the specific buttons and settings of the machine. When you define a tool for an AI model, you provide the exact interface it needs to interact with your local files or private data systems. This setup bridges the gap between the model's vast general knowledge and your specific, private requirements.
Defining the Tool Interface
To make a function available to an AI, you must provide a formal description of what that function does. This description tells the AI what arguments the function expects and what kind of result it will return. Think of this as a contract between your code and the AI model. If the contract is unclear, the model might try to send incorrect data to your code, causing errors or unexpected behavior. You define this interface by specifying the name, a clear description, and the required input parameters for each function.
Key term: — this metadata acts as the bridge allowing the language model to trigger your local code.
When you build an , you must ensure every tool definition is precise. If you create a tool to list files, you should describe it as a command that returns a list of items in a directory. You must also specify that the input parameter is a folder path. Without these details, the AI cannot guess how to use your tool effectively.
Implementing the Execution Logic
Once the interface is defined, you must write the actual code that performs the task. This is where the AI's request meets your local environment. In a shell command tool, your code receives an input string from the AI and must treat it as untrusted. Two habits keep this safe. First, never paste that string into a shell command, because characters like a semicolon would let the model run a second command you never intended. Pass the value as a separate argument instead. Second, resolve the path and confirm it still sits inside a directory you chose, so a value like "../../.ssh" cannot escape.
import { execFileSync } from "node:child_process";
import { resolve, relative, isAbsolute } from "node:path";
const ROOT = resolve("/Users/you/safe-workspace"); // [1]
const listFiles = {
name: "list_files",
description: "List files in a directory",
inputSchema: { type: "object", properties: { path: { type: "string" } } }
}; // [2]
async function execute(args) {
const target = resolve(ROOT, args.path ?? ".");
const rel = relative(ROOT, target);
if (rel.startsWith("..") || isAbsolute(rel)) {
throw new Error("Path is outside the allowed directory"); // [3]
}
return execFileSync("ls", [target]).toString(); // [4]
}- Pin every request to one root directory the tool is allowed to read.
- The schema declares the shape only — it does not make the value safe.
- Resolve the path, then reject anything that escapes the root via "..".
- execFileSync passes the path as an argument, so shell characters never run.
Managing Tool Security and Scope
Granting an AI the ability to run shell commands is a powerful but sensitive capability. You must limit the scope of these tools to prevent the model from accessing files it does not need. Imagine giving a house guest a key to your front door but not the keys to your personal safe. You restrict the tool's access to specific directories or safe system commands. By keeping the execution environment contained, you ensure that even if the AI makes a mistake, the impact on your system remains minimal and controlled.
| Feature | Purpose | Security Best Practice |
|---|---|---|
| Input Schema | Validates data types | Enforce strict typing |
| Description | Explains function intent | Be clear and specific |
| Execution Logic | Performs the action | Use allow-lists for commands |
Using these structures allows you to build safe, reliable tools that extend the AI's reach. As you move forward, remember that the quality of your tool definitions directly dictates how well the AI can assist you with your private tasks.
Defining a tool requires both a clear schema that the AI understands and a secure execution layer that protects your local system.
The next Station introduces Prompt Collections, which determines how you organize and manage the requests sent to your custom tools.