Skip to main content

liminal_cli/mcp/
template_tools.rs

1//! Proposals carry paths and invocation data; the server pins and holds them.
2
3use super::tools::ToolResult;
4use crate::network::Rail;
5use serde_json::{Map, Value, json};
6
7/// The proposal names no subjects or digest: both come from the server's site.
8#[must_use]
9pub fn tool_entries() -> Vec<Value> {
10    vec![
11        json!({"name":"propose_template","description":"Propose the bound builder's command for its site. The server validates operator roots, hashes the file and holds exact path, digest, args, environment names and subjects for a person's approval.",
12        "inputSchema":{"type":"object","required":["service","command","args","env","stop_timeout_ms"],"additionalProperties":false,
13            "properties":{"service":{"type":"string"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},
14                "env":{"type":"array","items":{"type":"string"}},"stop_timeout_ms":{"type":"integer","minimum":1},"operation":{"type":"string"}}}}),
15    ]
16}
17
18/// Forwards the invocation on the ticket's rail, never running the command.
19#[must_use]
20pub fn tool<R: Rail>(rail: &R, name: &str, arguments: &Map<String, Value>) -> Option<ToolResult> {
21    (name == "propose_template").then(|| super::plan_tools::forward(rail, name, arguments))
22}
23
24#[cfg(test)]
25#[path = "template_tools_tests.rs"]
26mod tests;