Chapter 7: Adding a Backend Tool
TL;DR
- Open
src/lib.rsin your pack. - Define a tool with typed input/output.
- Register the tool in your MCP server.
- Run
worka devand test the UI action.
Our user interface is ready, but it can't do anything yet because the greet tool doesn't exist on the backend. In this chapter, we will implement it.
Step 1: Locate your pack code
In Worka v2, each pack exposes a single MCP server in src/lib.rs.
This file contains the tool definitions and the pack entry points.
Step 2: Define the tool’s data structures
It's a best practice to define the expected input and output of your tool using Rust structs. This makes your code type-safe and easier to understand. We will use the serde library, which is included by default, to automatically serialize and deserialize these structs from JSON.
Add these structs to the top of your main.rs file:
use serde::{Deserialize, Serialize};
// Describes the JSON parameters we expect from the frontend
#[derive(Deserialize)]
struct GreetParams {
name: String,
}
// Describes the JSON object we will send back
#[derive(Serialize)]
struct GreetResponse {
greeting: String,
}
Step 3: Implement the tool function
A "Tool" in an MCP server is simply an async function that receives a ToolRequest and returns a ToolResponse. Let's create a function for our greet tool.
use rmcp::server::{ToolRequest, ToolResponse};
use serde_json::json;
// ... (structs from above)
async fn greet_tool(req: ToolRequest) -> ToolResponse {
// Deserialize the incoming JSON params into our GreetParams struct
let params: GreetParams = serde_json::from_value(req.params).unwrap();
// Construct the response data
let response = GreetResponse {
greeting: format!("Hello, {}!", params.name),
};
// Return a successful response, converting our struct back to JSON
ToolResponse::success(json!(response))
}
Step 4: Register the tool
Register the tool in the MCP server builder so the host can discover it. The SDK exposes a typed interface so tool inputs and outputs remain structured and validated.
Step 5: Test the full flow
Save the main.rs file. In your terminal, the worka dev server will notice the change, display compilation progress for your Rust code, and automatically restart the backend server.
Now, go back to the Worka application and open your view. Trigger the UI action and confirm the tool response is rendered.