For MCP Servers we can expose resources to clients/AI tools for them to use.
A resource should be something more or less static or not complex. It does support parameters, but these should be more look at as navigation. Imagine you have a cook book. This book is a resource. You can also create a resource just listing all of the recepies, and you can create a dynamic resource which relies on the recepie you have selected. Files and folders are also good examples of what are typical resources.
Now lets add resources to our MCP Server. We start by creating a file for our resource implementation in the mcp folder called resources.ts. We will use the helper files here to have some data to work with.
Lets imagine that we have a company that are using drones for various activities. We are creating an AI system to help manage these. Giving the AI information about these drones can be a useful feature for us, so let's create some resources for providing this information.
We start by creating a method that accepts the MCPServer as input and that we will use to register all the resources.
// We import the neccesary classes
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
// We import the test data
import { drones } from "./helpers/drones.js";
// Function for registrering the resources to the MCP Server
function addResources(server: McpServer) {
// We register a list of all the drones as a resource
server.registerResource(
"list-drones", // We give the resource a name
"drones://", // Some pattern or "url"
{
title: "List Drones", // A more readable title
description: "Lists the drones that we have" // And a more descriptive description
},
(uri) => {
// We handle the request and returns the drones as part of the content.
const droneNames = drones.map(drone => drone.model);
return {
contents: [
{
uri: uri.href,
mimeType: "application/json",
text: JSON.stringify(droneNames)
}
]
}
}
)
// We add a new resource for getting the information about a specific drone
server.registerResource(
"get-drone",
// Now we can create a bit more complex resource template to ensure only a specific set of "paths" are viable
new ResourceTemplate("drones://{model}", {
list: undefined,
complete: {
model: (value, context) => {
return drones.map(drone => drone.model.replace(" ", "-"));
}
}
}),
{
title: "Get Drone",
description: "Gets a specific model of drones"
},
// Handle the request as before, but now we also fetch the expected parameter
(uri, {model}) => {
// We search the drones for the specific model and returns it.
const drone = drones.find(d => d.model.replace(" ", "-") === model);
return {
contents: [
{
uri: uri.href,
mimeType: "application/json",
text: JSON.stringify(drone)
}
]
}
}
)
}
export { addResources }The next step is to import this function to the MCP server instance and use it to register the resources on the MCP Server.
After doing so the src/mcp/server.ts should look something like this.
// 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";
// 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);
// 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 get the different resources
If we for example go to the mcp.json file where the MCP is set up like before, we can browse the resources 
Clicking this we should see the two resources we just created.
Clicking the Get Drone resource we can see that it requires a parameter. We can also see that it has autocompletion enabled for this parameter.
Clicking on one of the options should give us the information about that specific drone.


