impl McpAgentsMdBridge {
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn new() -> Self {
Self {
config: BridgeConfig::default(),
tool_registry: Vec::new(),
}
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn with_config(config: BridgeConfig) -> Self {
Self {
config,
tool_registry: Vec::new(),
}
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn agents_to_mcp(&self, doc: &AgentsMdDocument) -> Vec<McpTool> {
let mut tools = Vec::new();
for cmd in &doc.commands {
tools.push(self.command_to_tool(cmd));
}
if self.config.quality_level != QualityLevel::None {
tools.push(self.create_quality_tool());
}
tools
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn mcp_to_agents(&self, tools: &[McpTool]) -> String {
let mut output = String::new();
output.push_str("# AGENTS.md\n\n");
output.push_str("## Available Tools\n\n");
for tool in tools {
output.push_str(&format!("### {}\n", tool.name));
output.push_str(&format!("{}\n\n", tool.description));
if let ToolHandler::Command(ref cmd) = tool.handler {
output.push_str("```bash\n");
output.push_str(&format!("{}\n", cmd.command));
output.push_str("```\n\n");
}
}
output
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn translate_request(&self, req: Request) -> TranslatedRequest {
let metadata = TranslationMetadata {
timestamp: std::time::SystemTime::now(),
quality_checks: vec![],
warnings: vec![],
};
let translated = match req {
Request::AgentsMd(ref agents_req) => {
Request::Mcp(self.agents_request_to_mcp(agents_req))
}
Request::Mcp(ref mcp_req) => Request::AgentsMd(self.mcp_request_to_agents(mcp_req)),
};
TranslatedRequest {
original: req,
translated,
metadata,
}
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn unify_response(&self, resp: Response) -> UnifiedResponse {
let unified = match resp {
Response::AgentsMd(ref agents_resp) => self.agents_response_to_unified(agents_resp),
Response::Mcp(ref mcp_resp) => self.mcp_response_to_unified(mcp_resp),
};
let quality_report = if self.config.quality_level == QualityLevel::None {
None
} else {
Some(self.check_response_quality(&unified))
};
UnifiedResponse {
original: resp,
unified,
quality_report,
}
}
fn command_to_tool(&self, cmd: &Command) -> McpTool {
McpTool {
name: cmd.name.clone(),
description: format!("Execute: {}", cmd.command),
input_schema: json!({
"type": "object",
"properties": {
"args": {
"type": "array",
"items": {"type": "string"}
}
}
}),
output_schema: json!({
"type": "object",
"properties": {
"stdout": {"type": "string"},
"stderr": {"type": "string"},
"exit_code": {"type": "integer"}
}
}),
handler: ToolHandler::Command(cmd.clone()),
}
}
fn create_quality_tool(&self) -> McpTool {
McpTool {
name: "quality_gate".to_string(),
description: "Run PMAT quality gates".to_string(),
input_schema: json!({
"type": "object",
"properties": {
"file": {"type": "string"},
"level": {"type": "string"}
}
}),
output_schema: json!({
"type": "object",
"properties": {
"passed": {"type": "boolean"},
"score": {"type": "number"},
"issues": {
"type": "array",
"items": {"type": "string"}
}
}
}),
handler: ToolHandler::Function("quality_gate".to_string()),
}
}
fn agents_request_to_mcp(&self, req: &AgentsMdRequest) -> McpRequest {
McpRequest {
method: req.request_type.clone(),
params: req.params.clone(),
}
}
fn mcp_request_to_agents(&self, req: &McpRequest) -> AgentsMdRequest {
AgentsMdRequest {
request_type: req.method.clone(),
params: req.params.clone(),
}
}
fn agents_response_to_unified(&self, resp: &AgentsMdResponse) -> JsonValue {
json!({
"success": resp.success,
"result": resp.result,
"error": resp.error,
})
}
fn mcp_response_to_unified(&self, resp: &McpResponse) -> JsonValue {
json!({
"success": resp.error.is_none(),
"result": resp.result,
"error": resp.error,
})
}
fn check_response_quality(&self, response: &JsonValue) -> QualityReport {
let mut issues = Vec::new();
let mut suggestions = Vec::new();
let mut score: f64 = 100.0;
if let Some(error) = response.get("error") {
if !error.is_null() {
issues.push("Response contains error".to_string());
score -= 20.0;
}
}
if let Some(result) = response.get("result") {
if result.is_null() || (result.is_string() && result.as_str() == Some("")) {
issues.push("Empty result".to_string());
suggestions.push("Provide meaningful output".to_string());
score -= 10.0;
}
}
QualityReport {
score: score.max(0.0),
issues,
suggestions,
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn register_tool(&mut self, tool: McpTool) {
self.tool_registry.push(tool);
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn get_tools(&self) -> &[McpTool] {
&self.tool_registry
}
}