tessera-codegraph 0.8.0

A local, deterministic semantic code graph and MCP server for AI coding agents. 11 languages, personalized PageRank impact, hallucination validator, call-path tracing, graph export, incremental indexing.
Documentation
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::path::Path;

use anyhow::Result;

use crate::db;
use crate::mcp;

pub fn serve(addr: &str, db_path: &Path) -> Result<()> {
    let conn = db::open_existing(db_path)?;
    let listener = TcpListener::bind(addr)?;
    println!("Tessera MCP HTTP listening on http://{addr}");
    println!("  POST /mcp     JSON-RPC MCP endpoint");
    println!("  GET  /sse     readiness event stream");
    println!("  GET  /health  health check");

    for stream in listener.incoming() {
        match stream {
            Ok(mut stream) => {
                if let Err(error) = handle_stream(&mut stream, &conn, db_path) {
                    let _ = write_response(
                        &mut stream,
                        "500 Internal Server Error",
                        "text/plain; charset=utf-8",
                        &error.to_string(),
                    );
                }
            }
            Err(error) => eprintln!("mcp-http accept error: {error}"),
        }
    }
    Ok(())
}

fn handle_stream(
    stream: &mut TcpStream,
    conn: &rusqlite::Connection,
    db_path: &Path,
) -> Result<()> {
    let mut buffer = Vec::new();
    let mut chunk = [0u8; 8192];
    loop {
        let read = stream.read(&mut chunk)?;
        if read == 0 {
            break;
        }
        buffer.extend_from_slice(&chunk[..read]);
        if request_complete(&buffer) {
            break;
        }
        if buffer.len() > 2 * 1024 * 1024 {
            write_response(
                stream,
                "413 Payload Too Large",
                "text/plain; charset=utf-8",
                "request too large",
            )?;
            return Ok(());
        }
    }

    let request = String::from_utf8_lossy(&buffer);
    let Some((head, body)) = request.split_once("\r\n\r\n") else {
        write_response(
            stream,
            "400 Bad Request",
            "text/plain; charset=utf-8",
            "malformed HTTP request",
        )?;
        return Ok(());
    };
    let mut lines = head.lines();
    let request_line = lines.next().unwrap_or_default();
    let mut parts = request_line.split_whitespace();
    let method = parts.next().unwrap_or_default();
    let path = parts.next().unwrap_or_default();

    match (method, path) {
        ("GET", "/health") => write_response(
            stream,
            "200 OK",
            "application/json",
            r#"{"ok":true,"service":"tessera-mcp-http"}"#,
        )?,
        ("GET", "/sse") => {
            let body = "event: ready\ndata: {\"endpoint\":\"/mcp\"}\n\n";
            write_raw(
                stream,
                "HTTP/1.1 200 OK\r\nContent-Type: text/event-stream\r\nCache-Control: no-cache\r\nConnection: close\r\n\r\n",
                body,
            )?;
        }
        ("POST", "/mcp") => {
            let response = mcp::handle_json_rpc(conn, db_path, body);
            let json = serde_json::to_string(&response)?;
            write_response(stream, "200 OK", "application/json", &json)?;
        }
        _ => write_response(
            stream,
            "404 Not Found",
            "text/plain; charset=utf-8",
            "not found",
        )?,
    }
    Ok(())
}

fn request_complete(buffer: &[u8]) -> bool {
    let Some(header_end) = find_header_end(buffer) else {
        return false;
    };
    let head = String::from_utf8_lossy(&buffer[..header_end]);
    let content_length = head.lines().find_map(|line| {
        let (name, value) = line.split_once(':')?;
        if name.eq_ignore_ascii_case("content-length") {
            value.trim().parse::<usize>().ok()
        } else {
            None
        }
    });
    match content_length {
        Some(length) => buffer.len() >= header_end + 4 + length,
        None => true,
    }
}

fn find_header_end(buffer: &[u8]) -> Option<usize> {
    buffer.windows(4).position(|window| window == b"\r\n\r\n")
}

fn write_response(
    stream: &mut TcpStream,
    status: &str,
    content_type: &str,
    body: &str,
) -> Result<()> {
    let head = format!(
        "HTTP/1.1 {status}\r\nContent-Type: {content_type}\r\nContent-Length: {}\r\nConnection: close\r\n\r\n",
        body.len()
    );
    write_raw(stream, &head, body)
}

fn write_raw(stream: &mut TcpStream, head: &str, body: &str) -> Result<()> {
    stream.write_all(head.as_bytes())?;
    stream.write_all(body.as_bytes())?;
    stream.flush()?;
    Ok(())
}