Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788//! beamdev - Main entry point.//!//! This binary starts the MCP server with stdio transport.
use beamdev::cookie::{DEFAULT_COOKIE_FILE, read_cookie};use beamdev::server::{BeamdevServer, FormatterMode};use clap::Parser;use rmcp::ServiceExt;use rmcp::transport::stdio;use std::path::PathBuf;use tracing_subscriber::EnvFilter;
/// beamdev - a BEAM development MCP server for coding agents////// Connects to one Erlang/BEAM node, named with --node, and runs code on it./// The connection is re-established whenever the node restarts. Code runs/// unsandboxed, so point this at development nodes only.#[derive(Parser, Debug)]#[command(name = "beamdev")]#[command(version, about, long_about = None)]struct Args { /// Output format mode for displaying Erlang terms. #[arg(long, default_value = "erlang", value_parser = parse_mode)] mode: FormatterMode,
/// Log level (trace, debug, info, warn, error). #[arg(long, default_value = "info")] log_level: String,
/// The node to work against, e.g. "myapp@localhost". #[arg(long, value_parser = parse_node)] node: String,
/// File holding the Erlang cookie the node authenticates with. #[arg(long, default_value = DEFAULT_COOKIE_FILE)] cookie_file: PathBuf,}
fn parse_mode(s: &str) -> Result<FormatterMode, String> { s.parse()}
fn parse_node(s: &str) -> Result<String, String> { if !s.contains('@') { return Err(format!( "invalid node name '{}'. Expected format: 'name@host'", s )); } Ok(s.to_string())}
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let args = Args::parse();
let filter = EnvFilter::try_new(&args.log_level).unwrap_or_else(|_| EnvFilter::new("info"));
tracing_subscriber::fmt() .with_env_filter(filter) .with_writer(std::io::stderr) .init();
let cookie = read_cookie(&args.cookie_file).map_err(|e| { format!( "cannot read the cookie from {}: {e}", args.cookie_file.display() ) })?;
tracing::info!( "Starting beamdev against {} (mode: {})", args.node, args.mode );
// The node is often still booting when the client launches us, so the // connection is the supervisor's job rather than a precondition for // serving. let server = BeamdevServer::new(args.mode, args.node, cookie); server.start();
let service = server.serve(stdio()).await?; service.waiting().await?;
Ok(())}