Crates.io | pulseengine-mcp-macros |
lib.rs | pulseengine-mcp-macros |
version | 0.10.0 |
created_at | 2025-07-27 16:11:07.929358+00 |
updated_at | 2025-08-15 04:22:11.438237+00 |
description | Procedural macros for PulseEngine MCP Framework - simplified server and tool development |
homepage | https://github.com/pulseengine/mcp |
repository | https://github.com/pulseengine/mcp |
max_upload_size | |
id | 1770196 |
size | 402,381 |
Procedural macros for the PulseEngine MCP Framework that dramatically simplify server and tool development.
Add to your Cargo.toml
:
[dependencies]
# Core macros
pulseengine-mcp-macros = "0.7.1"
# Required dependencies for generated code
pulseengine-mcp-protocol = "0.7.1"
pulseengine-mcp-server = "0.7.1"
pulseengine-mcp-transport = "0.7.1"
async-trait = "0.1"
thiserror = "1.0"
tokio = { version = "1.0", features = ["full"] }
# For STDIO transport (recommended)
tracing = "0.1"
tracing-subscriber = "0.3"
use pulseengine_mcp_macros::{mcp_server, mcp_tools};
#[mcp_server(name = "Hello Server")]
#[derive(Default, Clone)]
pub struct HelloServer;
#[mcp_tools]
impl HelloServer {
/// Say hello to someone
pub async fn hello(&self, name: Option<String>) -> anyhow::Result<String> {
Ok(format!("Hello, {}!", name.unwrap_or_else(|| "World".to_string())))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// CRITICAL for STDIO: Configure logging to stderr
HelloServer::configure_stdio_logging();
let server = HelloServer::with_defaults().serve_stdio().await?;
server.run().await?;
Ok(())
}
These dependencies are always required when using #[mcp_server]
:
pulseengine-mcp-protocol = "0.7.1"
pulseengine-mcp-server = "0.7.1"
pulseengine-mcp-transport = "0.7.1"
async-trait = "0.1"
thiserror = "1.0"
tokio = { version = "1.0", features = ["full"] }
stdio-logging
feature)For STDIO transport compatibility:
pulseengine-mcp-macros = { version = "0.7.1", features = ["stdio-logging"] }
tracing-subscriber = "0.3"
auth
feature + auth parameter)Important: Authentication is opt-in. By default, servers have no authentication.
When using auth = "memory"
, auth = "file"
, etc.:
pulseengine-mcp-macros = { version = "0.7.1", features = ["auth"] }
pulseengine-mcp-auth = "0.7.1"
#[mcp_server]
Generates a complete MCP server from a struct:
#[mcp_server(
name = "My Server",
version = "1.0.0",
description = "Server description",
auth = "memory" // Optional: "memory", "file", "disabled"
)]
#[derive(Default, Clone)]
pub struct MyServer;
Generated methods:
MyServer::with_defaults()
- Create instanceMyServer::serve_stdio()
- Start STDIO transportMyServer::serve_http(port)
- Start HTTP transportMyServer::configure_stdio_logging()
- Fix STDIO logging#[mcp_tools]
Automatically discovers public methods as MCP tools:
#[mcp_tools]
impl MyServer {
/// Tool description from doc comment
pub async fn my_tool(&self, param: String) -> anyhow::Result<String> {
Ok(format!("Result: {}", param))
}
}
Note: Currently passthrough - full implementation coming soon.
For MCP clients like Claude Desktop:
// CRITICAL: Configure logging first!
MyServer::configure_stdio_logging();
let server = MyServer::with_defaults().serve_stdio().await?;
For web-based clients:
let server = MyServer::with_defaults().serve_http(8080).await?;
For real-time clients:
let server = MyServer::with_defaults().serve_websocket(8080).await?;
By default, servers have no authentication. To enable authentication, add the auth
parameter:
// Memory-based (development)
#[mcp_server(name = "Dev Server", auth = "memory")]
// File-based (production)
#[mcp_server(name = "Prod Server", auth = "file", app_name = "my-app")]
// Explicitly disabled (same as default)
#[mcp_server(name = "Test Server", auth = "disabled")]
// No auth parameter = no authentication (default)
#[mcp_server(name = "Simple Server")]
Requires: pulseengine-mcp-auth
dependency and auth
feature only when auth
parameter is specified.
⚠️ CRITICAL: For STDIO transport, you MUST configure logging to go to stderr, not stdout. Stdout is reserved for JSON-RPC messages only.
// Always call this before serve_stdio()
MyServer::configure_stdio_logging();
Failure to do this will break MCP client compatibility with errors like:
Error from MCP server: SyntaxError: Unexpected token '2025-0"... is not valid JSON
See examples/hello-world-stdio-fixed/
for a working example with proper STDIO logging configuration.
Licensed under either of
at your option.