magi-code 0.96.2

Repository-aware CLI coding agent for terminal work
Documentation
//! Inventory-only MCP endpoint for Claude CLI. Never executes host tools.
use anyhow::{Context, Result, bail};
use serde_json::{Value, json};
use std::io::{self, BufRead, Read, Write};

pub(crate) fn serve_inventory(path: &std::path::Path) -> Result<()> {
    let source = std::fs::read(path).context("reading Claude tool inventory")?;
    if source.len() > 1024 * 1024 {
        bail!("Claude tool inventory too large");
    }
    let tools: Value = serde_json::from_slice(&source)?;
    let tools = tools
        .as_array()
        .context("Claude tool inventory must be a list")?;
    let stdin = io::stdin();
    let mut input = stdin.lock();
    let mut output = io::stdout().lock();
    let mut line = Vec::new();
    loop {
        line.clear();
        let count = (&mut input)
            .take(1024 * 1024 + 1)
            .read_until(b'\n', &mut line)?;
        if count == 0 {
            return Ok(());
        }
        if count > 1024 * 1024 || line.last() != Some(&b'\n') {
            bail!("Claude MCP request too large");
        }
        let request: Value = serde_json::from_slice(&line).context("invalid Claude MCP request")?;
        if let Some(id) = request.get("id") {
            let result = match request.get("method").and_then(Value::as_str) {
                Some("initialize") => {
                    json!({"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"magi-inert-inventory","version":"1"}})
                }
                Some("tools/list") => json!({"tools":tools}),
                Some("tools/call") => {
                    json!({"isError":true,"content":[{"type":"text","text":"Denied: only magi-code executes tools."}]})
                }
                _ => json!({}),
            };
            serde_json::to_writer(
                &mut output,
                &json!({"jsonrpc":"2.0","id":id,"result":result}),
            )?;
            output.write_all(b"\n")?;
            output.flush()?;
        }
    }
}