Introduction: Giving Your AI Agent a Blueprint
Welcome back, future AI architects! In our previous chapter, we explored the foundational concepts of the Model Context Protocol (MCP) and understood its role as a universal language for AI agents to interact with the world. Now, let’s dive into the heart of MCP: tool schemas.
Imagine you’re training a personal assistant. You wouldn’t just tell it, “Go order food.” You’d give it a clear, step-by-step guide: “To order food, you need to know the restaurant, the items, and the delivery address.” This guide is essentially a schema. For AI agents, tool schemas are the precise, machine-readable blueprints that define what a tool can do, how to use it, and even how to visually represent its interactions.
In this chapter, we’ll learn how to craft these essential schemas. We’ll explore how to use JSON Schema to define tool parameters, understand the unique way MCP allows tools to declare UI resources, and walk through practical examples using TypeScript. By the end, you’ll be able to create robust, descriptive schemas that empower AI agents to understand and effectively utilize your custom tools. Ready to give your agents their first detailed instructions? Let’s go!
Core Concepts: The Blueprint for AI Tools
At its heart, the Model Context Protocol (MCP) aims to standardize how AI agents discover and interact with external applications and services. The core mechanism for this interaction is the Tool Schema.
What is a Tool Schema?
Think of a tool schema as a comprehensive instruction manual for an AI agent. It’s not just about telling the agent what a tool does, but also how to invoke it, what information it needs, and even how to represent its functionality or output to a human user. A well-defined schema prevents ambiguity and allows agents to intelligently decide when and how to use a tool.
MCP tool schemas are typically composed of two main parts:
- Function Definition: Describes the actual callable action(s) the tool provides, including its name, a description, and the parameters it accepts.
- UI Definition (Optional but Powerful): Describes user interface components or interactions associated with the tool, allowing for rich, context-aware user experiences beyond simple text.
JSON Schema: The Universal Language for Data
Before we dive into defining tools, let’s quickly re-familiarize ourselves with JSON Schema. It’s a powerful standard for defining the structure of JSON data. Why is it important here? Because when an AI agent needs to call a tool, it often needs to provide arguments (parameters), and JSON Schema is the perfect way to define what those arguments should look like.
For example, if a getWeather tool needs a location parameter, JSON Schema can specify that location must be a string, and perhaps even provide examples or regular expression patterns.
The Model Context Protocol leverages JSON Schema to ensure that tool parameters are clearly defined and validated, making agent-tool interactions robust and predictable. You can find more details on the official JSON Schema website.
Defining Tool Functions: Actions an Agent Can Take
The primary purpose of a tool schema is to declare the functions (or actions) that a tool provides. These are the operations an AI agent can “call” to perform tasks.
Each function definition typically includes:
name: A unique, descriptive identifier for the function (e.g.,orderPizza,getWeatherForecast).description: A human-readable explanation of what the function does. This is crucial for the AI agent to understand the tool’s purpose and when to use it.parameters: A JSON Schema object that defines the structure and types of arguments the function expects. This is where you specify required fields, data types, and any constraints.
Let’s consider a simple getWeather function. It might need a location and an optional unit (Celsius or Fahrenheit).
{
"name": "getWeather",
"description": "Retrieves the current weather conditions for a specified location.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g., 'San Francisco, CA'"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "The unit of temperature to use. Defaults to 'fahrenheit'."
}
},
"required": ["location"]
}
}
This structure tells an AI agent everything it needs to know to call getWeather.
Beyond Functions: UI Resources in MCP
Here’s where MCP truly shines and differentiates itself from simpler function-calling protocols. The Model Context Protocol, as highlighted in the modelcontextprotocol/ext-apps repository, allows tools to declare UI resources. This means a tool isn’t just a backend API; it can also provide front-end components or instructions for displaying rich user interfaces.
Why is this important?
- User Confirmation: An agent might need to show a user a summary of an order before confirming.
- Rich Data Display: Instead of just text, a weather tool could provide a UI component to display a forecast graph.
- Interactive Forms: A booking tool could provide a form for users to input complex travel details.
- Progress Indicators: A long-running task can show a custom progress bar.
The ui part of a tool schema typically defines a structure that describes how to render or how to interact with a tool’s input or output in a graphical environment. This could reference a specific component, layout instructions, or even a URL to an embeddable widget.
While the exact structure for UI definitions is still evolving with the MCP specification (currently a draft as of 2026-01-26), the concept is to provide a standardized way for tools to suggest or provide UI elements. For example, a ui property might contain a type (e.g., form, card, chart), properties for data binding, and even references to external UI libraries or component definitions.
The Overall Structure of an MCP Tool Schema
Combining these ideas, a complete MCP tool schema will encapsulate both its functional capabilities and its UI-related resources.
Let’s visualize this with a simple diagram:
This diagram shows how a single MCP Tool Schema provides a holistic definition, covering both the programmatic interface (function) and the potential user-facing interface (UI).
Step-by-Step Implementation: Crafting Your First MCP Tool Schema in TypeScript
Now, let’s get practical! We’ll define a simple MCP tool schema using TypeScript, demonstrating both function and UI declarations.
Setup: Make sure you have Node.js (v18+) and TypeScript (v5+) installed. Create a new directory for your project and initialize it:
mkdir mcp-tool-schemas
cd mcp-tool-schemas
npm init -y
npm install typescript @types/node --save-dev
npx tsc --init
Open tsconfig.json and ensure target is es2022 or later, and module is NodeNext or ESNext.
Step 1: The Basic Tool Definition (Function Only)
Let’s start by defining a tool that can retrieve product information from an inventory. We’ll create a file named src/tool-definitions.ts.
// src/tool-definitions.ts
/**
* Defines the schema for a tool that can retrieve product information.
* This object adheres to the Model Context Protocol (MCP) specification for tool definitions.
*
* Note: The MCP specification is currently a draft (as of 2026-01-26),
* and this structure reflects anticipated patterns from the official repositories.
* The TypeScript SDK v2, anticipated Q1 2026, will provide official types.
*/
export const getProductInfoToolSchema = {
// The 'name' property is a unique identifier for this tool's function.
// AI agents use this name to invoke the tool.
name: "getProductInfo",
// The 'description' is crucial. It helps the AI agent understand what the tool does
// and when it should be used. Make it clear and concise!
description: "Retrieves detailed information about a product using its ID or SKU.",
// The 'parameters' property uses JSON Schema to define the input arguments
// that the 'getProductInfo' function expects.
parameters: {
// The top-level type for parameters is typically 'object' because tools often
// take multiple named arguments.
type: "object",
properties: {
// Define a 'productId' parameter.
productId: {
type: "string",
description: "The unique identifier (ID) of the product.",
},
// Define an optional 'sku' parameter.
sku: {
type: "string",
description: "The Stock Keeping Unit (SKU) of the product, if ID is not available.",
},
},
// The 'required' array specifies which parameters MUST be provided.
// In this case, either 'productId' OR 'sku' should be present,
// but JSON Schema doesn't have a direct 'oneOf' for required,
// so we'll make both optional and rely on tool implementation logic
// or agent's understanding to provide at least one.
// For simplicity, let's make productId required for now.
required: ["productId"],
},
};
console.log("Product Info Tool Schema Defined:", getProductInfoToolSchema);
Explanation:
- We define an
export const getProductInfoToolSchemaobject. This object represents our tool’s definition. name:getProductInfois the unique name an AI agent will use to call this function.description: Provides context to the AI about the tool’s purpose.parameters: This is where the JSON Schema comes in.type: "object": The parameters will be passed as a JSON object.properties: Defines the individual arguments:productId(string, required) andsku(string, optional).required: ["productId"]: Explicitly states thatproductIdmust always be provided.
To quickly test this, you can add a start script to your package.json:
// package.json (excerpt)
"scripts": {
"start": "npx ts-node src/tool-definitions.ts"
},
Then run npm start in your terminal. You’ll see the schema printed. (You might need to npm install -g ts-node or npm install ts-node --save-dev if you don’t have ts-node.)
Step 2: Adding UI Resources to the Tool
Now, let’s enhance our getProductInfoToolSchema by adding UI resource declarations. This allows the tool to suggest how its input form or output display should look. Remember, the MCP ui concept is still evolving, so this example uses anticipated patterns from modelcontextprotocol/ext-apps.
// src/tool-definitions.ts (updated)
/**
* Defines the schema for a tool that can retrieve product information,
* including both its functional capabilities and UI resources.
* This object adheres to the Model Context Protocol (MCP) specification for tool definitions.
*
* Note: The MCP specification is currently a draft (as of 2026-01-26),
* and this structure reflects anticipated patterns from the official repositories.
* The TypeScript SDK v2, anticipated Q1 2026, will provide official types.
*/
export const getProductInfoToolSchema = {
name: "getProductInfo",
description: "Retrieves detailed information about a product using its ID or SKU.",
parameters: {
type: "object",
properties: {
productId: {
type: "string",
description: "The unique identifier (ID) of the product.",
},
sku: {
type: "string",
description: "The Stock Keeping Unit (SKU) of the product, if ID is not available.",
},
},
required: ["productId"],
},
// --- NEW: UI Resource Definition ---
ui: {
// The 'type' property suggests the primary UI component or interaction type.
// This could be a standard type like 'form', 'card', 'table', or a custom component ID.
type: "product-details-card",
// 'title' and 'description' can be used for UI rendering, e.g., for a card header.
title: "Product Information",
description: "Display for detailed product data.",
// 'inputForm' can define a schema for a UI form to collect parameters for this tool.
// This is useful if the agent needs to prompt the user for input.
inputForm: {
type: "object",
properties: {
productId: {
type: "string",
label: "Product ID",
placeholder: "e.g., P001-A",
},
sku: {
type: "string",
label: "SKU (Optional)",
placeholder: "e.g., ABC-123",
},
},
required: ["productId"],
},
// 'outputDisplay' can define how the tool's result should be rendered.
// This could reference a predefined component or a layout.
outputDisplay: {
component: "ProductDetailsComponent", // A hypothetical component name
props: {
// These props might be dynamic, bound to the tool's output data.
// For simplicity, we'll use static placeholders for now.
// In a real scenario, this might use JSON Pointers or templating.
titlePath: "$.name", // Path to product name in the tool's output
imagePath: "$.imageUrl",
descriptionPath: "$.description",
},
},
// 'actions' can define UI actions associated with the tool, e.g., buttons.
actions: [
{
id: "addToCart",
label: "Add to Cart",
type: "button",
// This could trigger another MCP tool or an external action.
triggers: {
tool: "addToCart",
parameters: {
productId: "$.productId", // Bind from current product context
quantity: 1,
},
},
},
],
},
};
console.log("\nProduct Info Tool Schema with UI Defined:", JSON.stringify(getProductInfoToolSchema, null, 2));
Explanation:
- We’ve added a
uiproperty to ourgetProductInfoToolSchema. ui.type: Suggests a specific UI rendering component,product-details-card.ui.inputForm: This nested JSON Schema describes a form that could be presented to the user to gatherproductIdandsku. Notice thelabelandplaceholderproperties which are common UI hints.ui.outputDisplay: Suggests how the tool’s result should be rendered, referencing aProductDetailsComponentand providingpropsthat might dynamically bind to the tool’s output data (e.g.,$.nameimplies a JSON Pointer to thenamefield in the tool’s response).ui.actions: Defines interactive elements like an “Add to Cart” button. This button could, in turn, trigger another MCP tool (addToCart) and pass relevant parameters.
This extended schema now provides an AI agent with both the functional means to get product data and rich instructions on how to interact with a user for input or display the results visually.
Step 3: Exporting and Using the Schema (Conceptual)
In a real-world MCP application, these schema definitions would be registered with an MCP server or directly loaded by an MCP-compatible AI agent framework (like the MCP TypeScript SDK v2, anticipated Q1 2026). The export keyword makes our schema available for import elsewhere.
For instance, an agent framework might import this schema:
// src/agent-app.ts (conceptual)
import { getProductInfoToolSchema } from './tool-definitions';
// In a real application, you'd register this schema with an MCP runtime
// or provide it to your AI agent's tool registry.
// const mcpClient = new McpClient(); // From MCP TypeScript SDK v2
// mcpClient.registerTool(getProductInfoToolSchema);
console.log("Agent app loaded tool schema:", getProductInfoToolSchema.name);
// Later, the AI agent might decide to call this tool:
// const agentDecision = {
// tool: "getProductInfo",
// parameters: { productId: "P001-A" }
// };
// const result = await mcpClient.executeTool(agentDecision);
// console.log("Tool execution result:", result);
This conceptual agent-app.ts file illustrates how an agent framework would consume your well-defined tool schema.
Mini-Challenge: Build a “Restaurant Menu” Tool Schema
Now it’s your turn to apply what you’ve learned!
Challenge: Create a tool schema named listMenuItems for a restaurant application. This tool should:
- Take an optional
category(e.g., “Appetizers”, “Main Courses”, “Desserts”) as a string parameter. - Take an optional
dietaryRestrictions(e.g., “vegetarian”, “gluten-free”) as an array of strings. - Include a
uidefinition that suggests aninputFormforcategoryanddietaryRestrictions, and anoutputDisplaycomponent namedMenuItemListComponentfor showing the results. - Ensure the
descriptionis clear for an AI agent.
Hint:
- For
dietaryRestrictions, usetype: "array"withitems: { type: "string" }. - For
ui.inputFormproperties, addlabelandplaceholderfor user guidance. - For
ui.outputDisplay, simply define acomponentproperty.
What to observe/learn: This challenge reinforces your understanding of defining both simple and array parameters using JSON Schema, and structuring the ui property for both input and output.
// Your solution here (e.g., in src/challenge-tool.ts)
// export const listMenuItemsToolSchema = {
// // ... your schema here ...
// };
Click for Solution (try it yourself first!)
// src/challenge-tool.ts
export const listMenuItemsToolSchema = {
name: "listMenuItems",
description: "Retrieves a list of menu items from the restaurant, optionally filtered by category and dietary restrictions.",
parameters: {
type: "object",
properties: {
category: {
type: "string",
description: "The menu category to filter by (e.g., 'Appetizers', 'Main Courses', 'Desserts').",
enum: ["Appetizers", "Main Courses", "Desserts", "Drinks"] // Example categories
},
dietaryRestrictions: {
type: "array",
description: "A list of dietary restrictions to consider (e.g., 'vegetarian', 'gluten-free').",
items: {
type: "string"
}
}
},
// No parameters are strictly required for a general menu listing.
required: []
},
ui: {
type: "menu-browser", // A custom type for a menu browsing UI
title: "Browse Restaurant Menu",
description: "Interactive display for exploring menu items.",
inputForm: {
type: "object",
properties: {
category: {
type: "string",
label: "Menu Category",
placeholder: "e.g., Main Courses",
enum: ["Appetizers", "Main Courses", "Desserts", "Drinks"]
},
dietaryRestrictions: {
type: "array",
label: "Dietary Restrictions",
description: "Select any dietary needs.",
items: {
type: "string",
enum: ["vegetarian", "vegan", "gluten-free", "nut-free"] // Example restrictions
},
uniqueItems: true // Ensure no duplicate restrictions
}
},
required: []
},
outputDisplay: {
component: "MenuItemListComponent", // A hypothetical component for displaying menu items
props: {
// These props would bind to the actual menu data returned by the tool
itemsPath: "$.menuItems", // Path to the array of menu items in the tool's output
showImages: true,
allowOrdering: true
}
},
actions: [
{
id: "viewDetails",
label: "View Item Details",
type: "button",
triggers: {
tool: "getMenuItemDetails", // Another hypothetical tool
parameters: {
itemId: "$.selectedItemId" // Binds to an item selected in the UI
}
}
}
]
}
};
console.log("Restaurant Menu Tool Schema Defined:\n", JSON.stringify(listMenuItemsToolSchema, null, 2));
Common Pitfalls & Troubleshooting
Crafting effective tool schemas is crucial. Here are some common issues you might encounter:
Ambiguous or Incomplete JSON Schema for Parameters:
- Pitfall: Your
parametersJSON Schema isn’t precise enough, leading the AI agent to guess or provide incorrect arguments. For example, if adatefield istype: "string"without aformat(e.g.,date-time), the agent might sendtomorrowinstead of2026-03-21T09:00:00Z. - Troubleshooting: Always be as specific as possible. Use
format(e.g.,date-time,email,uri),enumfor fixed choices,patternfor regex validation, and cleardescriptionfields. Test your schema with a JSON Schema validator.
- Pitfall: Your
Missing or Vague
descriptionFields:- Pitfall: The
descriptionfor your tool or its parameters is too short or unclear. AI agents rely heavily on these descriptions to understand the purpose and context of your tool. A generic description like “Gets data” is unhelpful. - Troubleshooting: Write descriptive, action-oriented descriptions. Explain what the tool does, why it’s useful, and any important caveats. Imagine you’re explaining it to a new human colleague.
- Pitfall: The
Ignoring UI Resource Potential:
- Pitfall: You define functional tools but neglect the
uiproperty. This means your tools can’t leverage MCP’s ability to provide rich, interactive user experiences, limiting agent output to plain text. - Troubleshooting: For any tool that involves user input, confirmation, or complex output, consider how a user would best interact with it visually. Even a simple
ui.typeandui.outputDisplay.componentcan significantly enhance the agent’s utility. Think about what a user would see or do when using your tool.
- Pitfall: You define functional tools but neglect the
Summary
Phew! You’ve just taken a significant step in empowering AI agents. In this chapter, we’ve explored the fundamental concept of Model Context Protocol tool schemas.
Here are the key takeaways:
- Tool schemas are the instruction manuals for AI agents, defining both functional capabilities and UI resources.
- JSON Schema is the standard used within MCP to precisely define the
parametersfor tool functions, ensuring clarity and validation. - MCP goes beyond simple function calling by allowing tools to declare UI resources, enabling rich, interactive experiences for input gathering and output display.
- Crafting clear
name,description, and well-structuredparametersis vital for an AI agent to correctly understand and utilize your tools. - The
uiproperty, though still evolving in the MCP draft specification, is a powerful feature for integrating visual components and user interactions directly into agent workflows.
You’ve learned how to blueprint your AI tools! In the next chapter, we’ll move from defining individual tools to making them discoverable. We’ll explore Tool Registration and Discovery, understanding how an AI agent finds and accesses the tools it needs to perform its tasks. Get ready to connect your blueprints to the wider AI ecosystem!
References
- Model Context Protocol Specification and Documentation: An overview of the protocol, its goals, and core concepts (as of 2026-01-26 draft).
- Official TypeScript SDK for Model Context Protocol: The primary SDK for building MCP applications with TypeScript (anticipated v2 stable release Q1 2026).
- MCP Extensible Apps (UI Resources): Repository discussing how MCP allows for declaration of UI resources, extending tool capabilities beyond just data.
- JSON Schema Official Website: Comprehensive documentation and examples for defining JSON data structures.
This page is AI-assisted and reviewed. It references official documentation and recognized resources where relevant.