@ppdocs/mcp 3.2.7 → 3.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,7 @@
8
8
  * 📝 工作流: kg_task, kg_files, kg_discuss (3个)
9
9
  * 🔬 代码分析: code_scan, code_query, code_impact, code_context (4个)
10
10
  */
11
+ import { createContext } from './shared.js';
11
12
  import { registerInitTool } from './init.js';
12
13
  import { registerStatusTool } from './kg_status.js';
13
14
  import { registerDocTools } from './docs.js';
@@ -18,18 +19,20 @@ import { registerFileTools } from './files.js';
18
19
  import { registerDiscussionTools } from './discussion.js';
19
20
  import { registerAnalyzerTools } from './analyzer.js';
20
21
  export function registerTools(server, projectId, user, onProjectChange) {
21
- // 🔗 初始化 (kg_init 运行时项目切换)
22
- registerInitTool(server, projectId, onProjectChange || (() => { }));
22
+ // 创建共享可变上下文所有工具捕获此对象引用
23
+ const ctx = createContext(projectId, user);
24
+ // 🔗 初始化 (kg_init — 运行时项目切换,更新 ctx)
25
+ registerInitTool(server, ctx, onProjectChange || (() => { }));
23
26
  // 📊 导航 (kg_status + kg_tree在docs中)
24
- registerStatusTool(server, projectId);
27
+ registerStatusTool(server, ctx);
25
28
  // 📚 知识 (kg_doc + kg_tree + kg_projects + kg_rules)
26
- registerDocTools(server, projectId);
27
- registerProjectTools(server, projectId);
28
- registerRuleTools(server, projectId);
29
+ registerDocTools(server, ctx.projectId);
30
+ registerProjectTools(server, ctx.projectId);
31
+ registerRuleTools(server, ctx.projectId);
29
32
  // 📝 工作流 (kg_task + kg_files + kg_discuss)
30
- registerTaskTools(server, projectId, user);
33
+ registerTaskTools(server, ctx.projectId, ctx.user);
31
34
  registerFileTools(server);
32
- registerDiscussionTools(server, projectId);
35
+ registerDiscussionTools(server, ctx.projectId);
33
36
  // 🔬 代码分析 (不变)
34
- registerAnalyzerTools(server, projectId);
37
+ registerAnalyzerTools(server, ctx.projectId);
35
38
  }
@@ -5,9 +5,8 @@
5
5
  * - 智能体调用 kg_init 传入 projectPath
6
6
  * - MCP 从该路径读取 .ppdocs 配置
7
7
  * - 重新初始化 HTTP Client 指向正确项目
8
- * - 后续所有工具调用自动使用新的项目上下文
8
+ * - 更新共享 McpContext,所有工具自动获取新 projectId
9
9
  */
10
10
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
11
- /** 获取当前已初始化的 projectId */
12
- export declare function getActiveProjectId(): string | null;
13
- export declare function registerInitTool(server: McpServer, defaultProjectId: string, onProjectChange: (newProjectId: string, newApiUrl: string) => void): void;
11
+ import { type McpContext } from './shared.js';
12
+ export declare function registerInitTool(server: McpServer, ctx: McpContext, onProjectChange: (newProjectId: string, newApiUrl: string) => void): void;
@@ -5,20 +5,15 @@
5
5
  * - 智能体调用 kg_init 传入 projectPath
6
6
  * - MCP 从该路径读取 .ppdocs 配置
7
7
  * - 重新初始化 HTTP Client 指向正确项目
8
- * - 后续所有工具调用自动使用新的项目上下文
8
+ * - 更新共享 McpContext,所有工具自动获取新 projectId
9
9
  */
10
10
  import * as fs from 'fs';
11
11
  import * as path from 'path';
12
12
  import { z } from 'zod';
13
13
  import { initClient } from '../storage/httpClient.js';
14
14
  import { wrap, safeTool } from './shared.js';
15
- // 当前会话的项目上下文 (模块级单例)
16
- let currentProjectId = null;
15
+ // 当前会话的 API URL (用于幂等检查)
17
16
  let currentApiUrl = null;
18
- /** 获取当前已初始化的 projectId */
19
- export function getActiveProjectId() {
20
- return currentProjectId;
21
- }
22
17
  /** 尝试从指定目录读取 .ppdocs 配置 */
23
18
  function readPpdocsFrom(dir) {
24
19
  const configPath = path.join(dir, '.ppdocs');
@@ -38,8 +33,8 @@ function readPpdocsFrom(dir) {
38
33
  return null;
39
34
  }
40
35
  }
