Little Bear LabsMCP UI

Unpacking Hidden MCP Gems: Resources

Digital Library
Angus Bezzina

MCP servers allow you to expose data and context from various data sources to large language models (LLMs) and other client applications. One of the key benefits of MCP is the flexibility to serve both static and dynamic data through well-defined resources and resource templates. In this article, we break down how resources and resource templates work, why they are important, and some tips and tricks on implementing them effectively.

What Are MCP Resources?

Within the MCP framework, resources represent any type of content that you want to make available for consumption by LLMs or other applications. This can include:

  • Text Data: Source code, configuration files, logs, or JSON data.
  • Binary Data: Images, PDFs, audio files, and other non-text files (provided in base64).
  • API Data: Results from APIs, database queries, or system metrics.

Each resource is uniquely identified by a URI. For example:

  • `file:///logs/app.log` might represent log files.
  • `api://weather/today` could be used for current weather information.

The resource design separates the identifier from the content, which provides the ability to manage data updates, handle subscriptions, and support error notifications when a resource changes.

Leveraging Resource Templates for Dynamic Content

Static resources with fixed URIs work well when data is predictable, but in many cases you may need a more dynamic solution. This is where resource templates come in, as they allow you define URI patterns that can dynamically generate content based on parameters instead of predefining every possible resource.

A classic example of this would be a personalised greeting. Instead of creating a new resource for every unique name, you can define a resource template like this:

{
"uriTemplate": "greetings://{name}",
"name": "Personal Greeting",
"description": "A greeting message personalized to the user",
"mimeType": "text/plain"
}

Then, when a client requests the URI `greetings://Janet`, the MCP server extracts the parameter (Janet), processes it, and returns a dynamically generated response such as:

{
"contents": [
{
"uri": "greetings://Janet",
"mimeType": "text/plain",
"text": "Hello, Janet! Welcome to MCP."
}
]
}

This pattern offers several benefits:

  • Dynamism: One template can serve an unlimited number of concrete resources.
  • Scalability: There’s no need to add hundreds or thousands of static resource definitions.
  • Consistency: Dynamic resource generation can be applied uniformly, ensuring consistent behavior across similar requests.

Implementing Best Practices

To make the most of resource templates in your MCP server, consider these recommendations:

1. Organize Your Code: Create dedicated modules or files for resource-related handlers. Keeping resource logic separate improves code maintainability and clarity.

2. Expose Resource Metadata: Implement endpoints (e.g., resources/list and resources/templates/list) that returns the list of available resources. This helps client applications (Claude Desktop, Cursor) and LLMs understand what content they can request.

3. Efficient Template Parsing: When processing a resource request, check if the provided URI matches any defined template. Use a regular expression or a URI parser to extract parameters and generate the response. For instance:

server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const uri = request.params.uri;
const greetingPattern = /^greetings:\/\/(.+)$/;
const match = uri.match(greetingPattern);
if (match) {
const name = decodeURIComponent(match[1]);
return {
contents: [
{
uri,
mimeType: "text/plain",
text: `Hello, ${name}! Welcome to MCP.`
}
]
};
}
throw new Error("Resource not found");
});

4. Error Handling & Template Validation: Validate incoming parameters carefully to prevent injection attacks or malformed URIs.

5. Use Clear Naming Conventions: Define descriptive names and URIs that are intuitive, making it easier for clients and LLMs to select appropriate resources. Setting proper MIME types ensures that the consuming application correctly interprets the data.

6. Document Your Resources: Include detailed documentation of available resources and templates, expected parameters, and how dynamic generation works. This will help client developers understand how to construct valid URI requests.

Final Thoughts

Resources are a powerful tool for extending the capabilities of MCP servers. By leveraging them effectively, you can dynamically expose data from your system, scale your deployments effortlessly, and ensure a consistent, flexible integration with LLMs and other data-consuming applications.