Skip to content

Commit 09b4b06

Browse files
authored
clean ups and optimisation in mcp (#3012)
1 parent ce4a6e9 commit 09b4b06

File tree

8 files changed

+160
-110
lines changed

8 files changed

+160
-110
lines changed

golem-api-grpc/proto/golem/mcp/core.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ message CompiledMcp {
1414
string domain = 4;
1515
map<string, golem.registry.RegisteredAgentTypeImplementer> agent_type_implementers = 5;
1616
golem.customapi.SecuritySchemeDetails security_scheme = 6;
17+
repeated golem.registry.RegisteredAgentType registered_agent_types = 7;
1718
}

golem-registry-service/src/repo/model/deployment.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ impl TryFrom<DeploymentCompiledMcpRecord> for CompiledMcp {
599599
domain: Domain(value.domain),
600600
agent_type_implementers: mcp_data.implementers,
601601
security_scheme: None,
602+
registered_agent_types: Vec::new(),
602603
})
603604
}
604605
}

golem-registry-service/src/services/deployment/deployment_context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ impl DeploymentContext {
297297
domain: domain.clone(),
298298
agent_type_implementers,
299299
security_scheme,
300+
registered_agent_types: Vec::new(),
300301
};
301302
all_compiled_mcps.push(compiled_mcp);
302303
}

golem-registry-service/src/services/deployment/mcp.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::repo::deployment::DeploymentRepo;
22
use crate::repo::model::deployment::DeployRepoError;
33
use crate::services::security_scheme::SecuritySchemeService;
44
use golem_common::base_model::domain_registration::Domain;
5+
use golem_common::model::agent::RegisteredAgentType;
56
use golem_common::{SafeDisplay, error_forwarding};
67
use golem_service_base::custom_api::SecuritySchemeDetails;
78
use golem_service_base::mcp::CompiledMcp;
@@ -56,6 +57,7 @@ impl DeployedMcpService {
5657
match optional_deployment {
5758
Some(deployment) => {
5859
let security_scheme_id = deployment.mcp_data.value().security_scheme_id;
60+
let environment_id = deployment.environment_id;
5961
let mut compiled_mcp = CompiledMcp::try_from(deployment)?;
6062

6163
if let Some(scheme_id) = security_scheme_id {
@@ -76,6 +78,50 @@ impl DeployedMcpService {
7678
});
7779
}
7880

81+
let mut registered_agent_types = Vec::new();
82+
for agent_type_name in compiled_mcp.agent_type_implementers.keys() {
83+
match self
84+
.deployment_repo
85+
.get_deployed_agent_type(environment_id, &agent_type_name.0)
86+
.await
87+
{
88+
Ok(Some(record)) => {
89+
match golem_common::model::agent::DeployedRegisteredAgentType::try_from(
90+
record,
91+
) {
92+
Ok(deployed) => {
93+
registered_agent_types
94+
.push(RegisteredAgentType::from(deployed));
95+
}
96+
Err(e) => {
97+
tracing::warn!(
98+
"Failed to convert agent type {} for domain {}: {}",
99+
agent_type_name.0,
100+
domain.0,
101+
e
102+
);
103+
}
104+
}
105+
}
106+
Ok(None) => {
107+
tracing::warn!(
108+
"Agent type {} not found for domain {}",
109+
agent_type_name.0,
110+
domain.0,
111+
);
112+
}
113+
Err(e) => {
114+
tracing::warn!(
115+
"Failed to fetch agent type {} for domain {}: {}",
116+
agent_type_name.0,
117+
domain.0,
118+
e
119+
);
120+
}
121+
}
122+
}
123+
compiled_mcp.registered_agent_types = registered_agent_types;
124+
79125
Ok(compiled_mcp)
80126
}
81127
None => Err(DeployedMcpError::NoActiveMcpForDomain(domain.clone())),

golem-service-base/src/mcp/mod.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,40 @@
1+
// Copyright 2024-2026 Golem Cloud
2+
//
3+
// Licensed under the Golem Source License v1.1 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://license.golem.cloud/LICENSE
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
115
mod protobuf;
216

317
use golem_common::base_model::account::AccountId;
418
use golem_common::base_model::deployment::DeploymentRevision;
519
use golem_common::base_model::domain_registration::Domain;
620
use golem_common::base_model::environment::EnvironmentId;
7-
use golem_common::model::agent::AgentTypeName;
21+
use golem_common::model::agent::{AgentTypeName, RegisteredAgentType};
822
use golem_common::model::component::{ComponentId, ComponentRevision};
923
use std::collections::HashMap;
1024

1125
use crate::custom_api::SecuritySchemeDetails;
1226

1327
pub type AgentTypeImplementers = HashMap<AgentTypeName, (ComponentId, ComponentRevision)>;
1428

29+
#[derive(Clone)]
1530
pub struct CompiledMcp {
1631
pub account_id: AccountId,
1732
pub environment_id: EnvironmentId,
1833
pub deployment_revision: DeploymentRevision,
1934
pub domain: Domain,
2035
pub agent_type_implementers: AgentTypeImplementers,
2136
pub security_scheme: Option<SecuritySchemeDetails>,
37+
pub registered_agent_types: Vec<RegisteredAgentType>,
2238
}
2339

2440
impl CompiledMcp {

golem-service-base/src/mcp/protobuf.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::mcp::{AgentTypeImplementers, CompiledMcp};
22
use golem_common::base_model::domain_registration::Domain;
3-
use golem_common::model::agent::AgentTypeName;
3+
use golem_common::model::agent::{AgentTypeName, RegisteredAgentType};
44

55
impl From<CompiledMcp> for golem_api_grpc::proto::golem::mcp::CompiledMcp {
66
fn from(value: CompiledMcp) -> Self {
@@ -23,6 +23,11 @@ impl From<CompiledMcp> for golem_api_grpc::proto::golem::mcp::CompiledMcp {
2323
})
2424
.collect(),
2525
security_scheme: value.security_scheme.map(|s| s.into()),
26+
registered_agent_types: value
27+
.registered_agent_types
28+
.into_iter()
29+
.map(|rat| rat.into())
30+
.collect(),
2631
}
2732
}
2833
}
@@ -50,6 +55,12 @@ impl TryFrom<golem_api_grpc::proto::golem::mcp::CompiledMcp> for CompiledMcp {
5055
})
5156
.collect::<Result<_, String>>()?;
5257

