Skip to content

Commit 7914b7c

Browse files
committed
docs: update template with MCP resource examples and comprehensive documentation
- Add #[mcp_resource] examples with URI templates - Include ServerStatus and ServerConfig data structures - Demonstrate parameterized resources with example-data/{id} - Add comprehensive Tools vs Resources comparison table - Update README with resource testing commands and explanations - Show both operational tools and read-only resource patterns - Provide clear guidance on when to use tools vs resources The template now showcases the complete MCP capabilities including both tools for operations and resources for read-only data access.
1 parent f4654c9 commit 7914b7c

File tree

2 files changed

+165
-6
lines changed

2 files changed

+165
-6
lines changed

README.md

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,36 @@ A template repository for creating Model Context Protocol (MCP) servers using th
1212
```
1313
3. **Customize the server**:
1414
- Update `Cargo.toml` with your project details
15-
- Modify `src/lib.rs` to implement your tools
15+
- Modify `src/lib.rs` to implement your tools and resources
1616
- Update this README with your project information
1717

1818
4. **Build and test**:
1919
```bash
2020
cargo build
21+
# Test tools
2122
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | ./target/debug/template-mcp-server
23+
# Test resources
24+
echo '{"jsonrpc":"2.0","id":2,"method":"resources/list","params":{}}' | ./target/debug/template-mcp-server
2225
```
2326

2427
## 🛠 What's Included
2528

2629
This template provides:
2730

2831
- **Complete MCP server setup** using PulseEngine MCP framework
29-
- **Automatic tool discovery** with `#[mcp_tools]` macro
32+
- **Automatic tool & resource discovery** with `#[mcp_tools]` and `#[mcp_resource]` macros
3033
- **Example tools** demonstrating different parameter types:
3134
- Simple status check (no parameters)
3235
- Echo with optional parameters
3336
- Numeric calculations
3437
- Structured data creation
3538
- List processing
3639
- Error handling examples
40+
- **Example resources** for read-only data access:
41+
- Server status information (`template://server-status`)
42+
- Server configuration (`template://server-config`)
43+
- Parameterized data lookup (`template://example-data/{id}`)
44+
- **URI template support** for parameterized resources
3745
- **STDIO transport** for integration with MCP clients
3846
- **Proper logging configuration** for debugging
3947

@@ -127,8 +135,54 @@ echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | ./target/deb
127135

128136
# Call a tool
129137
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_status","arguments":{}}}' | ./target/debug/template-mcp-server
138+
139+
# List available resources
140+
echo '{"jsonrpc":"2.0","id":3,"method":"resources/list","params":{}}' | ./target/debug/template-mcp-server
141+
142+
# Read a resource
143+
echo '{"jsonrpc":"2.0","id":4,"method":"resources/read","params":{"uri":"template://server-status"}}' | ./target/debug/template-mcp-server
130144
```
131145

146+
## 🔍 Tools vs Resources
147+
148+
This template demonstrates both **MCP Tools** and **MCP Resources**:
149+
150+
### Tools (Operations)
151+
Tools are functions that **perform operations** or **modify state**. They:
152+
- Take parameters as input
153+
- Can have side effects (create, update, delete)
154+
- Return results from their execution
155+
- Are called via `tools/call` method
156+
157+
**Examples in template:**
158+
- `get_status()` - Checks server status
159+
- `echo(message, prefix)` - Transforms input
160+
- `add_numbers(a, b)` - Performs calculations
161+
- `create_data(...)` - Creates new data
162+
163+
### Resources (Read-Only Data)
164+
Resources provide **read-only access to data**. They:
165+
- Use URI templates for identification
166+
- Cannot modify state (read-only)
167+
- Are accessed via `resources/read` method
168+
- Perfect for configuration, status, or reference data
169+
170+
**Examples in template:**
171+
- `template://server-status` - Current server status
172+
- `template://server-config` - Server configuration
173+
- `template://example-data/{id}` - Data lookup by ID
174+
175+
### When to Use Each
176+
177+
| Use Tools For | Use Resources For |
178+
|---------------|-------------------|
179+
| Operations & actions | Read-only data access |
180+
| Data modification | Configuration settings |
181+
| Calculations | Status information |
182+
| API calls | Reference data |
183+
| File operations | Cached data |
184+
| Dynamic processing | Static information |
185+
132186
## 📝 Customizing Your Server
133187

134188
### 1. Update Package Information

template-mcp-server/src/lib.rs

Lines changed: 109 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
//! This template provides a starting point for building MCP servers using the
44
//! PulseEngine MCP framework. It demonstrates:
55
//! - Using the #[mcp_server] macro for automatic server setup
6-
//! - Using the #[mcp_tools] macro for automatic tool discovery
6+
//! - Using the #[mcp_tools] macro for automatic tool and resource discovery
77
//! - Basic tool implementations with different parameter types
8+
//! - Resource implementations for read-only data access
9+
//! - URI templates for parameterized resources
810
//! - Proper error handling and async support
911
10-
use pulseengine_mcp_macros::{mcp_server, mcp_tools};
12+
use pulseengine_mcp_macros::{mcp_server, mcp_tools, mcp_resource};
1113
use serde::{Deserialize, Serialize};
1214

