2025-12-05 20:29:51 -06:00
#!/usr/bin/env python3
"""
True MCP Server for Claude Code integration .
Wraps the Claude OS REST API as a proper MCP server with stdio transport .
Server name is " code-forge " for backwards compatibility with existing
memories and documentation , but it IS Claude OS .
Usage :
Run : . / install . sh ( this will configure everything )
Or manually add to ~ / . claude / settings . json :
{
" mcpServers " : {
" code-forge " : {
" command " : " /path/to/claude-os/venv/bin/python3 " ,
" args " : [ " /path/to/claude-os/mcp_server/claude_code_mcp.py " ] ,
" env " : {
" CLAUDE_OS_API " : " http://localhost:8051 "
}
}
}
}
"""
import asyncio
import json
import os
import sys
from typing import Any
import httpx
from mcp . server import Server
from mcp . server . stdio import stdio_server
from mcp . types import Tool , TextContent
# Configuration
API_BASE = os . environ . get ( " CLAUDE_OS_API " , " http://localhost:8051 " )
# Initialize MCP server - named "code-forge" for backwards compatibility
server = Server ( " code-forge " )
def api_url ( path : str ) - > str :
""" Build full API URL. """
return f " { API_BASE } { path } "
async def api_get ( path : str ) - > dict :
""" Make GET request to API. """
async with httpx . AsyncClient ( ) as client :
response = await client . get ( api_url ( path ) , timeout = 30.0 )
response . raise_for_status ( )
return response . json ( )
async def api_post ( path : str , data : dict = None ) - > dict :
""" Make POST request to API. """
async with httpx . AsyncClient ( ) as client :
response = await client . post ( api_url ( path ) , json = data or { } , timeout = 60.0 )
response . raise_for_status ( )
return response . json ( )
async def api_delete ( path : str ) - > dict :
""" Make DELETE request to API. """
async with httpx . AsyncClient ( ) as client :
response = await client . delete ( api_url ( path ) , timeout = 30.0 )
response . raise_for_status ( )
return response . json ( )
2025-12-11 12:56:49 -06:00
async def api_put ( path : str , data : dict = None ) - > dict :
""" Make PUT request to API. """
async with httpx . AsyncClient ( ) as client :
response = await client . put ( api_url ( path ) , json = data or { } , timeout = 30.0 )
response . raise_for_status ( )
return response . json ( )
2025-12-05 20:29:51 -06:00
@server.list_tools ( )
async def list_tools ( ) - > list [ Tool ] :
""" List available Claude OS tools.
Tool names match what templates / commands expect :
- mcp__code - forge__search_knowledge_base
- mcp__code - forge__list_knowledge_bases
- mcp__code - forge__list_documents
- etc .
"""
return [
# Knowledge Base Tools
Tool (
name = " list_knowledge_bases " ,
description = " List all knowledge bases in Claude OS " ,
inputSchema = {
" type " : " object " ,
" properties " : { } ,
" required " : [ ]
}
) ,
Tool (
name = " create_knowledge_base " ,
description = " Create a new knowledge base " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" name " : { " type " : " string " , " description " : " Name of the knowledge base " } ,
" kb_type " : { " type " : " string " , " enum " : [ " generic " , " code " , " documentation " ] , " default " : " generic " } ,
" description " : { " type " : " string " , " description " : " Description of the KB " }
} ,
" required " : [ " name " ]
}
) ,
Tool (
name = " search_knowledge_base " ,
description = " Search/query a knowledge base using RAG. Returns relevant documents and an AI-generated answer. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base to search " } ,
" query " : { " type " : " string " , " description " : " Search query " } ,
" top_k " : { " type " : " integer " , " default " : 5 , " description " : " Number of results to return " } ,
" use_hybrid " : { " type " : " boolean " , " default " : True , " description " : " Use hybrid search (semantic + keyword) " }
} ,
" required " : [ " kb_name " , " query " ]
}
) ,
Tool (
name = " get_kb_stats " ,
description = " Get statistics for a knowledge base (document count, chunk count, etc.) " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base " }
} ,
" required " : [ " kb_name " ]
}
) ,
Tool (
name = " list_documents " ,
description = " List all documents in a knowledge base " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base " }
} ,
" required " : [ " kb_name " ]
}
) ,
Tool (
name = " delete_knowledge_base " ,
description = " Delete a knowledge base and all its documents " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base to delete " }
} ,
" required " : [ " kb_name " ]
}
) ,
# Project Tools
Tool (
name = " list_projects " ,
description = " List all projects registered with Claude OS " ,
inputSchema = {
" type " : " object " ,
" properties " : { } ,
" required " : [ ]
}
) ,
Tool (
name = " create_project " ,
description = " Create/register a new project with Claude OS " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" name " : { " type " : " string " , " description " : " Project name " } ,
" path " : { " type " : " string " , " description " : " Absolute path to project directory " } ,
" description " : { " type " : " string " , " description " : " Project description " }
} ,
" required " : [ " name " , " path " ]
}
) ,
Tool (
name = " get_project " ,
description = " Get details for a specific project " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" project_id " : { " type " : " integer " , " description " : " Project ID " }
} ,
" required " : [ " project_id " ]
}
) ,
# Indexing Tools
Tool (
name = " index_structural " ,
description = " Run tree-sitter structural indexing on code files. Fast indexing that extracts functions, classes, imports. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base " } ,
" path " : { " type " : " string " , " description " : " Path to directory to index " }
} ,
" required " : [ " kb_name " , " path " ]
}
) ,
Tool (
name = " index_semantic " ,
2025-12-08 17:19:15 -05:00
description = " Run semantic embedding indexing on a knowledge base. Creates vector embeddings for similarity search. Runs in background by default - returns job_id to check progress at /api/jobs/ {job_id} . " ,
2025-12-05 20:29:51 -06:00
inputSchema = {
" type " : " object " ,
" properties " : {
2025-12-08 17:19:15 -05:00
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base " } ,
" project_path " : { " type " : " string " , " description " : " Path to project to index " } ,
" selective " : { " type " : " boolean " , " description " : " If true, only index top 20 % most important files + docs (default: true) " } ,
" background " : { " type " : " boolean " , " description " : " If true, run in background (default: true). Set false to block until complete. " }
2025-12-05 20:29:51 -06:00
} ,
2025-12-08 17:19:15 -05:00
" required " : [ " kb_name " , " project_path " ]
2025-12-05 20:29:51 -06:00
}
) ,
# Document Management
Tool (
name = " upload_document " ,
description = " Upload/save a document or memory to a knowledge base " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base " } ,
" content " : { " type " : " string " , " description " : " Content to save (markdown supported) " } ,
" filename " : { " type " : " string " , " description " : " Filename for the document (e.g., ' my-memory.md ' ) " } ,
" title " : { " type " : " string " , " description " : " Title for the document " } ,
" tags " : { " type " : " array " , " items " : { " type " : " string " } , " description " : " Tags for categorization " }
} ,
" required " : [ " kb_name " , " content " , " filename " ]
}
) ,
Tool (
name = " delete_document " ,
description = " Delete a document from a knowledge base " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base " } ,
" filename " : { " type " : " string " , " description " : " Filename of the document to delete " }
} ,
" required " : [ " kb_name " , " filename " ]
}
) ,
# Utility Tools
Tool (
name = " get_ollama_models " ,
description = " List available Ollama models for embeddings and LLM " ,
inputSchema = {
" type " : " object " ,
" properties " : { } ,
" required " : [ ]
}
) ,
Tool (
name = " health_check " ,
description = " Check if Claude OS API server is running and healthy " ,
inputSchema = {
" type " : " object " ,
" properties " : { } ,
" required " : [ ]
}
2025-12-11 12:56:49 -06:00
) ,
# Session Tools
Tool (
name = " list_sessions " ,
description = " List Claude Code session files for a project. Sessions are stored in ~/.claude/projects/ { encoded-path}/ and contain conversation history. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" project_path " : { " type " : " string " , " description " : " Absolute path to project directory (e.g., /Users/x/Projects/myapp) " } ,
" limit " : { " type " : " integer " , " default " : 50 , " description " : " Maximum sessions to return (default: 50) " }
} ,
" required " : [ " project_path " ]
}
) ,
Tool (
name = " extract_session_insights " ,
description = " Extract insights from a Claude Code session file using LLM. Analyzes conversation to find decisions, patterns, solutions, and blockers. Optionally saves insights to a knowledge base. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" session_path " : { " type " : " string " , " description " : " Absolute path to .jsonl session file " } ,
" kb_name " : { " type " : " string " , " description " : " Knowledge base name to save insights (optional) " } ,
" auto_save " : { " type " : " boolean " , " default " : False , " description " : " Auto-save all insights without prompting " } ,
" insight_types " : {
" type " : " array " ,
" items " : { " type " : " string " , " enum " : [ " decision " , " pattern " , " solution " , " blocker " ] } ,
" default " : [ " decision " , " pattern " , " solution " , " blocker " ] ,
" description " : " Types of insights to extract "
} ,
" min_confidence " : { " type " : " number " , " default " : 0.7 , " description " : " Minimum confidence threshold (0.0-1.0) " }
} ,
" required " : [ " session_path " ]
}
) ,
# Skill Management Tools
Tool (
name = " list_skills " ,
description = " List all skills (global and project-level). Global skills are in ~/.claude/skills/, project skills are in {project} /.claude/skills/. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" project_path " : { " type " : " string " , " description " : " Project path to include project-level skills (optional) " } ,
" include_content " : { " type " : " boolean " , " default " : False , " description " : " Include full skill content " }
} ,
" required " : [ ]
}
) ,
Tool (
name = " list_skill_templates " ,
description = " List available skill templates that can be installed to projects. Templates are organized by category. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" category " : { " type " : " string " , " description " : " Filter by category (optional) " }
} ,
" required " : [ ]
}
) ,
Tool (
name = " get_skill " ,
description = " Get skill details including full content. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" name " : { " type " : " string " , " description " : " Skill name " } ,
" scope " : { " type " : " string " , " enum " : [ " global " , " project " ] , " description " : " Where the skill is located " } ,
" project_path " : { " type " : " string " , " description " : " Project path (required if scope is ' project ' ) " }
} ,
" required " : [ " name " , " scope " ]
}
) ,
Tool (
name = " install_skill_template " ,
description = " Install a skill template to a project. Copies the template to {project} /.claude/skills/. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" template_name " : { " type " : " string " , " description " : " Name of template to install " } ,
" project_path " : { " type " : " string " , " description " : " Project path to install to " } ,
" custom_name " : { " type " : " string " , " description " : " Custom name for installed skill (optional) " }
} ,
" required " : [ " template_name " , " project_path " ]
}
) ,
Tool (
name = " create_skill " ,
description = " Create a custom skill for a project. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" name " : { " type " : " string " , " description " : " Skill name " } ,
" description " : { " type " : " string " , " description " : " Skill description " } ,
" content " : { " type " : " string " , " description " : " Skill content (markdown) " } ,
" project_path " : { " type " : " string " , " description " : " Project path " } ,
" category " : { " type " : " string " , " description " : " Category (optional) " } ,
" tags " : { " type " : " array " , " items " : { " type " : " string " } , " description " : " Tags (optional) " }
} ,
" required " : [ " name " , " description " , " content " , " project_path " ]
}
) ,
Tool (
name = " update_skill " ,
description = " Update an existing project skill. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" name " : { " type " : " string " , " description " : " Skill name " } ,
" project_path " : { " type " : " string " , " description " : " Project path " } ,
" content " : { " type " : " string " , " description " : " New content (optional) " } ,
" description " : { " type " : " string " , " description " : " New description (optional) " } ,
" tags " : { " type " : " array " , " items " : { " type " : " string " } , " description " : " New tags (optional) " }
} ,
" required " : [ " name " , " project_path " ]
}
) ,
Tool (
name = " delete_skill " ,
description = " Delete a project skill. Cannot delete global skills. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" name " : { " type " : " string " , " description " : " Skill name to delete " } ,
" project_path " : { " type " : " string " , " description " : " Project path " }
} ,
" required " : [ " name " , " project_path " ]
}
2026-02-06 10:08:00 -06:00
) ,
# Knowledge Lifecycle Tools
Tool (
name = " kb_lifecycle_health " ,
description = " Get a comprehensive health report for a knowledge base including duplicate detection, embedding coverage, age distribution, and recommendations. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base " }
} ,
" required " : [ " kb_name " ]
}
) ,
Tool (
name = " kb_lifecycle_dedup " ,
description = " Scan for and merge duplicate documents in a knowledge base. Use action= ' scan ' to find duplicates, action= ' merge ' to merge them. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base " } ,
" action " : { " type " : " string " , " enum " : [ " scan " , " merge " ] , " description " : " Action to perform: scan for duplicates or merge them " } ,
" threshold " : { " type " : " number " , " default " : 0.85 , " description " : " Similarity threshold for scan (0.0-1.0) " } ,
" max_pairs " : { " type " : " integer " , " default " : 100 , " description " : " Maximum duplicate pairs to return " } ,
" keep_doc_id " : { " type " : " string " , " description " : " Document ID to keep (required for merge) " } ,
" remove_doc_ids " : { " type " : " array " , " items " : { " type " : " string " } , " description " : " Document IDs to remove (required for merge) " } ,
" dry_run " : { " type " : " boolean " , " default " : False , " description " : " Preview changes without applying " }
} ,
" required " : [ " kb_name " , " action " ]
}
) ,
Tool (
name = " kb_lifecycle_consolidate " ,
description = " Consolidate multiple related documents into a single merged document using LLM-powered summarization. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base " } ,
" doc_ids " : { " type " : " array " , " items " : { " type " : " string " } , " description " : " Document IDs to consolidate " } ,
" new_filename " : { " type " : " string " , " description " : " Filename for the consolidated document " } ,
" dry_run " : { " type " : " boolean " , " default " : False , " description " : " Preview without consolidating " }
} ,
" required " : [ " kb_name " , " doc_ids " , " new_filename " ]
}
) ,
Tool (
name = " kb_lifecycle_archive " ,
description = " Manage document archival: archive, restore, list archived, or find stale documents. " ,
inputSchema = {
" type " : " object " ,
" properties " : {
" kb_name " : { " type " : " string " , " description " : " Name of the knowledge base " } ,
" action " : { " type " : " string " , " enum " : [ " archive " , " restore " , " list " , " stale " ] , " description " : " Archival action to perform " } ,
" doc_ids " : { " type " : " array " , " items " : { " type " : " string " } , " description " : " Document IDs (required for archive/restore) " } ,
" reason " : { " type " : " string " , " default " : " manual " , " description " : " Reason for archiving " } ,
" stale_days " : { " type " : " integer " , " default " : 90 , " description " : " Days threshold for stale detection " }
} ,
" required " : [ " kb_name " , " action " ]
}
2025-12-05 20:29:51 -06:00
)
]
@server.call_tool ( )
async def call_tool ( name : str , arguments : dict [ str , Any ] ) - > list [ TextContent ] :
""" Execute a Claude OS tool. """
try :
result = await _execute_tool ( name , arguments )
return [ TextContent ( type = " text " , text = json . dumps ( result , indent = 2 ) ) ]
except httpx . HTTPStatusError as e :
error_msg = f " API error: { e . response . status_code } - { e . response . text } "
return [ TextContent ( type = " text " , text = json . dumps ( { " error " : error_msg } ) ) ]
except httpx . ConnectError :
return [ TextContent ( type = " text " , text = json . dumps ( {
" error " : " Cannot connect to Claude OS API. Is the server running? Start with: ./start_all_services.sh "
} ) ) ]
except Exception as e :
return [ TextContent ( type = " text " , text = json . dumps ( { " error " : str ( e ) } ) ) ]
async def _execute_tool ( name : str , args : dict [ str , Any ] ) - > dict :
""" Route tool calls to appropriate API endpoints. """
# Knowledge Base Tools
if name == " list_knowledge_bases " :
return await api_get ( " /api/kb " )
elif name == " create_knowledge_base " :
return await api_post ( " /api/kb " , {
" name " : args [ " name " ] ,
" kb_type " : args . get ( " kb_type " , " generic " ) ,
" description " : args . get ( " description " , " " )
} )
elif name == " search_knowledge_base " :
return await api_post ( f " /api/kb/ { args [ ' kb_name ' ] } /chat " , {
" query " : args [ " query " ] ,
" top_k " : args . get ( " top_k " , 5 ) ,
" use_hybrid " : args . get ( " use_hybrid " , True )
} )
elif name == " get_kb_stats " :
return await api_get ( f " /api/kb/ { args [ ' kb_name ' ] } /stats " )
elif name == " list_documents " :
return await api_get ( f " /api/kb/ { args [ ' kb_name ' ] } /documents " )
elif name == " delete_knowledge_base " :
return await api_delete ( f " /api/kb/ { args [ ' kb_name ' ] } " )
# Project Tools
elif name == " list_projects " :
return await api_get ( " /api/projects " )
elif name == " create_project " :
return await api_post ( " /api/projects " , {
" name " : args [ " name " ] ,
" path " : args [ " path " ] ,
" description " : args . get ( " description " , " " )
} )
elif name == " get_project " :
return await api_get ( f " /api/projects/ { args [ ' project_id ' ] } " )
# Indexing Tools
elif name == " index_structural " :
return await api_post ( f " /api/kb/ { args [ ' kb_name ' ] } /index-structural " , {
" path " : args [ " path " ]
} )
elif name == " index_semantic " :
2025-12-08 17:19:15 -05:00
return await api_post ( f " /api/kb/ { args [ ' kb_name ' ] } /index-semantic " , {
" project_path " : args [ " project_path " ] ,
" selective " : args . get ( " selective " , True ) ,
" background " : args . get ( " background " , True )
} )
2025-12-05 20:29:51 -06:00
# Document Management
elif name == " upload_document " :
2026-02-06 10:08:00 -06:00
return await api_post ( f " /api/kb/ { args [ ' kb_name ' ] } /documents/content " , {
2025-12-05 20:29:51 -06:00
" content " : args [ " content " ] ,
" filename " : args [ " filename " ] ,
" metadata " : {
" title " : args . get ( " title " , " " ) ,
" tags " : args . get ( " tags " , [ ] )
}
} )
elif name == " delete_document " :
return await api_delete ( f " /api/kb/ { args [ ' kb_name ' ] } /documents/ { args [ ' filename ' ] } " )
# Utility Tools
elif name == " get_ollama_models " :
return await api_get ( " /api/ollama/models " )
elif name == " health_check " :
try :
# Simple health check - list KBs should work if server is up
result = await api_get ( " /api/kb " )
return { " status " : " healthy " , " message " : " Claude OS is running " , " kb_count " : len ( result . get ( " knowledge_bases " , [ ] ) ) }
except Exception as e :
return { " status " : " unhealthy " , " error " : str ( e ) }
2025-12-11 12:56:49 -06:00
# Session Tools
elif name == " list_sessions " :
return await api_get ( f " /api/sessions/list?project_path= { args [ ' project_path ' ] } &limit= { args . get ( ' limit ' , 50 ) } " )
elif name == " extract_session_insights " :
return await api_post ( " /api/sessions/extract " , {
" session_path " : args [ " session_path " ] ,
" kb_name " : args . get ( " kb_name " ) ,
" auto_save " : args . get ( " auto_save " , False ) ,
" insight_types " : args . get ( " insight_types " ) ,
" min_confidence " : args . get ( " min_confidence " , 0.7 )
} )
# Skill Management Tools
elif name == " list_skills " :
project_path = args . get ( " project_path " , " " )
include_content = args . get ( " include_content " , False )
url = f " /api/skills?include_content= { include_content } "
if project_path :
url + = f " &project_path= { project_path } "
return await api_get ( url )
elif name == " list_skill_templates " :
category = args . get ( " category " )
url = " /api/skills/templates "
if category :
url + = f " ?category= { category } "
return await api_get ( url )
elif name == " get_skill " :
scope = args [ " scope " ]
name_param = args [ " name " ]
project_path = args . get ( " project_path " , " " )
url = f " /api/skills/ { scope } / { name_param } "
if project_path :
url + = f " ?project_path= { project_path } "
return await api_get ( url )
elif name == " install_skill_template " :
return await api_post ( f " /api/skills/install?project_path= { args [ ' project_path ' ] } " , {
" template_name " : args [ " template_name " ] ,
" custom_name " : args . get ( " custom_name " )
} )
elif name == " create_skill " :
return await api_post ( f " /api/skills?project_path= { args [ ' project_path ' ] } " , {
" name " : args [ " name " ] ,
" description " : args [ " description " ] ,
" content " : args [ " content " ] ,
" category " : args . get ( " category " ) ,
" tags " : args . get ( " tags " )
} )
elif name == " update_skill " :
return await api_put ( f " /api/skills/ { args [ ' name ' ] } ?project_path= { args [ ' project_path ' ] } " , {
" content " : args . get ( " content " ) ,
" description " : args . get ( " description " ) ,
" tags " : args . get ( " tags " )
} )
elif name == " delete_skill " :
return await api_delete ( f " /api/skills/ { args [ ' name ' ] } ?project_path= { args [ ' project_path ' ] } " )
2026-02-06 10:08:00 -06:00
# Knowledge Lifecycle Tools
elif name == " kb_lifecycle_health " :
return await api_get ( f " /api/kb/ { args [ ' kb_name ' ] } /lifecycle/health " )
elif name == " kb_lifecycle_dedup " :
action = args [ " action " ]
kb_name = args [ " kb_name " ]
if action == " scan " :
return await api_post ( f " /api/kb/ { kb_name } /lifecycle/dedup-scan " , {
" threshold " : args . get ( " threshold " , 0.85 ) ,
" max_pairs " : args . get ( " max_pairs " , 100 )
} )
elif action == " merge " :
return await api_post ( f " /api/kb/ { kb_name } /lifecycle/dedup-merge " , {
" keep_doc_id " : args [ " keep_doc_id " ] ,
" remove_doc_ids " : args [ " remove_doc_ids " ] ,
" dry_run " : args . get ( " dry_run " , False )
} )
else :
return { " error " : f " Unknown dedup action: { action } " }
elif name == " kb_lifecycle_consolidate " :
return await api_post ( f " /api/kb/ { args [ ' kb_name ' ] } /lifecycle/consolidate " , {
" doc_ids " : args [ " doc_ids " ] ,
" new_filename " : args [ " new_filename " ] ,
" dry_run " : args . get ( " dry_run " , False )
} )
elif name == " kb_lifecycle_archive " :
action = args [ " action " ]
kb_name = args [ " kb_name " ]
if action == " archive " :
return await api_post ( f " /api/kb/ { kb_name } /lifecycle/archive " , {
" doc_ids " : args [ " doc_ids " ] ,
" reason " : args . get ( " reason " , " manual " )
} )
elif action == " restore " :
return await api_post ( f " /api/kb/ { kb_name } /lifecycle/restore " , {
" doc_ids " : args [ " doc_ids " ]
} )
elif action == " list " :
return await api_get ( f " /api/kb/ { kb_name } /lifecycle/archived " )
elif action == " stale " :
stale_days = args . get ( " stale_days " , 90 )
return await api_get ( f " /api/kb/ { kb_name } /lifecycle/stale?stale_days= { stale_days } " )
else :
return { " error " : f " Unknown archive action: { action } " }
2025-12-05 20:29:51 -06:00
else :
return { " error " : f " Unknown tool: { name } " }
async def main ( ) :
""" Run the MCP server. """
async with stdio_server ( ) as ( read_stream , write_stream ) :
await server . run ( read_stream , write_stream , server . create_initialization_options ( ) )
if __name__ == " __main__ " :
asyncio . run ( main ( ) )