41
- export function registerInitTool(server, defaultProjectId, onProjectChange) {
42
- server.tool('kg_init', '🔗 项目上下文初始化 — 读取指定目录的 .ppdocs 配置,切换 MCP 连接到对应项目。首次对话建议调用。不传 projectPath 则使用当前工作目录', {
36
+ export function registerInitTool(server, ctx, onProjectChange) {
37
+ server.tool('kg_init', '🔗 项目上下文初始化 — 读取指定目录的 .ppdocs 配置,切换 MCP 连接到对应项目。首次对话必须调用。不传 projectPath 则使用当前工作目录', {
43
38
  projectPath: z.string().optional().describe('项目根目录的绝对路径(含 .ppdocs 文件),不传则使用 cwd'),
44
39
  }, async ({ projectPath }) => safeTool(async () => {
45
40
  const targetDir = projectPath || process.cwd();
@@ -52,7 +47,7 @@ export function registerInitTool(server, defaultProjectId, onProjectChange) {
52
47
  `或通过 WebUI 绑定项目:\n` +
53
48
  ` npx @ppdocs/mcp webui`);
54
49
  }
55
- // 2. 检查是否需要切换
50
+ // 2. 幂等检查
56
51
  if (currentApiUrl === config.apiUrl) {
57
52
  return wrap(`✅ 项目上下文已就绪 (无需切换)\n\n` +
58
53
  `📂 项目: ${config.projectId}\n` +
@@ -61,9 +56,11 @@ export function registerInitTool(server, defaultProjectId, onProjectChange) {
61
56
  }
62
57
  // 3. 重新初始化 HTTP Client
63
58
  initClient(config.apiUrl);
64
- currentProjectId = config.projectId;
65
59
  currentApiUrl = config.apiUrl;
66
- // 4. 通知主进程更新工具注册的 projectId
60
+ // 4. 更新共享上下文 — 所有工具立刻获得新 projectId
61
+ ctx.projectId = config.projectId;
62
+ ctx.user = config.user;
63
+ // 5. 通知主进程
67
64
  onProjectChange(config.projectId, config.apiUrl);
68
65
  return wrap(`✅ 项目上下文已初始化\n\n` +
69
66
  `📂 项目: ${config.projectId}\n` +
@@ -2,4 +2,5 @@
2
2
  * 📊 kg_status — 项目速览仪表盘 (新增)
3
3
  */
4
4
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
- export declare function registerStatusTool(server: McpServer, projectId: string): void;
5
+ import { type McpContext } from './shared.js';
6
+ export declare function registerStatusTool(server: McpServer, ctx: McpContext): void;
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { getClient } from '../storage/httpClient.js';
5
5
  import { wrap, safeTool } from './shared.js';
6
- export function registerStatusTool(server, projectId) {
6
+ export function registerStatusTool(server, ctx) {
7
7
  const client = () => getClient();
8
8
  server.tool('kg_status', '📊 项目速览仪表盘 — 一键了解项目健康。返回: 文档总数、目录数、活跃任务数、最近变更。每次对话开始建议首先调用', {}, async () => safeTool(async () => {
9
9
  const [docs, activeTasks] = await Promise.all([
@@ -20,7 +20,7 @@ export function registerStatusTool(server, projectId) {
20
20
  statusMap.set(s, (statusMap.get(s) || 0) + 1);
21
21
  }
22
22
  const lines = [
23
- `📊 项目速览 [${projectId}]`,
23
+ `📊 项目速览 [${ctx.projectId}]`,
24
24
  ``,
25
25
  `📄 文档: ${docCount} 个 | 📁 目录: ${dirCount} 个`,
26
26
  `📝 活跃任务: ${activeTasks.length} 个`,
@@ -3,6 +3,13 @@
3
3
  * 合并原 helpers.ts + 新增 safeTool / withCross 模式
4
4
  */
5
5
  import type { DocData } from '../storage/types.js';
6
+ /** 运行时可变上下文 — 所有工具通过引用获取最新值 */
7
+ export interface McpContext {
8
+ projectId: string;
9
+ user: string;
10
+ }
11
+ /** 创建可变上下文对象 (工具闭包捕获此对象的引用,kg_init 更新其属性) */
12
+ export declare function createContext(projectId: string, user: string): McpContext;
6
13
  export declare function wrap(text: string): {
7
14
  content: {
8
15
  type: "text";
@@ -2,6 +2,10 @@
2
2
  * MCP 工具共享模块
3
3
  * 合并原 helpers.ts + 新增 safeTool / withCross 模式
4
4
  */
5
+ /** 创建可变上下文对象 (工具闭包捕获此对象的引用,kg_init 更新其属性) */
6
+ export function createContext(projectId, user) {
7
+ return { projectId, user };
8
+ }
5
9
  // ==================== MCP 返回包装 ====================
6
10
  export function wrap(text) {
7
11
  return { content: [{ type: 'text', text }] };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ppdocs/mcp",
3
- "version": "3.2.7",
3
+ "version": "3.2.8",
4
4
  "description": "ppdocs MCP Server - Knowledge Graph for Claude",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",