1315
/// Example data structure that your tools might work with
@@ -19,6 +21,25 @@ pub struct ExampleData {
1921
pub tags: Vec<String>,
2022
}
2123

24+
/// Server status information (exposed as a resource)
25+
#[derive(Debug, Serialize, Deserialize, Clone)]
26+
pub struct ServerStatus {
27+
pub name: String,
28+
pub version: String,
29+
pub uptime_seconds: u64,
30+
pub tools_count: usize,
31+
pub resources_count: usize,
32+
}
33+
34+
/// Server configuration (exposed as a resource)
35+
#[derive(Debug, Serialize, Deserialize, Clone)]
36+
pub struct ServerConfig {
37+
pub max_concurrent_requests: usize,
38+
pub timeout_seconds: u64,
39+
pub debug_mode: bool,
40+
pub supported_formats: Vec<String>,
41+
}
42+
2243
/// Template MCP Server
2344
///
2445
/// Replace this with your own server implementation. The #[mcp_server] macro
@@ -29,14 +50,24 @@ pub struct ExampleData {
2950
description = "A template MCP server demonstrating basic functionality",
3051
auth = "disabled" // Change to "memory", "file", or remove for production
3152
)]
32-
#[derive(Default, Clone)]
53+
#[derive(Clone)]
3354
pub struct TemplateMcpServer {
55+
start_time: std::time::Instant,
3456
// Add your server state here
3557
// Example:
3658
// data_store: Arc<RwLock<HashMap<u64, ExampleData>>>,
3759
}
3860

39-
/// All public methods in this impl block become MCP tools automatically
61+
impl Default for TemplateMcpServer {
62+
fn default() -> Self {
63+
Self {
64+
start_time: std::time::Instant::now(),
65+
}
66+
}
67+
}
68+
69+
/// All public methods in this impl block become MCP tools or resources automatically
70+
/// Methods with #[mcp_resource] become resources, others become tools
4071
#[mcp_tools]
4172
impl TemplateMcpServer {
4273
/// Get server status and basic information
@@ -133,6 +164,80 @@ impl TemplateMcpServer {
133164
Ok("Tool executed successfully".to_string())
134165
}
135166
}
167+
168+
// Resources - Read-only data accessible via MCP resource URIs
169+
170+
/// Get server status information
171+
///
172+
/// This resource provides read-only access to the server's current status.
173+
/// Resources are for data that clients need to read but not modify.
174+
#[mcp_resource(
175+
uri_template = "template://server-status",
176+
name = "server_status",
177+
description = "Current server status and statistics",
178+
mime_type = "application/json"
179+
)]
180+
pub async fn server_status_resource(&self) -> anyhow::Result<ServerStatus> {
181+
let uptime = self.start_time.elapsed();
182+
183+
Ok(ServerStatus {
184+
name: "Template MCP Server".to_string(),
185+
version: "0.1.0".to_string(),
186+
uptime_seconds: uptime.as_secs(),
187+
tools_count: 6, // Update this if you add/remove tools
188+
resources_count: 3, // Update this if you add/remove resources
189+
})
190+
}
191+
192+
/// Get server configuration
193+
///
194+
/// This resource exposes the server's configuration settings.
195+
/// Resources are perfect for configuration data that clients need to read.
196+
#[mcp_resource(
197+
uri_template = "template://server-config",
198+
name = "server_config",
199+
description = "Server configuration settings",
200+
mime_type = "application/json"
201+
)]
202+
pub async fn server_config_resource(&self) -> anyhow::Result<ServerConfig> {
203+
Ok(ServerConfig {
204+
max_concurrent_requests: 100,
205+
timeout_seconds: 30,
206+
debug_mode: cfg!(debug_assertions),
207+
supported_formats: vec![
208+
"json".to_string(),
209+
"text".to_string(),
210+
"binary".to_string(),
211+
],
212+
})
213+
}
214+
215+
/// Get example data by ID
216+
///
217+
/// This resource demonstrates parameterized resources using URI templates.
218+
/// The {id} parameter is extracted from the URI when the resource is accessed.
219+
#[mcp_resource(
220+
uri_template = "template://example-data/{id}",
221+
name = "example_data",
222+
description = "Example data entry by ID",
223+
mime_type = "application/json"
224+
)]
225+
pub async fn example_data_resource(&self, id: String) -> anyhow::Result<ExampleData> {
226+
// In a real implementation, you'd look up the data by ID
227+
// For this template, we'll generate example data
228+
let id_num = id.parse::<u64>().unwrap_or(1);
229+
230+
Ok(ExampleData {
231+
id: id_num,
232+
name: format!("Example Item {}", id_num),
233+
value: (id_num as f64) * 1.5,
234+
tags: vec![
235+
"example".to_string(),
236+
"template".to_string(),
237+
format!("id-{}", id_num),
238+
],
239+
})
240+
}
136241
}
137242

138243
// Add any additional implementation methods here that are NOT tools

0 commit comments

Comments
 (0)