58+
let registered_agent_types: Vec<RegisteredAgentType> = value
59+
.registered_agent_types
60+
.into_iter()
61+
.map(|rat| rat.try_into())
62+
.collect::<Result<_, String>>()?;
63+
5364
Ok(Self {
5465
account_id: value
5566
.account_id
@@ -72,6 +83,7 @@ impl TryFrom<golem_api_grpc::proto::golem::mcp::CompiledMcp> for CompiledMcp {
7283
.map(|s| s.try_into())
7384
.transpose()
7485
.map_err(|e| format!("Invalid security_scheme: {}", e))?,
86+
registered_agent_types,
7587
})
7688
}
7789
}

golem-worker-service/src/mcp/agent_mcp_server.rs

Lines changed: 51 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -114,86 +114,69 @@ pub async fn get_agent_capabilities(
114114
let account_id = compiled_mcp.account_id;
115115
let environment_id = compiled_mcp.environment_id;
116116

117-
let agent_types = compiled_mcp.agent_types();
118-
119117
tracing::info!(
120-
"Found {} agent types for domain {}: {:?}",
121-
agent_types.len(),
118+
"Found {} registered agent types for domain {}: {:?}",
119+
compiled_mcp.registered_agent_types.len(),
122120
domain.0,
123-
agent_types
121+
compiled_mcp
122+
.registered_agent_types
124123
.iter()
125-
.map(|at| at.0.clone())
124+
.map(|rat| rat.agent_type.type_name.0.clone())
126125
.collect::<Vec<_>>()
127126
);
128127

129-
for agent_type_name in &agent_types {
130-
match mcp_definition_lookup
131-
.resolve_agent_type(domain, agent_type_name)
132-
.await
133-
{
134-
Ok(registered_agent_type) => {
135-
tracing::debug!(
136-
"Resolved agent type {} for domain {}: implemented by component {}, methods: {:?}",
137-
agent_type_name.0,
138-
domain.0,
139-
registered_agent_type.implemented_by.component_id.0,
140-
registered_agent_type
141-
.agent_type
142-
.methods
143-
.iter()
144-
.map(|m| m.name.clone())
145-
.collect::<Vec<_>>()
146-
);
128+
for registered_agent_type in &compiled_mcp.registered_agent_types {
129+
tracing::debug!(
130+
"Processing agent type {} for domain {}: implemented by component {}, methods: {:?}",
131+
registered_agent_type.agent_type.type_name.0,
132+
domain.0,
133+
registered_agent_type.implemented_by.component_id.0,
134+
registered_agent_type
135+
.agent_type
136+
.methods
137+
.iter()
138+
.map(|m| m.name.clone())
139+
.collect::<Vec<_>>()
140+
);
141+
142+
let agent_type = &registered_agent_type.agent_type;
143+
let component_id = registered_agent_type.implemented_by.component_id;
144+
145+
if let Some(prompt_hint) = &agent_type.constructor.prompt_hint {
146+
prompts.push(AgentMcpPrompt::from_constructor_hint(
147+
&agent_type.type_name,
148+
&agent_type.description,
149+
prompt_hint,
150+
));
151+
}
147152

148-
let agent_type = &registered_agent_type.agent_type;
153+
for method in &agent_type.methods {
154+
if let Some(prompt_hint) = &method.prompt_hint {
155+
prompts.push(AgentMcpPrompt::from_method_hint(
156+
&agent_type.type_name,
157+
method,
158+
&agent_type.constructor,
159+
prompt_hint,
160+
));
161+
}
149162

150-
let component_id = registered_agent_type.implemented_by.component_id;
163+
let agent_method_mcp = McpAgentCapability::from_agent_method(
164+
&account_id,
165+
&environment_id,
166+
&agent_type.type_name,
167+
method,
168+
&agent_type.constructor,
169+
component_id,
170+
);
151171

152-
if let Some(prompt_hint) = &agent_type.constructor.prompt_hint {
153-
prompts.push(AgentMcpPrompt::from_constructor_hint(
154-
&agent_type.type_name,
155-
&agent_type.description,
156-
prompt_hint,
157-
));
172+
match agent_method_mcp {
173+
McpAgentCapability::Tool(agent_mcp_tool) => {
174+
tools.push(*agent_mcp_tool);
158175
}
159-
160-
for method in &agent_type.methods {
161-
if let Some(prompt_hint) = &method.prompt_hint {
162-
prompts.push(AgentMcpPrompt::from_method_hint(
163-
&agent_type.type_name,
164-
method,
165-
&agent_type.constructor,
166-
prompt_hint,
167-
));
168-
}
169-
170-
let agent_method_mcp = McpAgentCapability::from_agent_method(
171-
&account_id,
172-
&environment_id,
173-
&agent_type.type_name,
174-
method,
175-
&agent_type.constructor,
176-
component_id,
177-
);
178-
179-
match agent_method_mcp {
180-
McpAgentCapability::Tool(agent_mcp_tool) => {
181-
tools.push(*agent_mcp_tool);
182-
}
183-
McpAgentCapability::Resource(agent_mcp_resource) => {
184-
resources.push(*agent_mcp_resource);
185-
}
186-
}
176+
McpAgentCapability::Resource(agent_mcp_resource) => {
177+
resources.push(*agent_mcp_resource);
187178
}
188179
}
189-
Err(e) => {
190-
tracing::error!(
191-
"Failed to resolve agent type {} for domain {}: {}",
192-
agent_type_name.0,
193-
domain.0,
194-
e
195-
);
196-
}
197180
}
198181
}
199182

0 commit comments

Comments
 (0)