Files
sanguo_llmwiki/mcp_server/tools/wiki_query.py
T
claude_dev dfd8421dc6 feat(§03): 实现 MCP Server 核心 - Storage/Service/Tool/MCP Protocol Layers
**Storage Layer:**
- Database 类(aiosqlite + WAL + 并发保护)
- WikiPage 数据模型
- fix_dirty_states 恢复机制
- FTS5 全文搜索支持
- 完整的 SQLite 表结构

**Service Layer:**
- CacheService(LRU 缓存 + TTL + 大小限制)
- QueryService(查询服务)
- ParserService(Markdown 解析)
- IndexerService(索引服务)
- GraphService(链接图服务)

**Tool Layer (8 个 MCP Tools):**
- wiki_query - FTS5 全文搜索 + 标签过滤
- memory_bridge - 按工具来源浏览
- wiki_status - 索引状态
- wiki_lint - 健康审计
- cross_linker - 缺失链接发现
- tag_taxonomy - 标签一致性
- wiki_synthesize - 跨概念综合分析
- daily_update - 日常维护 + hot.md 生成

**MCP Protocol Layer:**
- MCP 协议解析和封装
- 工具注册和路由
- 错误处理和日志
- stdio 模式支持

**配置和部署:**
- requirements.txt
- config.example.yaml
- ecosystem.config.cjs (PM2)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:32:43 +08:00

117 lines
3.6 KiB
Python

"""
Tool Layer - wiki_query 工具
基于 SQLite 索引查询 wiki,支持关键词(FTS5)和标签搜索。
参考设计文档:第 2.2 节
"""
import logging
from typing import List, Dict, Any
from ..services import QueryService
logger = logging.getLogger(__name__)
class WikiQueryTool:
"""wiki_query 工具实现"""
def __init__(self, query_service: QueryService):
self.query_service = query_service
async def handle(self, query: str = "", tags: List[str] = None, limit: int = 10) -> Dict[str, Any]:
"""
查询 wiki 页面
Args:
query: 查询关键词(FTS5 全文搜索)
tags: 标签过滤
limit: 返回数量限制
Returns:
{
"results": [
{
"path": "practices/moziplus-orchestration.md",
"title": "moziplus 编排实践",
"category": "practices",
"tags": ["moziplus", "orchestration"],
"summary": "...",
"lifecycle": "verified",
"updated_at": "2024-06-15T10:30:00",
"wikilink": "[[practices/moziplus-orchestration.md|moziplus 编排实践]]"
}
],
"total": 5,
"query": "...",
"tags": [...]
}
"""
if tags is None:
tags = []
results = []
# 组合查询
if query and tags:
# 先 FTS5 搜索,再标签过滤
fts_results = await self.query_service.search(query, limit * 2)
filtered = [r for r in fts_results if any(t in r.tags for t in tags)]
pages = filtered[:limit]
elif query:
# 仅 FTS5 搜索
pages = await self.query_service.search(query, limit)
elif tags:
# 仅标签搜索
pages = await self.query_service.search_by_tags(tags[:5]) # 限制标签数量
pages = pages[:limit]
else:
# 无查询条件,返回最近更新的页面
pages = []
# 格式化结果
for page in pages:
results.append({
"path": page.path,
"title": page.title,
"category": page.category,
"tags": page.tags,
"summary": page.summary,
"lifecycle": page.lifecycle,
"updated_at": page.updated_at,
"wikilink": f"[[{page.path}|{page.title}]]"
})
return {
"results": results,
"total": len(results),
"query": query,
"tags": tags
}
def get_schema(self) -> dict:
"""返回 MCP Tool schema"""
return {
"name": "wiki_query",
"description": "查询 wiki 页面,支持关键词(FTS5)和标签搜索",
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "查询关键词(FTS5 全文搜索)"
},
"tags": {
"type": "array",
"items": {"type": "string"},
"description": "标签过滤"
},
"limit": {
"type": "integer",
"default": 10,
"description": "返回数量限制"
}
}
}
}