Skip to content
Merged
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
5b9b2e8
setup mcp server for golem
afsalthaj Feb 22, 2026
a9f66ff
setup mcp server for golem
afsalthaj Feb 22, 2026
03404e8
add mcp_integration branch
afsalthaj Feb 23, 2026
83a8a6a
start adding domain
afsalthaj Feb 23, 2026
bf9ae5c
avoid tool_handler
afsalthaj Feb 24, 2026
f115581
add mcp server
afsalthaj Feb 24, 2026
08d1265
Add session info
afsalthaj Feb 24, 2026
5d46399
add mcp server
afsalthaj Feb 24, 2026
e779e9e
add mcp server
afsalthaj Feb 24, 2026
8c7fdee
fix all tests
afsalthaj Feb 24, 2026
751defb
fix the deployment flow
afsalthaj Feb 24, 2026
8c787e7
update sql
afsalthaj Feb 24, 2026
3ef0f5a
fix todo
afsalthaj Feb 24, 2026
35a14a0
return actual agent types
afsalthaj Feb 24, 2026
943cd81
return actual agent types
afsalthaj Feb 24, 2026
bcb8007
mcp server gateway failed
afsalthaj Feb 24, 2026
4c038d5
add mcp server
afsalthaj Feb 24, 2026
d43acb6
add mcp deployment api for cli
afsalthaj Feb 24, 2026
1939bab
make sure cli has access to mcp client
afsalthaj Feb 24, 2026
bec6269
update mcp server
afsalthaj Feb 24, 2026
07c21ba
Add some info
afsalthaj Feb 24, 2026
5c83e3b
Make sure an initial list tools is working
afsalthaj Feb 24, 2026
2ee443a
fix blocking issues
afsalthaj Feb 24, 2026
9850e50
reformat code
afsalthaj Feb 24, 2026
074f35f
append tool name
afsalthaj Feb 24, 2026
c4baf51
wire in worker service
afsalthaj Feb 24, 2026
3f91f33
wire in worker service
afsalthaj Feb 25, 2026
77e2b71
fix invoke
afsalthaj Feb 25, 2026
a01788a
fix warnings
afsalthaj Feb 25, 2026
c1e857f
start cleaning up
afsalthaj Feb 25, 2026
fd8fb81
make sure to select a stable mcp protocol version
afsalthaj Feb 25, 2026
e874de9
Merge branch 'main' into mcp_integration
afsalthaj Feb 25, 2026
484c26c
fix and cleanup
afsalthaj Feb 25, 2026
6dd03a8
reformat code
afsalthaj Feb 25, 2026
bdacf4f
add TODOs
afsalthaj Feb 25, 2026
47a0607
make deployment mcp revision table, and make mcp part of plan and sum…
afsalthaj Feb 25, 2026
53aa8c9
more fixes
afsalthaj Feb 25, 2026
9a9a91e
reformat
afsalthaj Feb 25, 2026
6cbb2e1
fix imports
afsalthaj Feb 25, 2026
c09b120
fix clippy
afsalthaj Feb 25, 2026
6ed4019
make sure cli integration with bootstrapped mcp works
afsalthaj Feb 26, 2026
fc41c21
make sure cli integration with bootstrapped mcp works (#2838)
afsalthaj Feb 26, 2026
e56279c
fix clippy
afsalthaj Feb 26, 2026
7692fec
Merge remote-tracking branch 'origin/mcp_integration' into mcp_integr…
afsalthaj Feb 26, 2026
ed28cef
fix sqls
afsalthaj Feb 26, 2026
d0c6293
fix clippy
afsalthaj Feb 26, 2026
347aaa1
reformat code
afsalthaj Feb 26, 2026
3d8215b
avoid clone
afsalthaj Feb 26, 2026
aa08384
more fixes based on manual testing
afsalthaj Feb 26, 2026
4f34341
more fixes and cleanups
afsalthaj Feb 26, 2026
de382aa
add configs
afsalthaj Feb 26, 2026
11821de
make mcp port configurable and fix golem bin
afsalthaj Feb 26, 2026
641dddf
Extend schema and value mapping for all component-model types (#2847)
afsalthaj Feb 27, 2026
958d2d8
Merge branch 'main' into mcp_integration
afsalthaj Feb 27, 2026
46662b9
fix conflicts
afsalthaj Feb 27, 2026
9326e8f
reformat code
afsalthaj Feb 27, 2026
7185c7a
fix clippy
afsalthaj Feb 27, 2026
443e147
reformat
afsalthaj Feb 27, 2026
442ca73
fix diff
afsalthaj Mar 2, 2026
429b1c2
avoid group of mcp with http
afsalthaj Mar 2, 2026
0db7242
avoid bloating repo layer
afsalthaj Mar 2, 2026
11f60ed
remove comments
afsalthaj Mar 2, 2026
8f60155
dedicated environment action
afsalthaj Mar 2, 2026
6e50518
avoid traits
afsalthaj Mar 2, 2026
ceb265e
reformat code
afsalthaj Mar 2, 2026
c80ac3b
avoid mcp deployments clone
afsalthaj Mar 2, 2026
7ec273f
make domain non updatable
afsalthaj Mar 2, 2026
93e60dc
avoid confusing comments
afsalthaj Mar 2, 2026
5266dae
rename to get_active_compiled_mcps_for_domain
afsalthaj Mar 2, 2026
5ae8bbf
clean up
afsalthaj Mar 2, 2026
36ac434
remove domain from rev table
afsalthaj Mar 2, 2026
7226b2d
reuse registered implementor
afsalthaj Mar 2, 2026
c4afc83
fix other inconsistencies of mcp compared to http
afsalthaj Mar 2, 2026
0355078
Merge branch 'main' into mcp_integration
afsalthaj Mar 2, 2026
c8c91ef
resolve conflicts and merge with main
afsalthaj Mar 2, 2026
013698f
update openapi
afsalthaj Mar 2, 2026
7d64cd3
fix tests
afsalthaj Mar 2, 2026
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
361 changes: 344 additions & 17 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ criterion = "0.5"
crossbeam-channel = "0.5.15"
crossterm = "0.28.1"
darling = "0.20.11"
dashmap = "7.0.0-rc2"
derive_more = { version = "2.0.1", features = ["display", "into", "from_str"] }
desert_rust = { version = "0.1.7", features = ["bigdecimal", "uuid", "chrono", "nonempty-collections", "serde-json", "bit-vec", "url", "mac_address"] }
dir-diff = "0.3.3"
Expand Down Expand Up @@ -205,6 +206,7 @@ regex = "1.11.1"
reqwest = { version = "0.12.13", features = ["gzip", "json", "multipart", "stream", ] }
ringbuf = "0.4.7"
rlimit = "0.10.2"
rmcp = {version = "0.16.0", features = ["server", "transport-streamable-http-server"] }
rsa = "0.9.7"

rustc-hash = "2.1.1"
Expand Down
6 changes: 5 additions & 1 deletion cli/golem-cli/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use golem_client::api::{
ApiDeploymentClientLive, ApiDomainClientLive, ApiSecurityClientLive, ApplicationClientLive,
ComponentClientLive, DeploymentClientLive, EnvironmentClientLive, GrantClientLive,
HealthCheckClientLive, HttpApiDefinitionClientLive, LimitsClientLive, LoginClientLive,
PluginClientLive, TokenClientLive, WorkerClientLive,
McpDeploymentClientLive, PluginClientLive, TokenClientLive, WorkerClientLive,
};
use golem_client::{Context as ClientContext, Security};
use golem_common::model::account::AccountId;
Expand All @@ -47,6 +47,7 @@ pub struct GolemClients {
pub grant: GrantClientLive,
pub limits: LimitsClientLive,
pub login: LoginClientLive,
pub mcp_deployment: McpDeploymentClientLive,
pub plugin: PluginClientLive,
pub token: TokenClientLive,
pub worker: WorkerClientLive,
Expand Down Expand Up @@ -159,6 +160,9 @@ impl GolemClients {
login: LoginClientLive {
context: login_context(),
},
mcp_deployment: McpDeploymentClientLive {
context: registry_context(),
},
plugin: PluginClientLive {
context: registry_context(),
},
Expand Down
7 changes: 7 additions & 0 deletions cli/golem-cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1573,6 +1573,10 @@ pub mod server {
#[clap(long)]
pub custom_request_port: Option<u16>,

/// Port to serve custom requests on, defaults to 9006
#[clap(long)]
pub mcp_port: Option<u16>,

/// Directory to store data in. Defaults to $XDG_STATE_HOME/golem
#[clap(long)]
pub data_dir: Option<PathBuf>,
Expand All @@ -1594,6 +1598,9 @@ pub mod server {
pub fn custom_request_port(&self) -> u16 {
self.custom_request_port.unwrap_or(9006)
}
pub fn mcp_port(&self) -> u16 {
self.mcp_port.unwrap_or(9007)
}
}

#[derive(Debug, Subcommand)]
Expand Down
180 changes: 178 additions & 2 deletions cli/golem-cli/src/command_handler/api/deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ use crate::context::Context;
use crate::error::service::{AnyhowMapServiceError, ServiceError};
use crate::log::{log_action, log_warn_action, LogColorize, LogIndent};
use crate::model::environment::{EnvironmentResolveMode, ResolvedEnvironmentIdentity};
use crate::model::http_api::HttpApiDeploymentDeployProperties;
use crate::model::http_api::{HttpApiDeploymentDeployProperties, McpDeploymentDeployProperties};
use crate::model::text::http_api_deployment::HttpApiDeploymentGetView;
use anyhow::{anyhow, bail};
use golem_client::api::ApiDeploymentClient;
use golem_client::api::{ApiDeploymentClient, McpDeploymentClient};
use golem_common::cache::SimpleCache;
use golem_common::model::deployment::DeploymentPlanHttpApiDeploymentEntry;
use golem_common::model::diff;
Expand Down Expand Up @@ -158,6 +158,34 @@ impl ApiDeploymentCommandHandler {
.unwrap_or_default())
}

pub async fn deployable_manifest_mcp_deployments(
&self,
environment_name: &EnvironmentName,
) -> anyhow::Result<BTreeMap<Domain, crate::model::http_api::McpDeploymentDeployProperties>>
{
let app_ctx = self.ctx.app_context_lock().await;
let app_ctx = app_ctx.some_or_err()?;
Ok(app_ctx
.application()
.mcp_deployments(environment_name)
.map(
|deployments: &BTreeMap<
golem_common::model::domain_registration::Domain,
crate::model::app::WithSource<
crate::model::http_api::McpDeploymentDeployProperties,
>,
>| {
deployments
.iter()
.map(|(domain, mcp_deployment)| {
(domain.clone(), mcp_deployment.value.clone())
})
.collect::<BTreeMap<_, _>>()
},
)
.unwrap_or_default())
}

pub async fn get_http_api_deployment_revision_by_id(
&self,
http_api_deployment_id: &HttpApiDeploymentId,
Expand Down Expand Up @@ -337,4 +365,152 @@ impl ApiDeploymentCommandHandler {

Ok(())
}

pub async fn create_staged_mcp_deployment(
&self,
environment_id: &ResolvedEnvironmentIdentity,
domain: &Domain,
deployable_mcp_deployment: &McpDeploymentDeployProperties,
) -> anyhow::Result<()> {
let clients = self.ctx.golem_clients().await?;

log_action(
"Creating",
format!("MCP deployment {}", domain.0.log_color_highlight()),
);
let _indent = LogIndent::new();

let agents = deployable_mcp_deployment
.agents
.iter()
.map(|(k, _v)| {
(
k.clone(),
golem_common::model::mcp_deployment::McpDeploymentAgentOptions::default(),
)
})
.collect();

let mcp_creation = golem_common::model::mcp_deployment::McpDeploymentCreation {
domain: domain.clone(),
agents,
};

let create = async || {
clients
.mcp_deployment
.create_mcp_deployment(&environment_id.environment_id.0, &mcp_creation)
.await
.map_err(ServiceError::from)
};

let deployment = match create().await {
Ok(result) => Ok(result),
Err(err) if err.is_domain_is_not_registered() => {
self.ctx
.api_domain_handler()
.register_missing_domain(&environment_id.environment_id, domain)
.await?;

create().await
}
Err(err) => Err(err),
}?;

log_action(
"Created",
format!(
"MCP deployment revision: {} {}",
deployment.domain.0.log_color_highlight(),
deployment.revision.to_string().log_color_highlight()
),
);

Ok(())
}

pub async fn delete_staged_mcp_deployment(
&self,
mcp_deployment: &golem_common::model::deployment::DeploymentPlanMcpDeploymentEntry,
) -> anyhow::Result<()> {
log_warn_action(
"Deleting",
format!(
"MCP deployment {}",
mcp_deployment.domain.0.log_color_highlight()
),
);
let _indent = LogIndent::new();

self.ctx
.golem_clients()
.await?
.mcp_deployment
.delete_mcp_deployment(&mcp_deployment.id.0, mcp_deployment.revision.into())
.await
.map_service_error()?;

log_action(
"Deleted",
format!(
"MCP deployment revision: {} {}",
mcp_deployment.domain.0.log_color_highlight(),
mcp_deployment.revision.to_string().log_color_highlight()
),
);

Ok(())
}

pub async fn update_staged_mcp_deployment(
&self,
mcp_deployment: &golem_common::model::deployment::DeploymentPlanMcpDeploymentEntry,
update: &golem_common::model::mcp_deployment::McpDeploymentUpdate,
diff: &diff::DiffForHashOf<diff::McpDeployment>,
) -> anyhow::Result<()> {
log_action(
"Updating",
format!(
"MCP deployment {}",
mcp_deployment.domain.0.log_color_highlight()
),
);
let _indent = LogIndent::new();

let agents_changed = match diff {
diff::DiffForHashOf::HashDiff { .. } => true,
diff::DiffForHashOf::ValueDiff { diff } => !diff.agents_changes.is_empty(),
};

let deployment = self
.ctx
.golem_clients()
.await?
.mcp_deployment
.update_mcp_deployment(
&mcp_deployment.id.0,
&golem_common::model::mcp_deployment::McpDeploymentUpdate {
current_revision: update.current_revision,
domain: update.domain.clone(),
agents: if agents_changed {
update.agents.clone()
} else {
None
},
},
)
.await
.map_service_error()?;

log_action(
"Updated",
format!(
"MCP deployment revision: {} {}",
deployment.domain.0.log_color_highlight(),
deployment.revision.to_string().log_color_highlight()
),
);

Ok(())
}
}
45 changes: 44 additions & 1 deletion cli/golem-cli/src/command_handler/app/deploy_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

use crate::model::component::{show_exported_agents, ComponentDeployProperties};
use crate::model::environment::ResolvedEnvironmentIdentity;
use crate::model::http_api::HttpApiDeploymentDeployProperties;
use crate::model::http_api::{HttpApiDeploymentDeployProperties, McpDeploymentDeployProperties};
use crate::model::text::component::is_sensitive_env_var_name;
use anyhow::bail;
use golem_client::model::{DeploymentPlan, DeploymentSummary};
Expand All @@ -38,6 +38,8 @@ pub struct DeployQuickDiff {
pub deployable_manifest_components: BTreeMap<ComponentName, ComponentDeployProperties>,
pub deployable_manifest_http_api_deployments:
BTreeMap<Domain, HttpApiDeploymentDeployProperties>,
#[allow(dead_code)]
pub deployable_manifest_mcp_deployments: BTreeMap<Domain, McpDeploymentDeployProperties>,
pub diffable_local_deployment: diff::Deployment,
pub local_deployment_hash: diff::Hash,
}
Expand Down Expand Up @@ -75,6 +77,8 @@ pub struct DeployDiff {
pub environment: ResolvedEnvironmentIdentity,
pub deployable_components: BTreeMap<ComponentName, ComponentDeployProperties>,
pub deployable_http_api_deployments: BTreeMap<Domain, HttpApiDeploymentDeployProperties>,
#[allow(dead_code)]
pub deployable_mcp_deployments: BTreeMap<Domain, McpDeploymentDeployProperties>,
pub diffable_local_deployment: diff::Deployment,
pub local_deployment_hash: diff::Hash,
#[allow(unused)] // NOTE: for debug logs
Expand Down Expand Up @@ -226,6 +230,21 @@ impl DeployDiff {
})
}

#[allow(dead_code)]
pub fn deployable_manifest_mcp_deployment(
&self,
domain: &Domain,
) -> &McpDeploymentDeployProperties {
self.deployable_mcp_deployments
.get(domain)
.unwrap_or_else(|| {
panic!(
"Expected MCP deployment {} not found in deployable manifest",
domain
)
})
}

pub fn staged_component_identity(
&self,
component_name: &ComponentName,
Expand Down Expand Up @@ -258,6 +277,22 @@ impl DeployDiff {
})
}

pub fn staged_mcp_deployment_identity(
&self,
domain: &Domain,
) -> &golem_common::model::deployment::DeploymentPlanMcpDeploymentEntry {
self.staged_deployment
.mcp_deployments
.iter()
.find(|dep| &dep.domain == domain)
.unwrap_or_else(|| {
panic!(
"Expected MCP deployment {} not found in staged deployment",
domain
)
})
}

pub fn current_component_identity(
&self,
component_name: &ComponentName,
Expand Down Expand Up @@ -757,6 +792,14 @@ fn normalized_diff_deployment(
})
.map(|(k, v)| (k.clone(), v.clone()))
.collect(),
mcp_deployments: deployment
.mcp_deployments
.iter()
.filter(|(domain, _)| {
diff.is_some_and(|diff| diff.mcp_deployments.contains_key(*domain))
})
.map(|(k, v)| (k.clone(), v.clone()))
.collect(),
}
}

Expand Down
Loading
Loading