Refactor to Pure Native JSON-RPC (Ditch SDKs)
This commit is contained in:
1 parent
5f0eba8a80
commit
f9dee11f32
9 files changed
+575
-1169
No files matched your search
@@ -1,73 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Brain Monitor</title>
|
||||
<style>
|
||||
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; padding: 40px; background-color: #f0f2f5; color: #333; }
|
||||
h1 { color: #2c3e50; text-align: center; margin-bottom: 30px; }
|
||||
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; max-width: 800px; margin: 0 auto; }
|
||||
.stat-card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.05); text-align: center; transition: transform 0.2s ease; }
|
||||
.stat-card:hover { transform: translateY(-5px); }
|
||||
.stat-value { font-size: 2.5em; font-weight: bold; color: #3498db; margin: 10px 0; }
|
||||
.stat-label { font-size: 1.1em; color: #7f8c8d; text-transform: uppercase; letter-spacing: 1px; }
|
||||
.status-dot { display: inline-block; width: 10px; height: 10px; background-color: #2ecc71; border-radius: 50%; margin-right: 8px; box-shadow: 0 0 5px #2ecc71; }
|
||||
.header-bar { max-width: 800px; margin: 0 auto 20px; display: flex; justify-content: space-between; align-items: center; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header-bar">
|
||||
<h1>🧠 Antigravity Brain Monitor</h1>
|
||||
<div><span class="status-dot"></span>System Online</div>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Entities</div>
|
||||
<div class="stat-value" id="val-entities">-</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Relations</div>
|
||||
<div class="stat-value" id="val-relations">-</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Active Tasks</div>
|
||||
<div class="stat-value" id="val-tasks">-</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Snippets</div>
|
||||
<div class="stat-value" id="val-snippets">-</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Tech Debt</div>
|
||||
<div class="stat-value" id="val-tech_debts">-</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">ADRs</div>
|
||||
<div class="stat-value" id="val-adrs">-</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function fetchStats() {
|
||||
try {
|
||||
const response = await fetch('/api/stats');
|
||||
const data = await response.json();
|
||||
|
||||
document.getElementById('val-entities').innerText = data.entities;
|
||||
document.getElementById('val-relations').innerText = data.relations;
|
||||
document.getElementById('val-tasks').innerText = data.tasks;
|
||||
document.getElementById('val-snippets').innerText = data.snippets;
|
||||
document.getElementById('val-tech_debts').innerText = data.tech_debts;
|
||||
document.getElementById('val-adrs').innerText = data.adrs;
|
||||
} catch (err) {
|
||||
console.error("Failed to fetch stats:", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Initial fetch
|
||||
fetchStats();
|
||||
// Poll every 2 seconds
|
||||
setInterval(fetchStats, 2000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+296
-338
File diff suppressed because it is too large.
Load diff
+77
-80
@@ -1,5 +1,6 @@
|
||||
mod handlers;
|
||||
mod models;
|
||||
mod mcp;
|
||||
mod state;
|
||||
mod store;
|
||||
mod tools;
|
||||
@@ -9,12 +10,7 @@ use crate::handlers::MemoryHandler;
|
||||
use crate::models::*;
|
||||
use crate::state::MemoryState;
|
||||
use crate::store::Store;
|
||||
use rust_mcp_sdk::{
|
||||
ServerDetails, ToMcpServerHandler,
|
||||
error::SdkResult,
|
||||
|
||||
schema::{Implementation, ServerCapabilities, ServerCapabilitiesTools},
|
||||
};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, RwLock};
|
||||
@@ -109,94 +105,95 @@ async fn reconcile_worker(state: Arc<MemoryState>) {
|
||||
}
|
||||
|
||||
|
||||
use rust_mcp_axum::{create_axum_server, AxumServerOptions};
|
||||
|
||||
fn run_server(state: Arc<MemoryState>) -> SdkResult<()> {
|
||||
|
||||
|
||||
use axum::{
|
||||
extract::{State, Query},
|
||||
response::sse::{Event, Sse},
|
||||
routing::{get, post},
|
||||
Json, Router,
|
||||
};
|
||||
use futures_util::stream::Stream;
|
||||
use std::convert::Infallible;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
struct AppState {
|
||||
handler: Arc<MemoryHandler>,
|
||||
clients: RwLock<HashMap<String, mpsc::Sender<Result<Event, Infallible>>>>,
|
||||
next_id: AtomicUsize,
|
||||
}
|
||||
|
||||
fn run_server(state: Arc<MemoryState>) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let state_clone = state.clone();
|
||||
tokio::spawn(async move {
|
||||
reconcile_worker(state_clone).await;
|
||||
tokio::spawn(reconcile_worker(Arc::clone(&state)));
|
||||
let app_state = Arc::new(AppState {
|
||||
handler: Arc::new(MemoryHandler { state }),
|
||||
clients: RwLock::new(HashMap::new()),
|
||||
next_id: AtomicUsize::new(1),
|
||||
});
|
||||
|
||||
let server_details = ServerDetails {
|
||||
server_info: Implementation {
|
||||
name: "gemini-mcp-memory".into(),
|
||||
version: "3.0.0".into(),
|
||||
title: Some("MCP Memory Server".into()),
|
||||
description: Some("Persistent memory MCP server".into()),
|
||||
icons: vec![],
|
||||
website_url: None,
|
||||
},
|
||||
capabilities: ServerCapabilities {
|
||||
tools: Some(ServerCapabilitiesTools {
|
||||
list_changed: Some(true),
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
instructions: None,
|
||||
meta: None,
|
||||
};
|
||||
|
||||
let options = AxumServerOptions {
|
||||
host: "0.0.0.0".to_string(),
|
||||
port: 3000,
|
||||
custom_sse_endpoint: Some("/sse".to_string()),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let server = create_axum_server(
|
||||
server_details,
|
||||
MemoryHandler { state: state.clone() }.to_mcp_server_handler(),
|
||||
options,
|
||||
);
|
||||
|
||||
let server = server.with_route(
|
||||
"/gate/verify",
|
||||
axum::routing::get(|| async move {
|
||||
axum::http::StatusCode::OK
|
||||
}),
|
||||
).with_route(
|
||||
"/dashboard",
|
||||
axum::routing::get(|| async move {
|
||||
axum::response::Html(include_str!("dashboard.html"))
|
||||
}),
|
||||
).with_route(
|
||||
"/api/stats",
|
||||
axum::routing::get({
|
||||
let state_clone = state.clone();
|
||||
move || async move {
|
||||
let (entities, relations) = {
|
||||
let graph = state_clone.get_full_graph();
|
||||
(graph.entities.len(), graph.relations.len())
|
||||
};
|
||||
let tasks = state_clone.tasks.read().len();
|
||||
let snippets = state_clone.snippets.read().len();
|
||||
let tech_debts = state_clone.tech_debts.read().len();
|
||||
let adrs = state_clone.adrs.read().len();
|
||||
|
||||
axum::Json(serde_json::json!({
|
||||
"entities": entities,
|
||||
"relations": relations,
|
||||
"tasks": tasks,
|
||||
"snippets": snippets,
|
||||
"tech_debts": tech_debts,
|
||||
"adrs": adrs
|
||||
}))
|
||||
}
|
||||
}),
|
||||
);
|
||||
let app = Router::new()
|
||||
.route("/sse", get(sse_handler))
|
||||
.route("/messages", post(message_handler))
|
||||
.with_state(app_state);
|
||||
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
eprintln!("MCP Memory Server running on http://0.0.0.0:3000/sse");
|
||||
server.start().await.unwrap();
|
||||
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
async fn sse_handler(
|
||||
State(state): State<Arc<AppState>>,
|
||||
) -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
|
||||
let session_id = format!("{}", state.next_id.fetch_add(1, Ordering::SeqCst));
|
||||
let (tx, rx) = mpsc::channel::<Result<Event, Infallible>>(100);
|
||||
|
||||
state.clients.write().unwrap().insert(session_id.clone(), tx.clone());
|
||||
|
||||
let _ = tx.send(Ok(Event::default().event("endpoint").data(format!("?sessionId={}", session_id)))).await;
|
||||
|
||||
let stream = ReceiverStream::new(rx);
|
||||
Sse::new(stream).keep_alive(axum::response::sse::KeepAlive::new())
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct SessionQuery {
|
||||
#[serde(rename = "sessionId")]
|
||||
session_id: String,
|
||||
}
|
||||
|
||||
async fn message_handler(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Query(query): Query<SessionQuery>,
|
||||
Json(payload): Json<serde_json::Value>,
|
||||
) -> axum::http::StatusCode {
|
||||
let handler = Arc::clone(&state.handler);
|
||||
let session_id = query.session_id.clone();
|
||||
let clients = Arc::clone(&state);
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Some(response) = handler.handle_request(payload).await {
|
||||
let tx_opt = clients.clients.read().unwrap().get(&session_id).cloned();
|
||||
if let Some(tx) = tx_opt {
|
||||
let data = serde_json::to_string(&response).unwrap();
|
||||
let _ = tx.send(Ok(Event::default().event("message").data(data))).await;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
axum::http::StatusCode::ACCEPTED
|
||||
}
|
||||
|
||||
mod proxy;
|
||||
|
||||
fn main() -> SdkResult<()> {
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde_json::json;
|
||||
|
||||
pub fn success(id: serde_json::Value, result: serde_json::Value) -> serde_json::Value {
|
||||
json!({
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"result": result
|
||||
})
|
||||
}
|
||||
|
||||
pub fn error(id: serde_json::Value, code: i32, message: &str) -> serde_json::Value {
|
||||
json!({
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"error": {
|
||||
"code": code,
|
||||
"message": message
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn tool_def<T: JsonSchema>(name: &str, description: &str) -> serde_json::Value {
|
||||
let schema = schemars::schema_for!(T);
|
||||
let schema_val = serde_json::to_value(&schema).unwrap();
|
||||
// MCP expects standard JSON schema. Schemars returns draft-07.
|
||||
json!({
|
||||
"name": name,
|
||||
"description": description,
|
||||
"inputSchema": schema_val
|
||||
})
|
||||
}
|
||||
+20
-6
@@ -1,22 +1,32 @@
|
||||
use rust_mcp_sdk::error::SdkResult;
|
||||
use tokio_util::io::StreamReader;
|
||||
use tokio::io::AsyncBufReadExt;
|
||||
use futures_util::StreamExt;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
pub fn run_proxy(target_url: &str) -> SdkResult<bool> {
|
||||
pub fn run_proxy(target_url: &str) -> Result<bool, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let client = reqwest::Client::builder().build().unwrap();
|
||||
let sse_url = format!("{}/sse", target_url);
|
||||
|
||||
let resp = match client.get(&sse_url).send().await {
|
||||
eprintln!("[PROXY] Connecting to Streamable HTTP: {}", sse_url);
|
||||
let resp = match client.get(&sse_url)
|
||||
.header("Accept", "text/event-stream")
|
||||
.send().await {
|
||||
Ok(r) => r,
|
||||
Err(_) => return Ok(true), // Connection failed (Leader is dead)
|
||||
Err(e) => {
|
||||
eprintln!("[PROXY] Connection failed: {}", e);
|
||||
return Ok(true);
|
||||
}
|
||||
};
|
||||
|
||||
let post_url = Arc::new(RwLock::new(format!("{}/messages", target_url)));
|
||||
if resp.status() == reqwest::StatusCode::GONE {
|
||||
eprintln!("[PROXY] Streamable HTTP endpoint is gone.");
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let post_url = Arc::new(RwLock::new(format!("{}/messages", target_url))); // Will be updated by endpoint event
|
||||
let post_url_clone = Arc::clone(&post_url);
|
||||
|
||||
let (tx, mut rx) = tokio::sync::mpsc::channel(1);
|
||||
@@ -47,7 +57,11 @@ pub fn run_proxy(target_url: &str) -> SdkResult<bool> {
|
||||
if url.is_empty() {
|
||||
url = url_arc.read().await.clone();
|
||||
}
|
||||
let _ = client.post(&url).header("Content-Type", "application/json").body(body).send().await;
|
||||
let _ = client.post(&url)
|
||||
.header("Accept", "application/json, text/event-stream")
|
||||
.header("Content-Type", "application/json")
|
||||
.body(body)
|
||||
.send().await;
|
||||
});
|
||||
}
|
||||
let _ = tx_clone.blocking_send(false); // Stdin EOF
|
||||
|
||||
+58
-151
@@ -1,64 +1,45 @@
|
||||
use rust_mcp_sdk::macros;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[macros::mcp_tool(name = "create_entities", description = "Create multiple new entities")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct CreateEntitiesTool {
|
||||
pub entities: Vec<serde_json::Value>,
|
||||
}
|
||||
#[macros::mcp_tool(
|
||||
name = "create_relations",
|
||||
description = "Create multiple new relations"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct CreateRelationsTool {
|
||||
pub relations: Vec<serde_json::Value>,
|
||||
}
|
||||
#[macros::mcp_tool(
|
||||
name = "add_observations",
|
||||
description = "Add observations to entities"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct AddObservationsTool {
|
||||
pub observations: Vec<serde_json::Value>,
|
||||
}
|
||||
#[macros::mcp_tool(
|
||||
name = "delete_entities",
|
||||
description = "Delete entities and relations"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct DeleteEntitiesTool {
|
||||
#[serde(rename = "entityNames")]
|
||||
pub entity_names: Vec<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "delete_observations", description = "Delete observations")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct DeleteObservationsTool {
|
||||
pub deletions: Vec<serde_json::Value>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "delete_relations", description = "Delete relations")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct DeleteRelationsTool {
|
||||
pub relations: Vec<serde_json::Value>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "read_graph", description = "Read the entire knowledge graph")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ReadGraphTool {
|
||||
pub namespace: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "search_nodes", description = "Search for nodes")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct SearchNodesTool {
|
||||
pub query: String,
|
||||
pub namespace: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "open_nodes", description = "Open specific nodes")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct OpenNodesTool {
|
||||
pub names: Vec<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "log_code_change", description = "Log a code change")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct LogCodeChangeTool {
|
||||
#[serde(rename = "filePath")]
|
||||
pub file_path: String,
|
||||
@@ -66,218 +47,165 @@ pub struct LogCodeChangeTool {
|
||||
pub git_commit: Option<String>,
|
||||
pub git_branch: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "query_recent_changes", description = "Query the audit ledger")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct QueryRecentChangesTool {}
|
||||
#[macros::mcp_tool(name = "visualize_graph", description = "Generate Mermaid diagram")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct VisualizeGraphTool {
|
||||
pub query: Option<String>,
|
||||
pub namespace: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "add_sticky_note", description = "Add a sticky note")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct AddStickyNoteTool {
|
||||
pub content: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "read_sticky_notes", description = "Read sticky notes")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ReadStickyNotesTool {}
|
||||
#[macros::mcp_tool(name = "condense_entity", description = "Condense observations")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct CondenseEntityTool {
|
||||
#[serde(rename = "entityName")]
|
||||
pub entity_name: String,
|
||||
pub summarized_observations: Vec<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "add_task", description = "Add a task")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct AddTaskTool {
|
||||
pub title: String,
|
||||
pub description: String,
|
||||
pub git_branch: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "update_task_status", description = "Update task status")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct UpdateTaskStatusTool {
|
||||
pub id: String,
|
||||
pub status: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "list_active_tasks", description = "List active tasks")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ListActiveTasksTool { pub git_branch: Option<String>, }
|
||||
#[macros::mcp_tool(name = "store_snippet", description = "Store code snippet")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct StoreSnippetTool {
|
||||
pub name: String,
|
||||
pub language: String,
|
||||
pub code: String,
|
||||
pub description: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "search_snippets", description = "Search snippets")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct SearchSnippetsTool {
|
||||
pub query: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "delete_snippet", description = "Delete snippet")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct DeleteSnippetTool {
|
||||
pub name: String,
|
||||
}
|
||||
#[macros::mcp_tool(
|
||||
name = "log_decision",
|
||||
description = "Log architectural decision record"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct LogDecisionTool {
|
||||
pub title: String,
|
||||
pub context: String,
|
||||
pub decision: String,
|
||||
pub consequence: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "query_decisions", description = "Query decision records")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct QueryDecisionsTool {
|
||||
pub query: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(
|
||||
name = "merge_entities",
|
||||
description = "Merge source entity into target entity"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct MergeEntitiesTool {
|
||||
#[serde(rename = "sourceEntity")]
|
||||
pub source_entity: String,
|
||||
#[serde(rename = "targetEntity")]
|
||||
pub target_entity: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "find_orphans", description = "Find entities with no relations")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct FindOrphansTool {}
|
||||
#[macros::mcp_tool(
|
||||
name = "learn_preference",
|
||||
description = "Store an AI behavioral preference"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct LearnPreferenceTool {
|
||||
pub key: String,
|
||||
pub value: String,
|
||||
}
|
||||
#[macros::mcp_tool(
|
||||
name = "read_preferences",
|
||||
description = "Read all learned behavioral preferences"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ReadPreferencesTool {}
|
||||
#[macros::mcp_tool(name = "log_error_fix", description = "Log an error fix")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct LogErrorFixTool {
|
||||
pub signature: String,
|
||||
pub solution: String,
|
||||
pub git_commit: Option<String>,
|
||||
pub git_branch: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "search_error_fixes", description = "Search error fixes")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct SearchErrorFixesTool {
|
||||
pub query: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "pin_file", description = "Pin a file to working set")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct PinFileTool {
|
||||
pub namespace: String,
|
||||
pub file_path: String,
|
||||
pub git_branch: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "unpin_file", description = "Unpin a file")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct UnpinFileTool {
|
||||
pub namespace: String,
|
||||
pub file_path: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "list_pinned_files", description = "List pinned files")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ListPinnedFilesTool {
|
||||
pub namespace: Option<String>,
|
||||
pub git_branch: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "add_session_summary", description = "Add a session summary")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct AddSessionSummaryTool {
|
||||
pub summary: String,
|
||||
pub namespace: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "get_project_timeline", description = "Get project timeline")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct GetProjectTimelineTool {
|
||||
pub namespace: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(
|
||||
name = "leave_handoff_memo",
|
||||
description = "Leave memo for next session"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct LeaveHandoffMemoTool {
|
||||
pub content: String,
|
||||
pub namespace: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "read_handoff_memos", description = "Read pending memos")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ReadHandoffMemosTool {
|
||||
pub namespace: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "clear_handoff_memos", description = "Clear read memos")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ClearHandoffMemosTool {
|
||||
pub ids: Vec<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "update_env_fingerprint", description = "Update env versions")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct UpdateEnvFingerprintTool {
|
||||
pub namespace: String,
|
||||
pub tool_versions: std::collections::HashMap<String, String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "read_env_fingerprint", description = "Read env footprint")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ReadEnvFingerprintTool {
|
||||
pub namespace: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "log_env_requirement", description = "Log env var requirement")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct LogEnvRequirementTool {
|
||||
pub namespace: String,
|
||||
pub key: String,
|
||||
pub description: String,
|
||||
pub is_secret: bool,
|
||||
}
|
||||
#[macros::mcp_tool(name = "add_milestone", description = "Add project milestone")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct AddMilestoneTool {
|
||||
pub title: String,
|
||||
pub namespace: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "update_milestone", description = "Update milestone status")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct UpdateMilestoneTool {
|
||||
pub id: String,
|
||||
pub status: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "list_milestones", description = "List milestones")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ListMilestonesTool {
|
||||
pub namespace: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(
|
||||
name = "generate_standup_report",
|
||||
description = "Generate a standup report"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct GenerateStandupReportTool {
|
||||
pub namespace: String,
|
||||
pub hours_lookback: u64,
|
||||
}
|
||||
#[macros::mcp_tool(name = "register_environment", description = "Register an environment")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct RegisterEnvironmentTool {
|
||||
pub namespace: String,
|
||||
pub name: String,
|
||||
@@ -285,35 +213,24 @@ pub struct RegisterEnvironmentTool {
|
||||
pub description: String,
|
||||
pub requires_vpn: bool,
|
||||
}
|
||||
#[macros::mcp_tool(
|
||||
name = "get_environment_details",
|
||||
description = "Get environment details"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct GetEnvironmentDetailsTool {
|
||||
pub namespace: String,
|
||||
}
|
||||
#[macros::mcp_tool(
|
||||
name = "add_pr_checklist_item",
|
||||
description = "Add a PR checklist item"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct AddPrChecklistItemTool {
|
||||
pub namespace: String,
|
||||
pub description: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "get_pr_checklist", description = "Get the PR checklist")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct GetPrChecklistTool {
|
||||
pub namespace: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "clear_pr_checklist", description = "Clear the PR checklist")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ClearPrChecklistTool {
|
||||
pub namespace: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "log_tech_debt", description = "Log tech debt")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct LogTechDebtTool {
|
||||
pub namespace: String,
|
||||
pub description: String,
|
||||
@@ -321,47 +238,37 @@ pub struct LogTechDebtTool {
|
||||
pub git_commit: Option<String>,
|
||||
pub git_branch: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "resolve_tech_debt", description = "Resolve tech debt")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ResolveTechDebtTool {
|
||||
pub id: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "list_tech_debt", description = "List tech debt")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ListTechDebtTool {
|
||||
pub namespace: String,
|
||||
pub include_resolved: bool,
|
||||
}
|
||||
#[macros::mcp_tool(name = "save_context_workspace", description = "Save current context")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct SaveContextWorkspaceTool {
|
||||
pub namespace: String,
|
||||
pub name: String,
|
||||
pub pinned_files: Vec<String>,
|
||||
pub active_task_ids: Vec<String>,
|
||||
}
|
||||
#[macros::mcp_tool(name = "load_context_workspace", description = "Load context")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct LoadContextWorkspaceTool {
|
||||
pub namespace: String,
|
||||
pub name: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "list_context_workspaces", description = "List contexts")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ListContextWorkspacesTool {
|
||||
pub namespace: String,
|
||||
}
|
||||
#[macros::mcp_tool(name = "omni_search", description = "Search across all memory vaults")]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct OmniSearchTool {
|
||||
pub query: String,
|
||||
pub namespace: Option<String>,
|
||||
}
|
||||
#[macros::mcp_tool(
|
||||
name = "get_project_health",
|
||||
description = "Get project health metrics"
|
||||
)]
|
||||
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct GetProjectHealthTool {
|
||||
pub namespace: String,
|
||||
}
|
||||
Reference in new issue
Block a user