Introduction
Welcome back, intrepid AI architects! In our previous chapter, we explored the fascinating world of Tool Schemas, learning how to precisely define the capabilities of an AI agent’s external tools. You crafted clear, unambiguous blueprints for what your tools can do. But what’s the use of a beautifully designed tool if no one knows it exists?
This chapter is all about making your amazing tools visible and accessible to AI agents and other services. We’ll dive into the critical processes of tool registration and tool discovery within the Model Context Protocol (MCP) ecosystem. Think of it like publishing your tool’s “yellow pages” entry, allowing agents to find and understand how to interact with your services. By the end of this chapter, you’ll be able to register your custom MCP tools and understand how AI agents can discover and utilize them, including how to enrich tool definitions with UI resources for more dynamic interactions.
Before we begin, ensure you have a basic understanding of JSON Schema and have a development environment set up for TypeScript/JavaScript, as we’ll be using the anticipated TypeScript SDK v2 for our examples.
Core Concepts: Making Tools Discoverable
The Model Context Protocol (MCP) aims to provide a standardized way for AI agents to interact with external tools. A fundamental part of this interaction is how agents find and learn about the tools available to them. This is where registration and discovery come into play.
What is Tool Registration?
Tool registration is the process by which a tool provider (that’s you!) informs an MCP server about the capabilities of its tools. It’s essentially submitting your tool’s schema, along with other metadata, to a central registry. Once registered, the MCP server acts as a directory, making your tool available for discovery by authorized AI agents and other systems.
Why is this important? Without registration, an AI agent would have no idea what tools exist, what they do, or how to call them. Registration centralizes this information, making tool management and integration scalable and efficient.
What is Tool Discovery?
Tool discovery is the inverse of registration. It’s how an AI agent or a client application queries an MCP server to find available tools that match its needs. An agent might ask, “Show me all tools that can provide weather information,” or “Are there any tools that can book a flight?” The MCP server, having received registrations from various tool providers, can then respond with a list of matching tools and their schemas.
This separation of concerns—providers registering and agents discovering—is a powerful pattern. It allows for a dynamic ecosystem where new tools can be added or updated without requiring every agent to be individually reconfigured.
The Registration Process Flow
Let’s visualize the basic flow of how a tool gets registered and then discovered:
- Define Tool Schema: You start by defining your tool’s capabilities using JSON Schema, as we covered in the previous chapter.
- Prepare Tool Manifest: For efficiency, especially if you have multiple tools, you’ll often group them into a “Tool Manifest.” This manifest is a collection of tool schemas and associated metadata.
- Authenticate (Optional but Recommended): Secure MCP servers will require authentication to ensure only authorized providers can register tools.
- Register Tool/Manifest: Your tool provider service sends the manifest to the MCP server.
- Validate and Store: The MCP server validates the incoming schema(s) against the MCP specification. If valid, it stores the tool definition(s) in its registry.
- Make Discoverable: The MCP server indexes the tool(s), making them available for discovery queries.
- Query for Tools: An AI agent or client application sends a request to the MCP server, asking for tools that meet certain criteria.
- Receive Discovered Tools: The MCP server responds with the schemas of matching tools.
- Utilize Tool: The AI agent then uses the received schema to understand how to call the tool’s functions.
Tool Manifests: Grouping Your Arsenal
Instead of registering each tool individually, the MCP often encourages the use of Tool Manifests. A manifest is a single document that can contain definitions for multiple tools provided by the same service or organization. This streamlines the registration process, reduces network overhead, and allows for easier management of related tools.
A typical manifest might look something like this (simplified):
{
"manifestId": "my-service-tools-v1",
"provider": {
"name": "My Awesome Services Inc.",
"url": "https://www.myservices.com"
},
"tools": [
{
"toolId": "weather-forecast-v1",
"name": "Weather Forecast",
"description": "Provides current weather and forecasts for any location.",
"schema": {
"type": "object",
"properties": { /* ... */ }
},
"endpoint": {
"type": "rest",
"url": "https://api.myservices.com/weather"
},
"permissions": [ /* ... */ ]
},
{
"toolId": "restaurant-finder-v1",
"name": "Restaurant Finder",
"description": "Finds restaurants near a given location.",
"schema": { /* ... */ },
"endpoint": { /* ... */ },
"permissions": [ /* ... */ ]
}
]
}
Extending Tools with UI Resources
One particularly powerful aspect of MCP, highlighted in the modelcontextprotocol/ext-apps specification, is the ability for tools to declare UI resources. This goes beyond just defining data inputs and outputs; it allows tool providers to suggest how their tool’s functionality could be represented in a user interface.
Imagine an AI agent recommending a restaurant. Instead of just giving text, the tool could provide a URL to an embedded map widget, a custom card component, or an image. This enables richer, more interactive experiences beyond plain text or data.
UI resources are typically defined within the tool’s schema or metadata and might include properties like:
iconUrl: A URL to an icon representing the tool.uiComponentUrl: A URL to a web component or iframe that can render a specific UI for the tool’s output or input.displayMetadata: Structured data for how the tool should be presented (e.g., color, category).
This feature is particularly exciting for developers building frontend applications that integrate with AI agents, allowing for a seamless blend of agent intelligence and custom user interfaces.
Permissions and Authorization during Registration
While we’ll dedicate a full chapter to security, it’s crucial to understand that during registration, a tool provider often defines the permissions required to use its tools. This might include:
- Scopes: What kind of access is needed (e.g.,
weather.read,restaurant.write). - Access Levels: Who can use the tool (e.g.,
public,internal,specific_user_groups).
The MCP server will store these permissions alongside the tool’s definition and enforce them during the discovery and execution phases. This ensures that only authorized agents and users can access sensitive functionalities.
Step-by-Step Implementation: Registering a Tool with TypeScript
As of 2026-03-20, the Model Context Protocol (MCP) specification is still in draft form, with its latest public draft dated 2026-01-26. The TypeScript SDK, anticipated to reach its v2 stable release in Q1 2026, offers robust tooling for interacting with MCP. We’ll use the anticipated syntax for this SDK.
Let’s walk through registering a simple “Weather Forecast” tool.
Prerequisites
Make sure you have Node.js and npm/yarn installed. Create a new TypeScript project:
mkdir mcp-tool-provider
cd mcp-tool-provider
npm init -y
npm install typescript @types/node ts-node
npx tsc --init
Now, let’s install the anticipated MCP TypeScript SDK. For demonstration purposes, we’ll assume a package named @modelcontextprotocol/sdk is available.
npm install @modelcontextprotocol/sdk@2.0.0-beta # Use beta for anticipated v2
Step 1: Define Your Tool Schema
We’ll reuse our getWeatherForecast tool schema from the previous chapter, making a slight adjustment to include UI metadata. Create a file named src/weatherTool.ts:
// src/weatherTool.ts
import { ToolDefinition } from '@modelcontextprotocol/sdk';
// This is our tool's capabilities defined using JSON Schema
const getWeatherForecastSchema = {
type: 'object',
properties: {
location: {
type: 'string',
description: 'The city and optional country, e.g., "London, UK" or "Tokyo"',
},
unit: {
type: 'string',
enum: ['celsius', 'fahrenheit'],
default: 'celsius',
description: 'The unit for temperature measurement.',
},
},
required: ['location'],
};
// Now, let's define the full ToolDefinition for registration
export const weatherToolDefinition: ToolDefinition = {
toolId: 'weather-forecast-v1', // Unique ID for our tool
name: 'Weather Forecast',
description: 'Provides current weather and a 5-day forecast for any specified location.',
version: '1.0.0',
schema: getWeatherForecastSchema,
// This is the endpoint where an agent would actually call our tool
// In a real scenario, this would point to your API gateway or serverless function
endpoint: {
type: 'rest', // Assuming a REST API endpoint
url: 'https://api.yourweatherprovider.com/forecast',
headers: {
'Authorization': 'Bearer YOUR_API_KEY_HERE' // Placeholder for actual auth
}
},
// Optional: Add UI resources as per modelcontextprotocol/ext-apps
// This helps client applications or agent UIs display the tool better.
ui: {
iconUrl: 'https://www.yourweatherprovider.com/icons/weather.svg',
displayMetadata: {
category: 'Utility',
color: '#3498db',
},
// If you had a custom web component to display weather, you could link it here:
// uiComponentUrl: 'https://www.yourweatherprovider.com/components/weather-widget.js'
},
// Define permissions required to use this tool
permissions: [
{
scope: 'weather.read', // A custom scope indicating read access to weather data
description: 'Allows reading weather forecast data.',
},
],
};
Explanation:
- We import
ToolDefinitionfrom the SDK. This is the standardized type for an MCP tool. toolId,name,description,version, andschemaare standard properties.- The
endpointspecifies where the agent should send requests to execute this tool. We’re using aresttype here, with a placeholder URL. In a real application, this would be your actual API endpoint. - The
uiproperty is where we leverage theext-appsextensions. We’ve added aniconUrlanddisplayMetadatato give client applications hints on how to present our tool. permissionsdefines the necessary scopes an agent or user needs to have to interact with this tool.
Step 2: Initialize the MCP Client and Register the Tool
Now, let’s create a script to register this tool with an MCP server.
Create src/registerTool.ts:
// src/registerTool.ts
import { McpClient, RegistrationResult, ToolManifest } from '@modelcontextprotocol/sdk';
import { weatherToolDefinition } from './weatherTool';
// IMPORTANT: Replace with your actual MCP Server URL and authentication token
// For a local development setup, this might be 'http://localhost:3000'
const MCP_SERVER_URL = process.env.MCP_SERVER_URL || 'https://mcp.example.com';
const AUTH_TOKEN = process.env.MCP_AUTH_TOKEN || 'your-secure-registration-token'; // This token authorizes your service to register tools
async function registerWeatherTool() {
console.log(`Attempting to register tool with MCP Server at: ${MCP_SERVER_URL}`);
try {
// 1. Initialize the MCP Client
// The SDK client handles communication with the MCP server.
const mcpClient = new McpClient({
baseUrl: MCP_SERVER_URL,
authToken: AUTH_TOKEN, // Used for authenticating our registration request
});
// 2. Create a Tool Manifest
// Even for a single tool, it's good practice to wrap it in a manifest.
// This allows for future expansion with more tools from your service.
const myToolManifest: ToolManifest = {
manifestId: 'my-weather-service-v1', // Unique ID for your manifest
provider: {
name: 'Our Example Weather Service',
url: 'https://www.example.com/weather-service',
},
tools: [weatherToolDefinition], // Include our defined tool
// Additional manifest-level metadata or settings can go here
};
// 3. Register the Tool Manifest
// The registerManifest method sends our tool definitions to the MCP server.
const result: RegistrationResult = await mcpClient.registerManifest(myToolManifest);
// 4. Handle the registration result
if (result.success) {
console.log('✅ Tool manifest registered successfully!');
console.log('Registration details:', JSON.stringify(result.details, null, 2));
} else {
console.error('❌ Failed to register tool manifest:');
console.error('Errors:', JSON.stringify(result.errors, null, 2));
process.exit(1); // Exit with an error code
}
} catch (error) {
console.error('An unexpected error occurred during registration:', error);
process.exit(1);
}
}
registerWeatherTool();
Explanation:
- We import
McpClient,RegistrationResult, andToolManifestfrom the SDK. McpClientis instantiated with thebaseUrlof your MCP server and anauthToken. This token is crucial for authenticating your service’s right to register tools.- We create a
ToolManifestobject. This manifest contains amanifestId,providerinformation, and an array oftools(in our case, justweatherToolDefinition). mcpClient.registerManifest(myToolManifest)sends this data to the MCP server.- The
RegistrationResultobject tells us if the registration was successful and provides details or errors.
Step 3: Run the Registration Script
To run this, you’ll need an MCP server running somewhere. For local testing, you might use a mock server or a development instance of an MCP server. For this example, let’s assume MCP_SERVER_URL and MCP_AUTH_TOKEN are set in your environment or replaced directly.
First, compile your TypeScript:
npx tsc
Then, run the compiled JavaScript:
node dist/registerTool.js
If successful, you should see a message indicating successful registration. If there’s an error, the console will log the details provided by the MCP server.
What Happens Next? (Discovery)
Once your tool is registered, an AI agent using the MCP SDK could then perform a discovery query. For example, an agent might do something like this (conceptual code):
// Conceptual AI Agent Discovery Code (not part of your tool provider)
import { McpClient } from '@modelcontextprotocol/sdk';
const agentMcpClient = new McpClient({
baseUrl: 'https://mcp.example.com',
// Agent might have its own auth token to discover tools
authToken: 'agent-discovery-token'
});
async function discoverWeatherTools() {
console.log('Agent attempting to discover weather tools...');
try {
// Query for tools that can perform actions related to 'weather'
const discoveredTools = await agentMcpClient.discoverTools({
query: 'weather', // A natural language query or schema-based filter
// Optionally, filter by scope or provider
// requiredScopes: ['weather.read']
});
if (discoveredTools.length > 0) {
console.log('✅ Agent discovered the following tools:');
discoveredTools.forEach(tool => {
console.log(` - ${tool.name} (ID: ${tool.toolId}, Version: ${tool.version})`);
if (tool.ui?.iconUrl) {
console.log(` Icon: ${tool.ui.iconUrl}`);
}
// The agent can now use tool.schema to understand how to call it
});
} else {
console.log('No weather tools discovered.');
}
} catch (error) {
console.error('Error during tool discovery:', error);
}
}
// discoverWeatherTools();
This conceptual example shows how an AI agent, using its own McpClient, would query the MCP server and receive your weatherToolDefinition (including its UI metadata and permissions) as part of the discoveredTools array. The agent can then use this information to decide whether and how to interact with your tool.
Mini-Challenge: Enhance Your Tool’s UI Metadata
Let’s make our weather tool even more user-friendly for any client application that might display it.
Challenge:
Modify the weatherToolDefinition in src/weatherTool.ts to include a cardComponentUrl in its ui property. Imagine this URL points to a custom web component that can render a visually appealing weather card. You can use a placeholder URL for now.
Hint:
Refer to the modelcontextprotocol/ext-apps documentation (or conceptual understanding) for how ui properties are structured. Add a new property like cardComponentUrl: 'https://www.yourweatherprovider.com/components/weather-card.js' within the existing ui object.
What to observe/learn: After updating and re-running the registration script (assuming your MCP server allows updates or re-registration), you’ll see how easily a tool’s metadata can be enriched without changing its core functional schema. This demonstrates the flexibility of MCP in supporting diverse client experiences.
Common Pitfalls & Troubleshooting
Even with the best intentions, registration can sometimes hit a snag. Here are a few common issues and how to approach them:
Invalid JSON Schema:
- Pitfall: Your
schemaobject inweatherToolDefinitiondoesn’t conform to valid JSON Schema syntax or to the specific requirements of the MCP specification. - Troubleshooting: The
RegistrationResultfrommcpClient.registerManifestwill often contain detailed validation errors. Pay close attention to theerrorsarray. Use an online JSON Schema validator (like JSON Schema Lint) to check your schema independently before attempting registration. - Example Error:
{"errors": [{"path": "/schema/properties/location", "message": "Missing 'type' property"}]}
- Pitfall: Your
Incorrect MCP Server Endpoint or Authentication:
- Pitfall: The
MCP_SERVER_URLis wrong, or theAUTH_TOKENis invalid or missing. - Troubleshooting: Check your
MCP_SERVER_URLfor typos. Ensure yourAUTH_TOKENis correct and has the necessary permissions on the MCP server to register tools. Network errors (ECONNREFUSED,401 Unauthorized,403 Forbidden) often indicate these issues. Verify the MCP server is actually running and accessible.
- Pitfall: The
Duplicate
toolIdormanifestId:- Pitfall: You’re trying to register a tool or manifest with an ID that already exists on the MCP server, and the server’s policy doesn’t allow updates or requires explicit update calls.
- Troubleshooting: If you’re developing, try changing
toolId(e.g.,weather-forecast-v1-test) ormanifestId(e.g.,my-weather-service-v1-dev). In a production environment, an MCP server would likely have a specific API for updating existing tool definitions, rather than re-registering. The error message will usually explicitly state a conflict.
Missing
endpointorpermissions:- Pitfall: The MCP specification might require certain fields like
endpointorpermissionsto be present for a tool to be valid. Forgetting these can lead to registration rejection. - Troubleshooting: Double-check the official MCP specification (refer to the
modelcontextprotocol/modelcontextprotocolGitHub repo) to ensure all mandatory fields forToolDefinitionare included.
- Pitfall: The MCP specification might require certain fields like
Summary
Phew! You’ve just taken a massive leap in understanding how AI agents interact with the world.
Here’s a quick recap of what we covered:
- Tool Registration is the process where your tool’s definition (its schema, endpoint, UI resources, and permissions) is submitted to an MCP server. This makes your tool’s capabilities known to the wider AI ecosystem.
- Tool Discovery is how AI agents or client applications query the MCP server to find relevant tools based on their needs, receiving the registered tool definitions in return.
- Tool Manifests allow you to group multiple related tools from a single provider, simplifying registration and management.
- The
uiproperty within aToolDefinition(part of theext-appsspecification) allows you to enrich your tool with UI resources like icons or custom component URLs, enabling richer user experiences. - We walked through a practical example using the anticipated TypeScript SDK v2 to define and register a
Weather Forecasttool, complete with UI metadata and permissions.
You now understand the crucial “handshake” between tool providers and AI agents. In the next chapter, we’ll dive even deeper, exploring the AI Agent Interaction Model and how agents actually use these discovered tools to execute tasks and achieve their goals. Get ready to see your agents come to life!
References
- Model Context Protocol - GitHub: https://github.com/modelcontextprotocol
- Specification and documentation for the Model Context Protocol: https://github.com/modelcontextprotocol/modelcontextprotocol
- Official repo for spec & SDK of MCP extended apps (including UI resources): https://github.com/modelcontextprotocol/ext-apps/
- The official TypeScript SDK for Model Context Protocol - GitHub: https://github.com/modelcontextprotocol/typescript-sdk
This page is AI-assisted and reviewed. It references official documentation and recognized resources where relevant.