use serde_json::{Value, json};
pub const PROTOCOL_VERSION: &str = "2024-11-05";
pub const SERVER_NAME: &str = "episteme";
pub const SERVER_VERSION: &str = env!("CARGO_PKG_VERSION");
pub const MAX_CODE_BYTES: usize = 500_000;
pub fn server_info() -> Value {
json!({
"name": SERVER_NAME,
"version": SERVER_VERSION,
})
}
pub fn capabilities() -> Value {
json!({
"tools": { "listChanged": false },
"resources": { "subscribe": false, "listChanged": false },
})
}
pub fn server_instructions() -> String {
"\
Episteme is a software engineering knowledge graph. Use it to AUTOMATICALLY ground your answers \
in proven patterns, laws, and refactoring techniques — even when the user doesn't know those terms.
CRITICAL: Auto-trigger on PROBLEM DESCRIPTIONS, not just named concepts. Users describe symptoms, \
not diagnoses. You must translate their informal problem into knowledge graph queries.
Auto-trigger rules — call Episteme tools WITHOUT waiting for the user to mention them:
## Code problems (auto-translate complaint -> knowledge graph query)
User says / does -> What to call
\"this class does too much\" / file > 300 lines -> search_knowledge(\"god class large class single responsibility\")
\"this function is too long\" -> search_knowledge(\"long method extract method\")
\"code is too complex\" / hard to follow -> search_knowledge(\"complexity smell cognitive overload\")
\"calling DB directly in business logic\" -> search_knowledge(\"coupling persistence repository data access layer\")
\"hard to test\" / can't write unit tests -> search_knowledge(\"testability dependency injection mockability\")
\"copy-pasted this\" / duplicated logic -> search_knowledge(\"duplicated code clone smell\")
\"changing X breaks Y\" / change ripple -> search_knowledge(\"brittle coupling change propagation rigidity\")
\"adding a new type means touching everywhere\" / growing switch -> search_knowledge(\"open closed principle strategy polymorphism\")
\"is this thread-safe?\" / concurrency concerns -> search_knowledge(\"thread safety race condition shared mutable state\")
\"API is slow\" / performance issues -> search_knowledge(\"N+1 query lazy loading caching performance\")
User shares code for review -> analyze_code(code) then suggest_refactorings(code)
User wants to refactor or improve code -> suggest_refactorings(code)
## Architecture discussions (auto-trigger on trade-off questions)
\"microservices vs monolith\" / how to split -> search_knowledge(\"monolith microservice decomposition bounded context\")
\"is this architecture okay?\" / architecture review -> search_knowledge(\"layered architecture coupling cohesion separation concerns\")
\"where should this go?\" / code placement -> search_knowledge(\"responsibility assignment package structure\")
Team/org structure affects code -> search_knowledge(\"Conway law organizational structure architecture\")
## Concept exploration (when user names something or asks follow-up)
Entity ID mentioned (DP-xxx, LAW-xxx, RF-xxx, SMELL-xxx) -> get_entity(id)
\"how does X relate to Y\" -> find_path or get_neighbors
\"tell me more\" about a previous result -> get_entity for full details, get_neighbors for connected concepts
## Always
- Translate informal language into technical queries. User says \"it's a tangled mess\", you search \"coupling tangled dependency\".
- After search_knowledge, present the named concept and explain it in the user's own language.
- Cite entity IDs (DP-005, LAW-003) in responses."
.to_owned()
}
const DESC_SEARCH: &str = "Hybrid search over the Episteme knowledge base. Use when the user asks about design patterns, engineering laws, code smells, refactorings, or any software engineering concept. Examples: \"what is Strategy pattern\", \"laws about coupling\", \"find smells related to God Class\", \"relevant principles for microservices\".";
const DESC_GET_ENTITY: &str = "Get detailed information about a knowledge graph entity by ID. Use when an entity ID is mentioned (DP-xxx, LAW-xxx, RF-xxx, SMELL-xxx) or the user asks \"tell me more about\" a previously mentioned concept.";
const DESC_GET_NEIGHBORS: &str = "Get entities related to a given entity in the knowledge graph. Use to explore what patterns complement a law, what refactorings solve a smell, or how concepts connect. Follow up after search_knowledge or get_entity.";
const DESC_FIND_PATH: &str = "Find the shortest path between two entities in the knowledge graph. Use when the user asks how two concepts relate or connect, e.g. \"how does Strategy relate to Open/Closed?\", \"what connects God Class and Single Responsibility?\".";
const DESC_ANALYZE_CODE: &str = "Detect code smells in source code. Use when the user shares code and asks for review, feedback, problems, or improvements. Supports Python, Java, Go, Rust, TypeScript, C++, C#, Kotlin, PHP, and Ruby.";
const DESC_SUGGEST_REFACTORINGS: &str = "Get ranked refactoring suggestions for source code. Uses composite scoring (severity, effort, principle alignment, usage) to prioritize suggestions. Supports Python, Java, Go, Rust, TypeScript, C++, C#, Kotlin, PHP, and Ruby.";
const DESC_ADD_INSIGHT: &str = "Add a tacit knowledge insight from free text. Automatically detects links to canonical knowledge graph entities and checks for duplicates. Use when capturing team decisions, lessons learned, or architectural rationale.";
const DESC_CONFIRM_LINKS: &str = "Confirm or reject auto-detected links between an insight and canonical entities. Use after add_insight to validate the suggested entity connections.";
const DESC_SEARCH_INSIGHTS: &str = "Search user-contributed tacit knowledge insights. Use when looking for past team decisions, lessons learned, or architectural notes recorded by the user or team.";
pub fn tool_schemas() -> Vec<Value> {
vec![
json!({
"name": "search_knowledge",
"description": DESC_SEARCH,
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Natural-language search query.",
},
"limit": {
"type": "integer",
"description": "Maximum results to return.",
"minimum": 1,
"maximum": 20,
"default": 5,
},
"entity_type": {
"type": "string",
"description": "Restrict results to this entity type.",
"enum": ["pattern", "refactoring", "law", "smell"],
},
},
"required": ["query"],
},
}),
json!({
"name": "get_entity",
"description": DESC_GET_ENTITY,
"inputSchema": {
"type": "object",
"properties": {
"entity_id": {
"type": "string",
"description": "Entity ID, e.g. DP-005, SMELL-01, RF-001.",
},
"detail_level": {
"type": "string",
"description": "How much detail to include.",
"enum": ["minimal", "summary", "detailed", "full"],
"default": "summary",
},
},
"required": ["entity_id"],
},
}),
json!({
"name": "get_neighbors",
"description": DESC_GET_NEIGHBORS,
"inputSchema": {
"type": "object",
"properties": {
"entity_id": {
"type": "string",
"description": "Source entity ID.",
},
"relation_type": {
"type": "string",
"description": "Filter by relation type.",
"enum": [
"solves",
"solved_by",
"enforces",
"violates",
"related_to",
],
},
},
"required": ["entity_id"],
},
}),
json!({
"name": "find_path",
"description": DESC_FIND_PATH,
"inputSchema": {
"type": "object",
"properties": {
"from_id": {
"type": "string",
"description": "Starting entity ID.",
},
"to_id": {
"type": "string",
"description": "Target entity ID.",
},
"max_depth": {
"type": "integer",
"description": "Maximum traversal depth.",
"minimum": 1,
"maximum": 10,
"default": 5,
},
},
"required": ["from_id", "to_id"],
},
}),
json!({
"name": "analyze_code",
"description": DESC_ANALYZE_CODE,
"inputSchema": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Source code to analyze.",
},
"language": {
"type": "string",
"description": "Programming language (python, java, go, rust, typescript, cpp, csharp, kotlin, php, ruby).",
"default": "python",
},
},
"required": ["code"],
},
}),
json!({
"name": "suggest_refactorings",
"description": DESC_SUGGEST_REFACTORINGS,
"inputSchema": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Source code to analyze.",
},
"language": {
"type": "string",
"description": "Programming language (python, java, go, rust, typescript, cpp, csharp, kotlin, php, ruby).",
"default": "python",
},
"top_k": {
"type": "integer",
"description": "Number of suggestions per detected smell.",
"minimum": 1,
"maximum": 10,
"default": 3,
},
},
"required": ["code"],
},
}),
json!({
"name": "add_insight",
"description": DESC_ADD_INSIGHT,
"inputSchema": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "Free-text insight content (decision, lesson learned, architectural note).",
},
"tags": {
"type": "array",
"items": { "type": "string" },
"description": "Optional tags for categorization.",
},
"linked_entities": {
"type": "array",
"items": { "type": "string" },
"description": "Optional entity IDs to explicitly link (e.g. DP-005, SMELL-01).",
},
"project": {
"type": "string",
"description": "Optional project name to tag the insight with.",
},
},
"required": ["text"],
},
}),
json!({
"name": "confirm_links",
"description": DESC_CONFIRM_LINKS,
"inputSchema": {
"type": "object",
"properties": {
"insight_id": {
"type": "string",
"description": "ID of the insight to confirm links for (e.g. TK-001).",
},
"accepted": {
"type": "array",
"items": { "type": "string" },
"description": "Entity IDs the user confirmed as valid links.",
},
"rejected": {
"type": "array",
"items": { "type": "string" },
"description": "Entity IDs the user rejected as invalid links.",
},
"merged_with": {
"type": "string",
"description": "Optional insight ID to merge with (supersedes relation).",
},
},
"required": ["insight_id", "accepted"],
},
}),
json!({
"name": "search_insights",
"description": DESC_SEARCH_INSIGHTS,
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Natural-language search query over user insights.",
},
"limit": {
"type": "integer",
"description": "Maximum results to return.",
"minimum": 1,
"maximum": 20,
"default": 10,
},
},
"required": ["query"],
},
}),
]
}
pub fn resource_schemas() -> Vec<Value> {
vec![
json!({
"uri": "episteme://stats",
"name": "Knowledge Graph Statistics",
"description": "Aggregate statistics about the knowledge graph.",
"mimeType": "application/json",
}),
json!({
"uri": "episteme://categories",
"name": "Categories and Entity Types",
"description": "Category and entity type listing.",
"mimeType": "application/json",
}),
json!({
"uri": "episteme://contradictions",
"name": "Contradictions",
"description": "Entities with conflicting relations.",
"mimeType": "application/json",
}),
]
}