use std::collections::BTreeMap;
use rmcp::handler::server::wrapper::Json;
use rmcp::{schemars, tool, tool_router};
use serde::Serialize;
use crate::mcp::query;
use crate::mcp::server::GitPawMcpServer;
#[derive(Serialize, schemars::JsonSchema)]
pub struct SessionStatusResponse {
pub session: Option<query::session::SessionSnapshot>,
}
#[derive(Serialize, schemars::JsonSchema)]
pub struct SessionSummary {
pub name: String,
pub status: String,
pub agent_count: usize,
pub agents_by_status: BTreeMap<String, usize>,
}
#[derive(Serialize, schemars::JsonSchema)]
pub struct SummaryResponse {
pub summary: Option<SessionSummary>,
}
#[derive(Serialize, schemars::JsonSchema)]
pub struct LearningsResponse {
pub sections: Vec<query::learnings::LearningSection>,
}
#[tool_router(router = session_router, vis = "pub(crate)")]
impl GitPawMcpServer {
#[tool(
description = "Return the active session snapshot: name, mode, status, agent count, broker \
URL, pause state, and per-agent status (live from the broker when reachable). \
{ \"session\": null } when no session is active."
)]
pub(crate) fn get_session_status(&self) -> Json<SessionStatusResponse> {
Json(SessionStatusResponse {
session: query::session::session_status(&self.ctx),
})
}
#[tool(
description = "Return a compact summary of the current session (name, status, agent count, \
and per-status agent counts), or { \"summary\": null } when none is active."
)]
pub(crate) fn get_session_summary(&self) -> Json<SummaryResponse> {
let summary = query::session::session_status(&self.ctx).map(|s| {
let mut by_status: BTreeMap<String, usize> = BTreeMap::new();
for a in &s.agents {
if !a.status.is_empty() {
*by_status.entry(a.status.clone()).or_default() += 1;
}
}
SessionSummary {
name: s.name,
status: s.status,
agent_count: s.agent_count,
agents_by_status: by_status,
}
});
Json(SummaryResponse { summary })
}
#[tool(
description = "Parse .git-paw/session-learnings.md into structured sections, each with a \
category and its entries. Returns the canonical sections as empty arrays \
when no learnings file exists."
)]
pub(crate) fn get_learnings(&self) -> Json<LearningsResponse> {
Json(LearningsResponse {
sections: query::learnings::learnings(&self.ctx),
})
}
}