|
1 | | -# rmcp-macros |
2 | | - |
3 | | -`rmcp-macros` is a procedural macro library for the Rust Model Context Protocol (RMCP) SDK, providing macros that facilitate the development of RMCP applications. |
| 1 | +<style> |
| 2 | +.rustdoc-hidden { display: none; } |
| 3 | +</style> |
4 | 4 |
|
5 | | -## Features |
| 5 | +<div class="rustdoc-hidden"> |
6 | 6 |
|
7 | | -This library primarily provides the following macros: |
| 7 | +# rmcp-macros |
8 | 8 |
|
9 | | -- `#[tool]`: Used to mark functions as RMCP tools, automatically generating necessary metadata and invocation mechanisms |
| 9 | +[](https://crates.io/crates/rmcp-macros) |
| 10 | +[](https://docs.rs/rmcp-macros) |
10 | 11 |
|
11 | | -## Usage |
| 12 | +</div> |
12 | 13 |
|
13 | | -### tool |
| 14 | +`rmcp-macros` is a procedural macro library for the Rust Model Context Protocol (RMCP) SDK, providing macros that facilitate the development of RMCP applications. |
14 | 15 |
|
15 | | -This macro is used to mark a function as a tool handler. |
| 16 | +## Available Macros |
16 | 17 |
|
17 | | -This will generate a function that return the attribute of this tool, with type `rmcp::model::Tool`. |
| 18 | +| Macro | Description | |
| 19 | +|-------|-------------| |
| 20 | +| [`#[tool]`][tool] | Mark a function as an MCP tool handler | |
| 21 | +| [`#[tool_router]`][tool_router] | Generate a tool router from an impl block | |
| 22 | +| [`#[tool_handler]`][tool_handler] | Generate `call_tool` and `list_tools` handler methods | |
| 23 | +| [`#[prompt]`][prompt] | Mark a function as an MCP prompt handler | |
| 24 | +| [`#[prompt_router]`][prompt_router] | Generate a prompt router from an impl block | |
| 25 | +| [`#[prompt_handler]`][prompt_handler] | Generate `get_prompt` and `list_prompts` handler methods | |
18 | 26 |
|
19 | | -#### Usage |
| 27 | +[tool]: https://docs.rs/rmcp-macros/latest/rmcp_macros/attr.tool.html |
| 28 | +[tool_router]: https://docs.rs/rmcp-macros/latest/rmcp_macros/attr.tool_router.html |
| 29 | +[tool_handler]: https://docs.rs/rmcp-macros/latest/rmcp_macros/attr.tool_handler.html |
| 30 | +[prompt]: https://docs.rs/rmcp-macros/latest/rmcp_macros/attr.prompt.html |
| 31 | +[prompt_router]: https://docs.rs/rmcp-macros/latest/rmcp_macros/attr.prompt_router.html |
| 32 | +[prompt_handler]: https://docs.rs/rmcp-macros/latest/rmcp_macros/attr.prompt_handler.html |
20 | 33 |
|
21 | | -| field | type | usage | |
22 | | -| :- | :- | :- | |
23 | | -| `name` | `String` | The name of the tool. If not provided, it defaults to the function name. | |
24 | | -| `description` | `String` | A description of the tool. The document of this function will be used. | |
25 | | -| `input_schema` | `Expr` | A JSON Schema object defining the expected parameters for the tool. If not provide, if will use the json schema of its argument with type `Parameters<T>` | |
26 | | -| `annotations` | `ToolAnnotationsAttribute` | Additional tool information. Defaults to `None`. | |
| 34 | +## Quick Example |
27 | 35 |
|
28 | | -#### Example |
| 36 | +```rust,ignore |
| 37 | +use rmcp::{tool, tool_router, tool_handler, ServerHandler, model::*}; |
29 | 38 |
|
30 | | -```rust |
31 | | -#[tool(name = "my_tool", description = "This is my tool", annotations(title = "我的工具", read_only_hint = true))] |
32 | | -pub async fn my_tool(param: Parameters<MyToolParam>) { |
33 | | - // handling tool request |
| 39 | +#[derive(Clone)] |
| 40 | +struct MyServer { |
| 41 | + tool_router: rmcp::handler::server::tool::ToolRouter<Self>, |
34 | 42 | } |
35 | | -``` |
36 | | - |
37 | | -### tool_router |
38 | | - |
39 | | -This macro is used to generate a tool router based on functions marked with `#[rmcp::tool]` in an implementation block. |
40 | | - |
41 | | -It creates a function that returns a `ToolRouter` instance. |
42 | | - |
43 | | -In most case, you need to add a field for handler to store the router information and initialize it when creating handler, or store it with a static variable. |
44 | | - |
45 | | -#### Usage |
46 | 43 |
|
47 | | -| field | type | usage | |
48 | | -| :- | :- | :- | |
49 | | -| `router` | `Ident` | The name of the router function to be generated. Defaults to `tool_router`. | |
50 | | -| `vis` | `Visibility` | The visibility of the generated router function. Defaults to empty. | |
51 | | - |
52 | | -#### Example |
53 | | - |
54 | | -```rust |
55 | 44 | #[tool_router] |
56 | | -impl MyToolHandler { |
57 | | - #[tool] |
58 | | - pub fn my_tool() { |
59 | | - |
60 | | - } |
61 | | - |
62 | | - pub fn new() -> Self { |
63 | | - Self { |
64 | | - // the default name of tool router will be `tool_router` |
65 | | - tool_router: Self::tool_router(), |
66 | | - } |
67 | | - } |
68 | | -} |
69 | | -``` |
70 | | - |
71 | | -Or specify the visibility and router name, which would be helpful when you want to combine multiple routers into one: |
72 | | - |
73 | | -```rust |
74 | | -mod a { |
75 | | - #[tool_router(router = tool_router_a, vis = "pub")] |
76 | | - impl MyToolHandler { |
77 | | - #[tool] |
78 | | - fn my_tool_a() { |
79 | | - |
80 | | - } |
| 45 | +impl MyServer { |
| 46 | + #[tool(description = "Say hello")] |
| 47 | + async fn hello(&self) -> String { |
| 48 | + "Hello, world!".into() |
81 | 49 | } |
82 | 50 | } |
83 | 51 |
|
84 | | -mod b { |
85 | | - #[tool_router(router = tool_router_b, vis = "pub")] |
86 | | - impl MyToolHandler { |
87 | | - #[tool] |
88 | | - fn my_tool_b() { |
89 | | - |
90 | | - } |
91 | | - } |
92 | | -} |
93 | | - |
94 | | -impl MyToolHandler { |
95 | | - fn new() -> Self { |
96 | | - Self { |
97 | | - tool_router: self::tool_router_a() + self::tool_router_b(), |
98 | | - } |
99 | | - } |
100 | | -} |
101 | | -``` |
102 | | - |
103 | | -### tool_handler |
104 | | - |
105 | | -This macro will generate the handler for `tool_call` and `list_tools` methods in the implementation block, by using an existing `ToolRouter` instance. |
106 | | - |
107 | | -#### Usage |
108 | | - |
109 | | -| field | type | usage | |
110 | | -| :- | :- | :- | |
111 | | -| `router` | `Expr` | The expression to access the `ToolRouter` instance. Defaults to `self.tool_router`. | |
112 | | - |
113 | | -#### Example |
114 | | -```rust |
115 | 52 | #[tool_handler] |
116 | | -impl ServerHandler for MyToolHandler { |
117 | | - // ...implement other handler |
118 | | -} |
119 | | -``` |
120 | | - |
121 | | -or using a custom router expression: |
122 | | -```rust |
123 | | -#[tool_handler(router = self.get_router().await)] |
124 | | -impl ServerHandler for MyToolHandler { |
125 | | - // ...implement other handler |
126 | | -} |
127 | | -``` |
128 | | - |
129 | | -#### Explained |
130 | | -This macro will be expended to something like this: |
131 | | -```rust |
132 | | -impl ServerHandler for MyToolHandler { |
133 | | - async fn call_tool( |
134 | | - &self, |
135 | | - request: CallToolRequestParam, |
136 | | - context: RequestContext<RoleServer>, |
137 | | - ) -> Result<CallToolResult, rmcp::ErrorData> { |
138 | | - let tcc = ToolCallContext::new(self, request, context); |
139 | | - self.tool_router.call(tcc).await |
140 | | - } |
141 | | - |
142 | | - async fn list_tools( |
143 | | - &self, |
144 | | - _request: Option<PaginatedRequestParam>, |
145 | | - _context: RequestContext<RoleServer>, |
146 | | - ) -> Result<ListToolsResult, rmcp::ErrorData> { |
147 | | - let items = self.tool_router.list_all(); |
148 | | - Ok(ListToolsResult::with_all_items(items)) |
| 53 | +impl ServerHandler for MyServer { |
| 54 | + fn get_info(&self) -> ServerInfo { |
| 55 | + ServerInfo::default() |
149 | 56 | } |
150 | 57 | } |
151 | 58 | ``` |
152 | 59 |
|
153 | | - |
154 | | -## Advanced Features |
155 | | - |
156 | | -- Support for custom tool names and descriptions |
157 | | -- Automatic generation of tool descriptions from documentation comments |
158 | | -- JSON Schema generation for tool parameters |
| 60 | +See the [full documentation](https://docs.rs/rmcp-macros) for detailed usage of each macro. |
159 | 61 |
|
160 | 62 | ## License |
161 | 63 |
|
162 | | -Please refer to the LICENSE file in the project root directory. |
| 64 | +Please refer to the LICENSE file in the project root directory. |
0 commit comments