MUST be used whenever creating an AtlasTool (client-side tool) for an Atlas agent. Do NOT manually write AtlasTool definitions or wire them into useAtlasChat — this skill handles the TypeBox schema, execute function, and hook wiring. Prerequisite: integrate-atlas-chat (vendored src/atlas-agent + TypeBox/AJV deps). This includes tools that fetch data, render UI, call APIs, show charts, query local state, or perform any browser-side action. Triggers: AtlasTool, client tool, add tool, create tool, new tool, tool definition, agent tool.
67
82%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
Scaffold a new AtlasTool named $ARGUMENTS and wire it into the app.
integrate-atlas-chat must already be complete: the app should vend the atlas-agent sources under src/atlas-agent/ (including react.ts) and have @sinclair/typebox, ajv, and ajv-formats installed as in that skill.
Client tools let the Atlas Agent invoke logic that runs in the browser — rendering charts, querying local state, showing UI panels, triggering navigation, etc. The agent decides when to call the tool; the app executes it and returns a result.
The flow is:
clientTool actionexecute() runs in the browser and returns { output, details }output (string) is sent back to the agent as the tool resultdetails (any shape) is available on message.toolCalls for the UI to renderBefore writing anything, read:
useAtlasChat is called (often src/App.tsx or a chat hook) to find where tools is passed — imports are typically from ./atlas-agent/react after integrate-atlas-chatCreate the tool as a typed constant. Use Type from @sinclair/typebox to define the parameters schema — this gives both compile-time types and runtime validation (same stack as the vendored atlas-agent from integrate-atlas-chat).
import { Type } from "@sinclair/typebox";
import type { AtlasTool } from "./atlas-agent/types";
export const myTool: AtlasTool = {
name: "my_tool", // snake_case — this is what the agent uses to invoke it
description:
"One sentence describing what this tool does and when the agent should call it.",
parameters: Type.Object({
exampleParam: Type.String({ description: "What this param is for" }),
optionalNum: Type.Optional(Type.Number({ description: "..." })),
}),
execute: async (args) => {
// args is fully typed from the schema above
// Do the work here — call APIs, update state, render UI, etc.
return {
output: "Plain text summary sent back to the agent",
details: {
// Any structured data you want available in the UI via message.toolCalls
},
};
},
};Adjust the ./atlas-agent/... path if the tool file is not directly under src/ next to the atlas-agent folder (for example ../atlas-agent/types from src/tools/).
| Schema | Usage |
|---|---|
Type.String() | string |
Type.Number() | number |
Type.Boolean() | boolean |
Type.Literal("foo") | exact value |
Type.Union([Type.Literal("a"), Type.Literal("b")]) | enum |
Type.Array(Type.String()) | string[] |
Type.Object({ ... }) | object |
Type.Optional(...) | mark any field optional |
Always add a description to each field — the agent uses these to understand what to pass.
Find the useAtlasChat call and add the tool to the tools array:
const { messages, send, ... } = useAtlasChat({
client: isLoading ? null : sdk,
agentExternalId: AGENT_EXTERNAL_ID,
tools: [myTool], // add here
});If the tool returns structured details, render them in the message list.
message.toolCalls is a ToolCall[] — one entry per tool call (client-side and server-side) in call order.
{msg.toolCalls?.map((tc, i) => (
// tc.name — tool name
// tc.output — the string sent back to the agent
// tc.details — your structured data (cast to your known shape)
<MyToolOutput key={i} data={tc.details as MyToolDetails} />
))}The agent can now invoke $ARGUMENTS. Describe what it does clearly in the description
field — the agent relies on that string to decide when and how to call the tool.
d6af887
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.