Agent SDK

Client tools

Use the Agent SDK clientTools prop to let the agent refresh data, navigate the UI, and update the current page from inside your app.

6 sections

clientTools lets the agent run browser-side functions inside the host app.

This is how an embedded agent goes beyond chat and starts interacting with your UI directly.

Use client tools for actions like:

  • refreshing the page's data after an MCP mutation
  • prefilling a form
  • navigating to a different view
  • selecting a record in the current screen
  • opening a local modal or drawer

The prop shape#

The Agent SDK config accepts a clientTools map:

TS
type ClientToolDefinition = {
  description: string;
  parameters: Record<
    string,
    {
      type: string;
      description: string;
      required?: boolean;
      enum?: string[];
    }
  >;
  execute: (params: Record<string, unknown>) => Promise<unknown>;
  requireConfirmation?: boolean;
};
 
type ClientToolsMap = Record<string, ClientToolDefinition>;

Pass it directly to EmcyChat:

TSX
<EmcyChat
  apiKey="emcy_sk_xxxx"
  agentId="ag_xxxxx"
  clientTools={clientTools}
/>

Todo sample example#

The Todo sample app exposes two browser-side tools:

TSX
const clientTools: ClientToolsMap = {
  fillQuickAddForm: {
    description: "Pre-fill the quick-add input.",
    parameters: {
      title: {
        type: "string",
        description: "Task title.",
        required: true,
      },
    },
    execute: async ({ title }) => {
      const nextTitle = String(title ?? "").trim();
      if (!nextTitle) {
        return { success: false, error: "Title required." };
      }
 
      setDraft(nextTitle);
      return { success: true, title: nextTitle };
    },
  },
  refreshTodoData: {
    description: "Refresh the todo list.",
    parameters: {},
    execute: async () => refreshTodos(),
  },
};

That gives the agent two important capabilities:

  • it can stage work in the local UI without calling the server
  • it can keep the host page in sync after a real MCP-side mutation

When to use client tools vs MCP tools#

Use MCP tools when the action should happen on the server side or against a real backend API.

Use client tools when the action should happen in the browser or affect only the current UI state.

Good split:

  • MCP tool: createTodo

  • client tool: refreshTodoData

  • MCP tool: getCustomer

  • client tool: navigateToCustomerDetails

Use prompt and context to teach the handoff#

The SDK will expose your clientTools, but you should still tell the agent when to use them.

Two good places:

  • the agent System Prompt
  • the per-turn context prop

Example:

TSX
<EmcyChat
  context={{
    hostRefreshInstruction:
      "After any server-side todo mutation, call the refreshTodoData client tool before you answer so the host page reflects the latest data.",
  }}
  clientTools={clientTools}
/>

That is a strong pattern for embedded agents: server truth comes from MCP, but visible UI completion comes from clientTools.

Best practices#

  • keep client tool names explicit and verb-first
  • describe what the tool changes in the UI
  • return structured results from execute
  • expose only actions that are safe for the current page
  • keep the set small so the agent is not choosing from unnecessary browser actions

If a tool is destructive or easy to misuse, set requireConfirmation.