Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
396 changes: 394 additions & 2 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions cli/golem-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ nondestructive = { workspace = true }
phf = { workspace = true }
prettyplease = { workspace = true }
proc-macro2 = { workspace = true }

quote = { workspace = true }
regex = { workspace = true }
reqwest = { workspace = true }
Expand Down Expand Up @@ -124,6 +125,11 @@ wit-encoder = { workspace = true }
wit-parser = { workspace = true }
webbrowser = { workspace = true }
warp = { workspace = true }
actix-web = "4.12.0"
rmcp-actix-web = "0.8.17"
rmcp = { version = "0.9.1", features = ["server", "transport-streamable-http-server-session"] }



[target.'cfg(not(any(target_os = "windows", target_vendor = "apple")))'.dependencies]
openssl = { workspace = true }
Expand Down
8 changes: 7 additions & 1 deletion cli/golem-cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub struct GolemCliCommand {
pub global_flags: GolemCliGlobalFlags,

#[clap(subcommand)]
pub subcommand: GolemCliSubcommand,
pub subcommand: Option<GolemCliSubcommand>,
}

// NOTE: inlined from clap-verbosity-flag, so we can override display order,
Expand Down Expand Up @@ -161,6 +161,12 @@ pub struct GolemCliGlobalFlags {
#[arg(long, global = true, display_order = 113)]
pub template_group: Option<String>,

#[arg(long, global = true, display_order = 113)]
pub serve: bool,

#[arg(long, global = true, requires = "serve", display_order = 114)]
pub serve_port: Option<u16>,

#[command(flatten)]
verbosity: Verbosity,

Expand Down
61 changes: 46 additions & 15 deletions cli/golem-cli/src/command_handler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,18 +137,19 @@ impl<Hooks: CommandHandlerHooks + 'static> CommandHandler<Hooks> {
let result = match GolemCliCommand::try_parse_from_lenient(args_iterator, true) {
GolemCliCommandParseResult::FullMatch(command) => {
#[cfg(feature = "server-commands")]
let verbosity = if matches!(command.subcommand, GolemCliSubcommand::Server { .. }) {
Hooks::override_verbosity(command.global_flags.verbosity())
} else {
command.global_flags.verbosity()
};
let verbosity =
if matches!(command.subcommand, Some(GolemCliSubcommand::Server { .. })) {
Hooks::override_verbosity(command.global_flags.verbosity())
} else {
command.global_flags.verbosity()
};
#[cfg(feature = "server-commands")]
let pretty_mode = if matches!(command.subcommand, GolemCliSubcommand::Server { .. })
{
Hooks::override_pretty_mode()
} else {
false
};
let pretty_mode =
if matches!(command.subcommand, Some(GolemCliSubcommand::Server { .. })) {
Hooks::override_pretty_mode()
} else {
false
};
#[cfg(not(feature = "server-commands"))]
let verbosity = command.global_flags.verbosity();
#[cfg(not(feature = "server-commands"))]
Expand Down Expand Up @@ -256,6 +257,10 @@ impl<Hooks: CommandHandlerHooks + 'static> CommandHandler<Hooks> {

async fn handle_command(&self, command: GolemCliCommand) -> anyhow::Result<()> {
match command.subcommand {
Some(GolemCliSubcommand::App { subcommand }) => {
self.ctx.app_handler().handle_command(subcommand).await
}
Some(GolemCliSubcommand::Component { subcommand }) => {
// App scoped root commands
GolemCliSubcommand::New {
application_name,
Expand Down Expand Up @@ -359,12 +364,16 @@ impl<Hooks: CommandHandlerHooks + 'static> CommandHandler<Hooks> {
.handle_command(subcommand)
.await
}
GolemCliSubcommand::Agent { subcommand } => {
Some(GolemCliSubcommand::Agent { subcommand }) => {
self.ctx.worker_handler().handle_command(subcommand).await
}
GolemCliSubcommand::Api { subcommand } => {
Some(GolemCliSubcommand::Api { subcommand }) => {
self.ctx.api_handler().handle_command(subcommand).await
}
Some(GolemCliSubcommand::Plugin { subcommand }) => {
self.ctx.plugin_handler().handle_command(subcommand).await
}
Some(GolemCliSubcommand::Profile { subcommand }) => {
// TODO: atomic
/*
GolemCliSubcommand::Plugin { subcommand } => {
Expand All @@ -375,14 +384,36 @@ impl<Hooks: CommandHandlerHooks + 'static> CommandHandler<Hooks> {
self.ctx.profile_handler().handle_command(subcommand).await
}
#[cfg(feature = "server-commands")]
GolemCliSubcommand::Server { subcommand } => {
Some(GolemCliSubcommand::Server { subcommand }) => {
self.hooks
.handler_server_commands(self.ctx.clone(), subcommand)
.await
}
GolemCliSubcommand::Cloud { subcommand } => {
Some(GolemCliSubcommand::Cloud { subcommand }) => {
self.ctx.cloud_handler().handle_command(subcommand).await
}
Some(GolemCliSubcommand::Repl {
component_name,
revision,
deploy_args,
script,
script_file,
disable_stream,
}) => {
self.ctx
.rib_repl_handler()
.cmd_repl(
component_name.component_name,
revision,
deploy_args.as_ref(),
script,
script_file,
!disable_stream,
)
.await
}
Some(GolemCliSubcommand::Completion { shell }) => self.cmd_completion(shell),
None => Err(anyhow::anyhow!("Missing subcommand")),
GolemCliSubcommand::Completion { shell } => self.cmd_completion(shell),
}
}
Expand Down
1 change: 1 addition & 0 deletions cli/golem-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub mod error;
pub mod fs;
pub mod fuzzy;
pub mod log;
pub mod mcp;
pub mod model;
pub mod validation;
pub mod wasm_rpc_stubgen;
Expand Down
33 changes: 33 additions & 0 deletions cli/golem-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
// limitations under the License.

use crate::hooks::NoHooks;
use golem_cli::command::GolemCliCommand;
use golem_cli::command::GolemCliCommandParseResult;
use golem_cli::command_handler::CommandHandler;
use golem_cli::mcp::context::McpContext;
use golem_cli::mcp::server;
use std::process::ExitCode;
use std::sync::Arc;

Expand Down Expand Up @@ -65,6 +69,35 @@ mod hooks {
}

fn main() -> ExitCode {
let args: Vec<_> = std::env::args_os().collect();
let parse_result = GolemCliCommand::try_parse_from_lenient(&args, true);
// Try to parse to check for serve mode
if let GolemCliCommandParseResult::FullMatch(cli) = parse_result {
if cli.global_flags.serve {
let port = cli.global_flags.serve_port.unwrap_or(1232);
println!("golem-cli running MCP Server at port {}", port);

return tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("Failed to build tokio runtime for MCP server")
.block_on(async {
match server::serve(
Arc::new(McpContext::new(std::env::current_dir().unwrap())),
port,
)
.await
{
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("MCP server error: {}", e);
ExitCode::FAILURE
}
}
});
}
}

tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
Expand Down
12 changes: 12 additions & 0 deletions cli/golem-cli/src/mcp/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use std::path::PathBuf;

#[derive(Clone, Debug)]
pub struct McpContext {
pub working_dir: PathBuf,
}

impl McpContext {
pub fn new(working_dir: PathBuf) -> Self {
Self { working_dir }
}
}
Loading