- Published on
Understanding Resources in MCP Servers: A Complete Guide
- Authors

- Name
- Anablock
AI Insights & Innovations
Resources in MCP servers allow you to expose data to clients, similar to GET request handlers in a typical HTTP server. They're perfect for scenarios where you need to fetch information rather than perform actions.
Understanding Resources Through an Example
Let's say you want to build a document mention feature where users can type @document_name to reference files. This requires two operations:
- Getting a list of all available documents (for autocomplete)
- Fetching the contents of a specific document (when mentioned)
When a user types @, you need to show available documents. When they submit a message with a mention, you automatically inject that document's content into the prompt sent to Claude.
How Resources Work
Resources follow a request-response pattern. Your client sends a ReadResourceRequest with a URI, and the MCP server responds with the data. The URI acts like an address for the resource you want to access.
Types of Resources
There are two types of resources:
Direct Resources
Static URIs that don't change, like docs://documents
Templated Resources
URIs with parameters, like docs://documents/{doc_id}
For templated resources, the Python SDK automatically parses parameters from the URI and passes them as keyword arguments to your function.
Implementing Resources
Resources are defined using the @mcp.resource() decorator. Here's how to create both types:
Direct Resource (List Documents)
@mcp.resource(
"docs://documents",
mime_type="application/json"
)
def list_docs() -> list[str]:
return list(docs.keys())
This creates a static resource that returns a list of all available document IDs. Perfect for populating an autocomplete menu.
Templated Resource (Fetch Document)
@mcp.resource(
"docs://documents/{doc_id}",
mime_type="text/plain"
)
def fetch_doc(doc_id: str) -> str:
if doc_id not in docs:
raise ValueError(f"Doc with id {doc_id} not found")
return docs[doc_id]
This creates a templated resource where {doc_id} becomes a parameter. The SDK automatically extracts the value from the URI and passes it to your function.
MIME Types
Resources can return any type of data - strings, JSON, binary, etc. The mime_type parameter gives clients a hint about what kind of data you're returning:
application/json- Structured JSON datatext/plain- Plain text content- Any other valid MIME type for different data formats
The MCP Python SDK automatically serializes your return values. You don't need to manually convert to JSON strings.
Testing Resources
You can test your resources using the MCP Inspector. Run your server with:
uv run mcp dev mcp_server.py
Then connect to the inspector in your browser. You'll see:
- Resources: Lists your direct/static resources
- Resource Templates: Shows templated resources that accept parameters
Click on any resource to test it and see the exact response structure your client will receive.
Real-World Use Cases
Document Management
Expose a library of documents that can be referenced in conversations:
- List all available documents
- Fetch specific document content
- Search documents by keyword
Configuration Access
Provide access to configuration data:
- System settings
- User preferences
- Environment variables
Data Browsing
Enable exploration of structured data:
- Database records
- File system navigation
- API endpoint discovery
Status and Monitoring
Expose real-time information:
- Server health metrics
- Job status
- Log entries
Best Practices
Use Descriptive URIs
Make your resource URIs self-documenting:
# Good
"docs://documents/{doc_id}"
"config://settings/{setting_name}"
# Less clear
"resource://{id}"
"data://{param}"
Handle Errors Gracefully
Always validate parameters and provide clear error messages:
@mcp.resource("docs://documents/{doc_id}")
def fetch_doc(doc_id: str) -> str:
if doc_id not in docs:
raise ValueError(f"Document '{doc_id}' not found")
return docs[doc_id]
Choose Appropriate MIME Types
Use the correct MIME type to help clients understand your data:
- JSON data →
application/json - Plain text →
text/plain - HTML →
text/html - Binary data →
application/octet-stream
Keep Resources Focused
Each resource should have a single, clear purpose. Don't try to do too much in one resource.
Resources vs. Tools
Understanding when to use resources versus tools is crucial:
| Resources | Tools | |---------------|----------| | Fetch/read data | Perform actions | | GET-like operations | POST/PUT/DELETE-like operations | | Idempotent (same input = same output) | May have side effects | | Examples: list files, read config | Examples: create file, send email |
Key Points
✅ Resources expose data, tools perform actions
✅ Use direct resources for static data, templated resources for parameterized queries
✅ MIME types help clients understand response format
✅ The SDK handles serialization automatically
✅ Parameter names in templated URIs become function arguments
Conclusion
Resources provide a clean, standardized way to make data available to MCP clients. Whether you're building document mentions, file browsing, configuration access, or any scenario where you need to fetch information from your server, resources give you a powerful and flexible pattern.
By following the examples and best practices in this guide, you can create robust, well-structured resources that make your MCP server a valuable data source for AI applications.
Start experimenting with resources in your MCP server today, and see how they can enhance your AI-powered workflows!