Now in the last section we were looking at resources, which handles less complex actions and provide more static content. The tools have a much wide use-case, and is today better implemented in most AI tools (such that the resources are often better implemented as tools instead).
The tools can fetch new information, perform searches, and also perform actions. Examples of such actions could be to update an issue in Jira or a work item in Azure DevOps, creating a pull request on GitHub etc. The usability doesn't end there, basically you can let it perform any action you are able to program it to perform
Let us start with some simple tools for our drone management system that we have been building up in the previous sections. As before we start by creating a new file in the mcp folder, this time called tools.ts.
// Import necessary modules and types
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
// Import the drones data from a helper file
import { drones } from "./helpers/drones.js";
// Import zod for schema validation. MCP Servers use zod for input schema validation.
import z from "zod";
// Function to register tools to the MCP server
function registerTools(server: McpServer) {
// Register a tool to list all drones
server.registerTool(
"list-drones", // Unique identifier for the tool
{
title: "List Drones", // Title of the tool
description: "This tool list all the drones we have in our organization" // Description of the tool
},
() => {
// The function that gets executed when the tool is called
return {
content: [
{
type: "text",
text: JSON.stringify(drones)
}
]
}
}
);
// Register a tool to list drones based on specific requirements
server.registerTool(
"list-drones-requirements",
{
title: "List Suitable Drones",
description: "This tool lists the drones that are suitable based on the requirements",
// Define the input schema using zod
inputSchema: {
// Define the input schema for the tool
minSpeed: z.number().describe("The minimum speed the drone has to be able to reach").optional(),
minLoad: z.number().describe("The minimum load the drone can carry").optional(),
minDistance: z.number().describe("The minimum distance the drone has to be able to fly").optional(),
autonomous: z.boolean().describe("Whether the drone has to be autonomous or not").optional()
}
},
( { minSpeed, minLoad, minDistance, autonomous } ) => {
// Filter the drones based on the provided requirements
const suitableDrones = drones.filter(drone => {
if (minSpeed && drone.specs.maxSpeed < minSpeed) return false
if (minLoad && drone.specs.loadCapacity < minLoad) return false
if (minDistance && drone.specs.maxDistance < minDistance) return false
if (autonomous !== undefined && drone.specs.autonomous !== autonomous) return false
return true
})
return {
content: [
{
type: "text",
text: JSON.stringify(suitableDrones)
}
]
}
}
);
}
// Export the registerTools function
export { registerTools }The code above creates two tools, one for listing all drones and one for listing drones based on specific requirements. The second tool also defines an input schema using zod to validate the input parameters.
The next step is to import this function to the MCP server instance and use it to register the tools on the MCP Server.
// Importing the MCP Server class from the SDK
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
// Importing the function for registrering resources
import { addResources } from "./resources.js";
// Import the function to register tools
import { registerTools } from "./tools.js";
// Creating the MCP server instance with a name and version
const server = new McpServer({
name: "My MCP Server",
version: "1.0.0",
});
// Use the function to register the resources.
addResources(server);
// Use the function to register the tools.
registerTools(server);
// Exporting the server so that we can use it in other parts of our application
export { server };Running the server again we should be able to call the different tools. This should be visible from the mcp.json file where the connection is defined.
Using GitHub Copilot we can make sure to call the tool we want to use by explicitly mentioning it in the prompt.
This should result in the tool being called and the result being used in the response.


