@panguard-ai/panguard-mcp 0.1.0 → 0.1.1

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.
@@ -0,0 +1,13 @@
1
+ /**
2
+ * MCP Config Module - Platform detection and config injection
3
+ * MCP 設定模組 - 平台偵測與設定注入
4
+ *
5
+ * @module @panguard-ai/panguard-mcp/config
6
+ */
7
+ export { detectPlatforms, getConfigPath } from './platform-detector.js';
8
+ export type { PlatformId, DetectedPlatform } from './platform-detector.js';
9
+ export { injectMCPConfig, removeMCPConfig, injectAll, getInstallCommand } from './mcp-injector.js';
10
+ export type { InjectionResult } from './mcp-injector.js';
11
+ export { parseMCPServers, resolveSkillDir, discoverAllSkills } from './mcp-config-reader.js';
12
+ export type { MCPServerEntry } from './mcp-config-reader.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACxE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACnG,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC7F,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * MCP Config Module - Platform detection and config injection
3
+ * MCP 設定模組 - 平台偵測與設定注入
4
+ *
5
+ * @module @panguard-ai/panguard-mcp/config
6
+ */
7
+ export { detectPlatforms, getConfigPath } from './platform-detector.js';
8
+ export { injectMCPConfig, removeMCPConfig, injectAll, getInstallCommand } from './mcp-injector.js';
9
+ export { parseMCPServers, resolveSkillDir, discoverAllSkills } from './mcp-config-reader.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAExE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEnG,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * MCP Config Reader - Parse installed MCP servers from platform configs
3
+ * MCP 設定讀取器 - 從平台設定檔解析已安裝的 MCP 伺服器
4
+ *
5
+ * Reads each detected platform's config file and extracts all mcpServers
6
+ * entries, enabling skill discovery across Claude Code, Cursor, OpenClaw, etc.
7
+ *
8
+ * @module @panguard-ai/panguard-mcp/config/mcp-config-reader
9
+ */
10
+ import type { PlatformId } from './platform-detector.js';
11
+ /** A single MCP server entry discovered from a platform config. */
12
+ export interface MCPServerEntry {
13
+ readonly name: string;
14
+ readonly command: string;
15
+ readonly args: readonly string[];
16
+ readonly env?: Readonly<Record<string, string>>;
17
+ readonly configPath: string;
18
+ readonly platformId: PlatformId;
19
+ }
20
+ /**
21
+ * Parse mcpServers from a platform config file.
22
+ * Returns empty array on failure (missing file, bad JSON, etc.).
23
+ */
24
+ export declare function parseMCPServers(configPath: string, platformId: PlatformId): readonly MCPServerEntry[];
25
+ /**
26
+ * Resolve the skill directory from an MCP server entry.
27
+ * For npx packages: attempts require.resolve. For local paths: uses command dir.
28
+ * Returns null if resolution fails.
29
+ */
30
+ export declare function resolveSkillDir(entry: MCPServerEntry): string | null;
31
+ /**
32
+ * Discover all MCP skills installed across all detected platforms.
33
+ * Filters out Panguard's own MCP server entry.
34
+ */
35
+ export declare function discoverAllSkills(): Promise<readonly MCPServerEntry[]>;
36
+ //# sourceMappingURL=mcp-config-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-config-reader.d.ts","sourceRoot":"","sources":["../../src/config/mcp-config-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIzD,mEAAmE;AACnE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,UAAU,GACrB,SAAS,cAAc,EAAE,CAwC3B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CA8BpE;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAsB5E"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * MCP Config Reader - Parse installed MCP servers from platform configs
3
+ * MCP 設定讀取器 - 從平台設定檔解析已安裝的 MCP 伺服器
4
+ *
5
+ * Reads each detected platform's config file and extracts all mcpServers
6
+ * entries, enabling skill discovery across Claude Code, Cursor, OpenClaw, etc.
7
+ *
8
+ * @module @panguard-ai/panguard-mcp/config/mcp-config-reader
9
+ */
10
+ import { existsSync, readFileSync } from 'node:fs';
11
+ import { dirname } from 'node:path';
12
+ import { createLogger } from '@panguard-ai/core';
13
+ import { detectPlatforms, getConfigPath } from './platform-detector.js';
14
+ const logger = createLogger('panguard-mcp:config-reader');
15
+ /**
16
+ * Parse mcpServers from a platform config file.
17
+ * Returns empty array on failure (missing file, bad JSON, etc.).
18
+ */
19
+ export function parseMCPServers(configPath, platformId) {
20
+ if (!existsSync(configPath))
21
+ return [];
22
+ try {
23
+ const raw = readFileSync(configPath, 'utf-8');
24
+ const parsed = JSON.parse(raw);
25
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
26
+ return [];
27
+ const config = parsed;
28
+ const servers = config['mcpServers'];
29
+ if (!servers || typeof servers !== 'object')
30
+ return [];
31
+ const entries = [];
32
+ for (const [name, value] of Object.entries(servers)) {
33
+ if (!value || typeof value !== 'object')
34
+ continue;
35
+ const server = value;
36
+ const command = typeof server['command'] === 'string' ? server['command'] : '';
37
+ const args = Array.isArray(server['args'])
38
+ ? server['args'].filter((a) => typeof a === 'string')
39
+ : [];
40
+ if (!command)
41
+ continue;
42
+ const env = server['env'] && typeof server['env'] === 'object'
43
+ ? Object.fromEntries(Object.entries(server['env'])
44
+ .filter(([, v]) => typeof v === 'string')
45
+ .map(([k, v]) => [k, v]))
46
+ : undefined;
47
+ entries.push({ name, command, args, env, configPath, platformId });
48
+ }
49
+ return entries;
50
+ }
51
+ catch (err) {
52
+ logger.warn(`Failed to parse MCP config at ${configPath}: ${err instanceof Error ? err.message : String(err)}`);
53
+ return [];
54
+ }
55
+ }
56
+ /**
57
+ * Resolve the skill directory from an MCP server entry.
58
+ * For npx packages: attempts require.resolve. For local paths: uses command dir.
59
+ * Returns null if resolution fails.
60
+ */
61
+ export function resolveSkillDir(entry) {
62
+ // npx -y @package/name pattern
63
+ if (entry.command === 'npx' && entry.args.length >= 1) {
64
+ const pkgArg = entry.args.find((a) => !a.startsWith('-'));
65
+ if (pkgArg) {
66
+ try {
67
+ const resolved = require.resolve(`${pkgArg}/package.json`, { paths: [process.cwd()] });
68
+ return dirname(resolved);
69
+ }
70
+ catch {
71
+ return null;
72
+ }
73
+ }
74
+ }
75
+ // node /path/to/server.js pattern
76
+ if (entry.command === 'node' && entry.args.length >= 1) {
77
+ const scriptPath = entry.args[0];
78
+ if (scriptPath && existsSync(scriptPath)) {
79
+ return dirname(scriptPath);
80
+ }
81
+ }
82
+ // Direct command path
83
+ if (entry.command.startsWith('/') || entry.command.startsWith('.')) {
84
+ if (existsSync(entry.command)) {
85
+ return dirname(entry.command);
86
+ }
87
+ }
88
+ return null;
89
+ }
90
+ /**
91
+ * Discover all MCP skills installed across all detected platforms.
92
+ * Filters out Panguard's own MCP server entry.
93
+ */
94
+ export async function discoverAllSkills() {
95
+ const platforms = await detectPlatforms();
96
+ const detected = platforms.filter((p) => p.detected);
97
+ const allSkills = [];
98
+ for (const platform of detected) {
99
+ // OpenClaw uses native skills, not MCP JSON config
100
+ if (platform.id === 'openclaw')
101
+ continue;
102
+ const configPath = getConfigPath(platform.id);
103
+ const servers = parseMCPServers(configPath, platform.id);
104
+ for (const server of servers) {
105
+ // Skip Panguard's own entry
106
+ if (server.name === 'panguard')
107
+ continue;
108
+ // Skip entries that resolve to panguard packages
109
+ if (server.args.some((a) => a.includes('panguard')))
110
+ continue;
111
+ allSkills.push(server);
112
+ }
113
+ }
114
+ logger.info(`Discovered ${allSkills.length} skill(s) across ${detected.length} platform(s)`);
115
+ return allSkills;
116
+ }
117
+ //# sourceMappingURL=mcp-config-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-config-reader.js","sourceRoot":"","sources":["../../src/config/mcp-config-reader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * MCP Config Injector - Write Panguard MCP config to AI agent platforms
3
+ * MCP 設定注入器 - 將 Panguard MCP 設定寫入 AI Agent 平台
4
+ *
5
+ * Supports Claude Code, Claude Desktop, Cursor, OpenClaw, Codex, Workbuddy, NemoClaw.
6
+ *
7
+ * @module @panguard-ai/panguard-mcp/config/mcp-injector
8
+ */
9
+ import type { PlatformId } from './platform-detector.js';
10
+ export interface InjectionResult {
11
+ platformId: PlatformId;
12
+ success: boolean;
13
+ configPath: string;
14
+ backupPath?: string;
15
+ error?: string;
16
+ }
17
+ /**
18
+ * Inject Panguard MCP config into a specific platform.
19
+ * 將 Panguard MCP 設定注入特定平台。
20
+ *
21
+ * @param platformId - Target platform / 目標平台
22
+ * @returns Injection result with success status and paths.
23
+ */
24
+ export declare function injectMCPConfig(platformId: PlatformId): InjectionResult;
25
+ /**
26
+ * Remove Panguard MCP config from a specific platform.
27
+ * 從特定平台移除 Panguard MCP 設定。
28
+ */
29
+ export declare function removeMCPConfig(platformId: PlatformId): InjectionResult;
30
+ /**
31
+ * Inject Panguard MCP config into all detected platforms.
32
+ * 將 Panguard MCP 設定注入所有偵測到的平台。
33
+ */
34
+ export declare function injectAll(platformIds: PlatformId[]): Promise<InjectionResult[]>;
35
+ /**
36
+ * Get the one-liner install command for display.
37
+ * 取得用於顯示的一行安裝指令。
38
+ */
39
+ export declare function getInstallCommand(): string;
40
+ //# sourceMappingURL=mcp-injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-injector.d.ts","sourceRoot":"","sources":["../../src/config/mcp-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKzD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2ID;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,eAAe,CAuDvE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,eAAe,CAqCvE;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAErF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
@@ -0,0 +1,261 @@
1
+ /**
2
+ * MCP Config Injector - Write Panguard MCP config to AI agent platforms
3
+ * MCP 設定注入器 - 將 Panguard MCP 設定寫入 AI Agent 平台
4
+ *
5
+ * Supports Claude Code, Claude Desktop, Cursor, OpenClaw, Codex, Workbuddy, NemoClaw.
6
+ *
7
+ * @module @panguard-ai/panguard-mcp/config/mcp-injector
8
+ */
9
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, rmSync } from 'node:fs';
10
+ import { dirname, join } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { createLogger } from '@panguard-ai/core';
13
+ import { getConfigPath } from './platform-detector.js';
14
+ const logger = createLogger('panguard-mcp:injector');
15
+ /** The MCP server entry Panguard adds to config files. */
16
+ const PANGUARD_MCP_ENTRY = {
17
+ command: 'npx',
18
+ args: ['-y', '@panguard-ai/panguard-mcp'],
19
+ };
20
+ /**
21
+ * Read an existing JSON config file, or return empty object.
22
+ * 讀取現有 JSON 設定檔,或回傳空物件。
23
+ */
24
+ function readJsonSafe(filePath) {
25
+ if (!existsSync(filePath))
26
+ return {};
27
+ try {
28
+ const raw = readFileSync(filePath, 'utf-8');
29
+ const parsed = JSON.parse(raw);
30
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
31
+ return parsed;
32
+ }
33
+ return {};
34
+ }
35
+ catch {
36
+ return {};
37
+ }
38
+ }
39
+ /**
40
+ * Back up a config file before modifying it.
41
+ * 修改前備份設定檔。
42
+ */
43
+ function backupFile(filePath) {
44
+ if (!existsSync(filePath))
45
+ return undefined;
46
+ const backupPath = `${filePath}.bak.${Date.now()}`;
47
+ copyFileSync(filePath, backupPath);
48
+ logger.info(`Backed up ${filePath} -> ${backupPath}`);
49
+ return backupPath;
50
+ }
51
+ /**
52
+ * Ensure parent directory exists.
53
+ * 確保父目錄存在。
54
+ */
55
+ function ensureDir(filePath) {
56
+ const dir = dirname(filePath);
57
+ if (!existsSync(dir)) {
58
+ mkdirSync(dir, { recursive: true });
59
+ }
60
+ }
61
+ /**
62
+ * Inject Panguard MCP config for Claude Desktop.
63
+ * Claude Desktop uses: { "mcpServers": { "panguard": { "command": "...", "args": [...] } } }
64
+ */
65
+ function injectClaudeDesktop(configPath) {
66
+ const config = readJsonSafe(configPath);
67
+ const servers = config['mcpServers'] ?? {};
68
+ servers['panguard'] = { ...PANGUARD_MCP_ENTRY };
69
+ config['mcpServers'] = servers;
70
+ writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
71
+ }
72
+ /**
73
+ * Inject Panguard MCP config for Claude Code.
74
+ * Claude Code uses: { "mcpServers": { "panguard": { "command": "...", "args": [...] } } }
75
+ * in ~/.claude/settings.local.json
76
+ */
77
+ function injectClaudeCode(configPath) {
78
+ const config = readJsonSafe(configPath);
79
+ const servers = config['mcpServers'] ?? {};
80
+ servers['panguard'] = { ...PANGUARD_MCP_ENTRY };
81
+ config['mcpServers'] = servers;
82
+ writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
83
+ }
84
+ /**
85
+ * Inject Panguard MCP config for Cursor.
86
+ * Cursor uses: { "mcpServers": { "panguard": { "command": "...", "args": [...] } } }
87
+ * in ~/.cursor/mcp.json
88
+ */
89
+ function injectCursor(configPath) {
90
+ const config = readJsonSafe(configPath);
91
+ const servers = config['mcpServers'] ?? {};
92
+ servers['panguard'] = { ...PANGUARD_MCP_ENTRY };
93
+ config['mcpServers'] = servers;
94
+ writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
95
+ }
96
+ /**
97
+ * Inject Panguard MCP config for Codex/Workbuddy/NemoClaw.
98
+ * Generic MCP JSON format: { "mcpServers": { "panguard": { ... } } }
99
+ */
100
+ function injectGenericMCP(configPath) {
101
+ const config = readJsonSafe(configPath);
102
+ const servers = config['mcpServers'] ?? {};
103
+ servers['panguard'] = { ...PANGUARD_MCP_ENTRY };
104
+ config['mcpServers'] = servers;
105
+ writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
106
+ }
107
+ /**
108
+ * Inject Panguard as an OpenClaw native skill.
109
+ * OpenClaw uses its own skill system (not MCP), so we copy SKILL.md
110
+ * to ~/.openclaw/skills/panguard/.
111
+ */
112
+ function injectOpenClawSkill(skillDir) {
113
+ mkdirSync(skillDir, { recursive: true });
114
+ // Resolve the bundled SKILL.md from this package
115
+ const thisDir = dirname(fileURLToPath(import.meta.url));
116
+ const bundledSkill = join(thisDir, '..', '..', 'openclaw-skill', 'SKILL.md');
117
+ if (existsSync(bundledSkill)) {
118
+ copyFileSync(bundledSkill, join(skillDir, 'SKILL.md'));
119
+ }
120
+ else {
121
+ // Fallback: write a minimal SKILL.md inline
122
+ const skillContent = [
123
+ '---',
124
+ 'name: panguard',
125
+ 'description: AI agent security platform -- audit skills, scan threats, run 24/7 protection',
126
+ 'homepage: https://panguard.ai',
127
+ 'license: MIT',
128
+ 'metadata: { "openclaw": { "requires": { "bins": ["npx"] }, "install": [{ "id": "node", "kind": "node", "package": "@panguard-ai/panguard", "bins": ["panguard"], "label": "Install Panguard AI" }] } }',
129
+ '---',
130
+ '',
131
+ '# Panguard AI',
132
+ '',
133
+ 'Security platform for AI agents with 9,700+ detection rules.',
134
+ '',
135
+ '## Commands',
136
+ '- `panguard audit skill .` -- Audit skills for threats',
137
+ '- `panguard scan` -- Security scan',
138
+ '- `panguard guard start` -- Start real-time protection',
139
+ '- `panguard status` -- Show status dashboard',
140
+ '',
141
+ ].join('\n');
142
+ writeFileSync(join(skillDir, 'SKILL.md'), skillContent, 'utf-8');
143
+ }
144
+ }
145
+ /**
146
+ * Inject Panguard MCP config into a specific platform.
147
+ * 將 Panguard MCP 設定注入特定平台。
148
+ *
149
+ * @param platformId - Target platform / 目標平台
150
+ * @returns Injection result with success status and paths.
151
+ */
152
+ export function injectMCPConfig(platformId) {
153
+ const configPath = getConfigPath(platformId);
154
+ const result = { platformId, success: false, configPath };
155
+ try {
156
+ ensureDir(configPath);
157
+ result.backupPath = backupFile(configPath);
158
+ switch (platformId) {
159
+ case 'claude-desktop':
160
+ injectClaudeDesktop(configPath);
161
+ break;
162
+ case 'claude-code':
163
+ injectClaudeCode(configPath);
164
+ break;
165
+ case 'cursor':
166
+ injectCursor(configPath);
167
+ break;
168
+ case 'openclaw':
169
+ injectOpenClawSkill(configPath);
170
+ break;
171
+ case 'codex':
172
+ case 'workbuddy':
173
+ case 'nemoclaw':
174
+ injectGenericMCP(configPath);
175
+ break;
176
+ }
177
+ // Verify the write succeeded
178
+ if (platformId === 'openclaw') {
179
+ // OpenClaw uses SKILL.md, not JSON
180
+ if (existsSync(join(configPath, 'SKILL.md'))) {
181
+ result.success = true;
182
+ logger.info(`Installed Panguard skill for OpenClaw at ${configPath}`);
183
+ }
184
+ else {
185
+ result.error = 'Verification failed: SKILL.md not found after write';
186
+ logger.error(result.error);
187
+ }
188
+ }
189
+ else {
190
+ const verify = readJsonSafe(configPath);
191
+ const servers = verify['mcpServers'];
192
+ if (servers && servers['panguard']) {
193
+ result.success = true;
194
+ logger.info(`Injected Panguard MCP config into ${platformId} at ${configPath}`);
195
+ }
196
+ else {
197
+ result.error = 'Verification failed: panguard entry not found after write';
198
+ logger.error(result.error);
199
+ }
200
+ }
201
+ }
202
+ catch (err) {
203
+ result.error = err instanceof Error ? err.message : String(err);
204
+ logger.error(`Failed to inject ${platformId}: ${result.error}`);
205
+ }
206
+ return result;
207
+ }
208
+ /**
209
+ * Remove Panguard MCP config from a specific platform.
210
+ * 從特定平台移除 Panguard MCP 設定。
211
+ */
212
+ export function removeMCPConfig(platformId) {
213
+ const configPath = getConfigPath(platformId);
214
+ const result = { platformId, success: false, configPath };
215
+ try {
216
+ if (platformId === 'openclaw') {
217
+ // Remove OpenClaw skill directory
218
+ const skillMd = join(configPath, 'SKILL.md');
219
+ if (existsSync(skillMd)) {
220
+ rmSync(configPath, { recursive: true, force: true });
221
+ logger.info(`Removed Panguard skill from OpenClaw`);
222
+ }
223
+ result.success = true;
224
+ return result;
225
+ }
226
+ if (!existsSync(configPath)) {
227
+ result.success = true;
228
+ return result;
229
+ }
230
+ result.backupPath = backupFile(configPath);
231
+ const config = readJsonSafe(configPath);
232
+ const servers = config['mcpServers'];
233
+ if (servers) {
234
+ delete servers['panguard'];
235
+ config['mcpServers'] = servers;
236
+ }
237
+ writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
238
+ result.success = true;
239
+ logger.info(`Removed Panguard MCP config from ${platformId}`);
240
+ }
241
+ catch (err) {
242
+ result.error = err instanceof Error ? err.message : String(err);
243
+ logger.error(`Failed to remove from ${platformId}: ${result.error}`);
244
+ }
245
+ return result;
246
+ }
247
+ /**
248
+ * Inject Panguard MCP config into all detected platforms.
249
+ * 將 Panguard MCP 設定注入所有偵測到的平台。
250
+ */
251
+ export async function injectAll(platformIds) {
252
+ return platformIds.map((id) => injectMCPConfig(id));
253
+ }
254
+ /**
255
+ * Get the one-liner install command for display.
256
+ * 取得用於顯示的一行安裝指令。
257
+ */
258
+ export function getInstallCommand() {
259
+ return 'npx panguard setup';
260
+ }
261
+ //# sourceMappingURL=mcp-injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-injector.js","sourceRoot":"","sources":["../../src/config/mcp-injector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Platform Detector - Detect installed AI agent runtimes
3
+ * 平台偵測器 - 偵測已安裝的 AI Agent 執行環境
4
+ *
5
+ * Detects Claude Code, Cursor, OpenClaw, Codex, Workbuddy, and NemoClaw.
6
+ * 偵測 Claude Code、Cursor、OpenClaw、Codex、Workbuddy 和 NemoClaw。
7
+ *
8
+ * @module @panguard-ai/panguard-mcp/config/platform-detector
9
+ */
10
+ export type PlatformId = 'claude-code' | 'claude-desktop' | 'cursor' | 'openclaw' | 'codex' | 'workbuddy' | 'nemoclaw';
11
+ export interface DetectedPlatform {
12
+ id: PlatformId;
13
+ name: string;
14
+ configPath: string;
15
+ detected: boolean;
16
+ alreadyConfigured: boolean;
17
+ }
18
+ /**
19
+ * Detect all supported AI agent platforms.
20
+ * 偵測所有支援的 AI Agent 平台。
21
+ *
22
+ * @returns Array of detected platforms with their config paths and status.
23
+ */
24
+ export declare function detectPlatforms(): Promise<DetectedPlatform[]>;
25
+ /**
26
+ * Get the MCP config path for a specific platform.
27
+ * 取得特定平台的 MCP 設定路徑。
28
+ */
29
+ export declare function getConfigPath(platformId: PlatformId): string;
30
+ //# sourceMappingURL=platform-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-detector.d.ts","sourceRoot":"","sources":["../../src/config/platform-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,MAAM,MAAM,UAAU,GAClB,aAAa,GACb,gBAAgB,GAChB,QAAQ,GACR,UAAU,GACV,OAAO,GACP,WAAW,GACX,UAAU,CAAC;AAEf,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,UAAU,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAiFD;;;;;GAKG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAsFnE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAU5D"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Platform Detector - Detect installed AI agent runtimes
3
+ * 平台偵測器 - 偵測已安裝的 AI Agent 執行環境
4
+ *
5
+ * Detects Claude Code, Cursor, OpenClaw, Codex, Workbuddy, and NemoClaw.
6
+ * 偵測 Claude Code、Cursor、OpenClaw、Codex、Workbuddy 和 NemoClaw。
7
+ *
8
+ * @module @panguard-ai/panguard-mcp/config/platform-detector
9
+ */
10
+ import { existsSync, readFileSync } from 'node:fs';
11
+ import { join } from 'node:path';
12
+ import { homedir, platform } from 'node:os';
13
+ import { execFile } from 'node:child_process';
14
+ import { createLogger } from '@panguard-ai/core';
15
+ const logger = createLogger('panguard-mcp:platform-detector');
16
+ /** Check if a command exists on PATH. */
17
+ function commandExists(cmd) {
18
+ if (!/^[a-zA-Z0-9_.-]+$/.test(cmd))
19
+ return Promise.resolve(false);
20
+ return new Promise((resolve) => {
21
+ const bin = platform() === 'win32' ? 'where' : 'which';
22
+ execFile(bin, [cmd], (err) => resolve(!err));
23
+ });
24
+ }
25
+ /** Check if a JSON config file has a panguard MCP server entry. */
26
+ function hasPanguardMCPEntry(filePath) {
27
+ if (!existsSync(filePath))
28
+ return false;
29
+ try {
30
+ const parsed = JSON.parse(readFileSync(filePath, 'utf-8'));
31
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
32
+ const servers = parsed['mcpServers'];
33
+ if (servers && typeof servers === 'object' && !Array.isArray(servers)) {
34
+ return 'panguard' in servers;
35
+ }
36
+ }
37
+ return false;
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ }
43
+ /** Check if OpenClaw has the panguard skill installed. */
44
+ function hasOpenClawSkill() {
45
+ return existsSync(getOpenClawSkillPath());
46
+ }
47
+ /** Get the MCP config path for Claude Desktop based on OS. */
48
+ function getClaudeDesktopConfigPath() {
49
+ const home = homedir();
50
+ switch (platform()) {
51
+ case 'darwin':
52
+ return join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
53
+ case 'win32':
54
+ return join(process.env['APPDATA'] ?? join(home, 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json');
55
+ default:
56
+ return join(home, '.config', 'claude', 'claude_desktop_config.json');
57
+ }
58
+ }
59
+ /** Get the MCP settings path for Claude Code. */
60
+ function getClaudeCodeConfigPath() {
61
+ return join(homedir(), '.claude', 'settings.local.json');
62
+ }
63
+ /** Get the MCP config path for Cursor. */
64
+ function getCursorConfigPath() {
65
+ return join(homedir(), '.cursor', 'mcp.json');
66
+ }
67
+ /** Get the OpenClaw skill installation path for Panguard. */
68
+ function getOpenClawSkillPath() {
69
+ return join(homedir(), '.openclaw', 'skills', 'panguard', 'SKILL.md');
70
+ }
71
+ /** Get the OpenClaw skills directory for Panguard. */
72
+ function getOpenClawSkillDir() {
73
+ return join(homedir(), '.openclaw', 'skills', 'panguard');
74
+ }
75
+ /** Get the MCP config path for Codex. */
76
+ function getCodexConfigPath() {
77
+ return join(homedir(), '.codex', 'mcp.json');
78
+ }
79
+ /** Get the MCP config path for Workbuddy. */
80
+ function getWorkbuddyConfigPath() {
81
+ return join(homedir(), '.workbuddy', '.mcp.json');
82
+ }
83
+ /** Get the MCP config path for NemoClaw. */
84
+ function getNemoClawConfigPath() {
85
+ return join(homedir(), '.nemoclaw', 'mcp.json');
86
+ }
87
+ /**
88
+ * Detect all supported AI agent platforms.
89
+ * 偵測所有支援的 AI Agent 平台。
90
+ *
91
+ * @returns Array of detected platforms with their config paths and status.
92
+ */
93
+ export async function detectPlatforms() {
94
+ const platforms = [];
95
+ // Claude Code
96
+ const claudeCodePath = getClaudeCodeConfigPath();
97
+ const claudeCodeDetected = await commandExists('claude') || existsSync(join(homedir(), '.claude'));
98
+ platforms.push({
99
+ id: 'claude-code',
100
+ name: 'Claude Code',
101
+ configPath: claudeCodePath,
102
+ detected: claudeCodeDetected,
103
+ alreadyConfigured: hasPanguardMCPEntry(claudeCodePath),
104
+ });
105
+ // Claude Desktop
106
+ const claudeDesktopPath = getClaudeDesktopConfigPath();
107
+ const claudeDesktopDetected = existsSync(claudeDesktopPath) ||
108
+ (platform() === 'darwin' && existsSync('/Applications/Claude.app'));
109
+ platforms.push({
110
+ id: 'claude-desktop',
111
+ name: 'Claude Desktop',
112
+ configPath: claudeDesktopPath,
113
+ detected: claudeDesktopDetected,
114
+ alreadyConfigured: hasPanguardMCPEntry(claudeDesktopPath),
115
+ });
116
+ // Cursor
117
+ const cursorPath = getCursorConfigPath();
118
+ const cursorDetected = await commandExists('cursor') ||
119
+ existsSync(join(homedir(), '.cursor')) ||
120
+ (platform() === 'darwin' && existsSync('/Applications/Cursor.app'));
121
+ platforms.push({
122
+ id: 'cursor',
123
+ name: 'Cursor',
124
+ configPath: cursorPath,
125
+ detected: cursorDetected,
126
+ alreadyConfigured: hasPanguardMCPEntry(cursorPath),
127
+ });
128
+ // OpenClaw (uses native skill system, not MCP)
129
+ const openclawSkillDir = getOpenClawSkillDir();
130
+ const openclawDetected = await commandExists('openclaw') || existsSync(join(homedir(), '.openclaw'));
131
+ platforms.push({
132
+ id: 'openclaw',
133
+ name: 'OpenClaw',
134
+ configPath: openclawSkillDir,
135
+ detected: openclawDetected,
136
+ alreadyConfigured: hasOpenClawSkill(),
137
+ });
138
+ // Codex
139
+ const codexPath = getCodexConfigPath();
140
+ const codexDetected = await commandExists('codex') || existsSync(join(homedir(), '.codex'));
141
+ platforms.push({
142
+ id: 'codex',
143
+ name: 'Codex CLI',
144
+ configPath: codexPath,
145
+ detected: codexDetected,
146
+ alreadyConfigured: hasPanguardMCPEntry(codexPath),
147
+ });
148
+ // Workbuddy
149
+ const workbuddyPath = getWorkbuddyConfigPath();
150
+ const workbuddyDetected = await commandExists('workbuddy') || existsSync(join(homedir(), '.workbuddy'));
151
+ platforms.push({
152
+ id: 'workbuddy',
153
+ name: 'Workbuddy',
154
+ configPath: workbuddyPath,
155
+ detected: workbuddyDetected,
156
+ alreadyConfigured: hasPanguardMCPEntry(workbuddyPath),
157
+ });
158
+ // NemoClaw
159
+ const nemoclawPath = getNemoClawConfigPath();
160
+ const nemoclawDetected = await commandExists('nemoclaw') || existsSync(join(homedir(), '.nemoclaw'));
161
+ platforms.push({
162
+ id: 'nemoclaw',
163
+ name: 'NemoClaw',
164
+ configPath: nemoclawPath,
165
+ detected: nemoclawDetected,
166
+ alreadyConfigured: hasPanguardMCPEntry(nemoclawPath),
167
+ });
168
+ const detected = platforms.filter((p) => p.detected);
169
+ logger.info(`Detected ${detected.length} platform(s): ${detected.map((p) => p.name).join(', ') || 'none'}`);
170
+ return platforms;
171
+ }
172
+ /**
173
+ * Get the MCP config path for a specific platform.
174
+ * 取得特定平台的 MCP 設定路徑。
175
+ */
176
+ export function getConfigPath(platformId) {
177
+ switch (platformId) {
178
+ case 'claude-code': return getClaudeCodeConfigPath();
179
+ case 'claude-desktop': return getClaudeDesktopConfigPath();
180
+ case 'cursor': return getCursorConfigPath();
181
+ case 'openclaw': return getOpenClawSkillDir();
182
+ case 'codex': return getCodexConfigPath();
183
+ case 'workbuddy': return getWorkbuddyConfigPath();
184
+ case 'nemoclaw': return getNemoClawConfigPath();
185
+ }
186
+ }
187
+ //# sourceMappingURL=platform-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-detector.js","sourceRoot":"","sources":["../../src/config/platform-detector.ts"],"names":[],"mappings":"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"}
@@ -12,17 +12,22 @@
12
12
  * Execute panguard_guard_start — start the real-time threat monitoring daemon.
13
13
  * 執行 panguard_guard_start — 啟動即時威脅監控常駐程式。
14
14
  *
15
- * NOTE: The MCP server does not directly spawn daemon processes to avoid
16
- * interfering with the stdio transport. Instead it validates the data directory
17
- * and returns instructions for the user/agent to run panguard-guard CLI.
18
- * 注意:MCP 伺服器不直接生成常駐進程以避免干擾 stdio 傳輸。
19
- * 改為驗證資料目錄並返回讓用戶/代理執行 panguard-guard CLI 的指示。
15
+ * Spawns the guard daemon as a detached background process with stdio
16
+ * redirected to a log file, so it does not interfere with MCP stdio transport.
17
+ * 將守護常駐程式作為分離的背景進程啟動,stdio 重導向到日誌檔案。
20
18
  */
21
19
  export declare function executeGuardStart(args: Record<string, unknown>): Promise<{
22
20
  content: {
23
21
  type: "text";
24
22
  text: string;
25
23
  }[];
24
+ isError?: undefined;
25
+ } | {
26
+ content: {
27
+ type: "text";
28
+ text: string;
29
+ }[];
30
+ isError: boolean;
26
31
  }>;
27
32
  /**
28
33
  * Execute panguard_guard_stop — stop the real-time threat monitoring daemon.
@@ -1 +1 @@
1
- {"version":3,"file":"guard-tools.d.ts","sourceRoot":"","sources":["../../src/tools/guard-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GA8BpE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GA6CnE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GAiEhE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GAiDhE"}
1
+ {"version":3,"file":"guard-tools.d.ts","sourceRoot":"","sources":["../../src/tools/guard-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;GA+LpE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GA6CnE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GAiEhE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GAiDhE"}
@@ -8,7 +8,10 @@
8
8
  *
9
9
  * @module @panguard-ai/panguard-mcp/tools/guard-tools
10
10
  */
11
- import { promises as fs } from 'node:fs';
11
+ import { promises as fs, existsSync, readFileSync, openSync, closeSync } from 'node:fs';
12
+ import { spawn } from 'node:child_process';
13
+ import { createRequire } from 'node:module';
14
+ import { fileURLToPath } from 'node:url';
12
15
  import os from 'node:os';
13
16
  import path from 'node:path';
14
17
  /**
@@ -22,11 +25,9 @@ function resolveDataDir(args) {
22
25
  * Execute panguard_guard_start — start the real-time threat monitoring daemon.
23
26
  * 執行 panguard_guard_start — 啟動即時威脅監控常駐程式。
24
27
  *
25
- * NOTE: The MCP server does not directly spawn daemon processes to avoid
26
- * interfering with the stdio transport. Instead it validates the data directory
27
- * and returns instructions for the user/agent to run panguard-guard CLI.
28
- * 注意:MCP 伺服器不直接生成常駐進程以避免干擾 stdio 傳輸。
29
- * 改為驗證資料目錄並返回讓用戶/代理執行 panguard-guard CLI 的指示。
28
+ * Spawns the guard daemon as a detached background process with stdio
29
+ * redirected to a log file, so it does not interfere with MCP stdio transport.
30
+ * 將守護常駐程式作為分離的背景進程啟動,stdio 重導向到日誌檔案。
30
31
  */
31
32
  export async function executeGuardStart(args) {
32
33
  const dataDir = resolveDataDir(args);
@@ -37,21 +38,166 @@ export async function executeGuardStart(args) {
37
38
  catch {
38
39
  // Directory may already exist
39
40
  }
40
- return {
41
- content: [
42
- {
43
- type: 'text',
44
- text: JSON.stringify({
45
- status: 'ready',
46
- dataDir,
47
- mode,
48
- message: 'Guard engine is ready to start. Run the following command in a terminal to start real-time monitoring:',
49
- command: `panguard-guard start --mode ${mode} --data-dir "${dataDir}"`,
50
- note: 'Use panguard_status to check current guard state after starting.',
51
- }, null, 2),
52
- },
53
- ],
54
- };
41
+ // Check if guard is already running
42
+ const pidFile = path.join(dataDir, 'panguard-guard.pid');
43
+ try {
44
+ const pidContent = await fs.readFile(pidFile, 'utf-8');
45
+ const existingPid = parseInt(pidContent.trim(), 10);
46
+ if (!isNaN(existingPid)) {
47
+ try {
48
+ process.kill(existingPid, 0);
49
+ // Process exists guard is already running
50
+ return {
51
+ content: [
52
+ {
53
+ type: 'text',
54
+ text: JSON.stringify({
55
+ status: 'already_running',
56
+ pid: existingPid,
57
+ dataDir,
58
+ mode,
59
+ message: `Guard engine is already running (PID: ${existingPid}).`,
60
+ }, null, 2),
61
+ },
62
+ ],
63
+ };
64
+ }
65
+ catch {
66
+ // Process not found — stale PID file, continue to start
67
+ await fs.unlink(pidFile).catch(() => undefined);
68
+ }
69
+ }
70
+ }
71
+ catch {
72
+ // No PID file — proceed to start
73
+ }
74
+ // Resolve the panguard-guard CLI script path
75
+ let guardCliScript;
76
+ try {
77
+ const _require = createRequire(import.meta.url);
78
+ const guardMainPath = _require.resolve('@panguard-ai/panguard-guard');
79
+ guardCliScript = path.join(path.dirname(guardMainPath), 'cli', 'index.js');
80
+ }
81
+ catch {
82
+ // Fallback: try resolving via import.meta.resolve
83
+ try {
84
+ const guardMainUrl = import.meta.resolve('@panguard-ai/panguard-guard');
85
+ guardCliScript = path.join(fileURLToPath(guardMainUrl), '..', 'cli', 'index.js');
86
+ }
87
+ catch {
88
+ return {
89
+ content: [
90
+ {
91
+ type: 'text',
92
+ text: JSON.stringify({
93
+ status: 'error',
94
+ message: 'Could not resolve @panguard-ai/panguard-guard package. Is it installed?',
95
+ }, null, 2),
96
+ },
97
+ ],
98
+ isError: true,
99
+ };
100
+ }
101
+ }
102
+ // Spawn guard as a detached background process
103
+ const logPath = path.join(dataDir, 'guard.log');
104
+ let logFd;
105
+ try {
106
+ logFd = openSync(logPath, 'a');
107
+ }
108
+ catch (err) {
109
+ return {
110
+ content: [
111
+ {
112
+ type: 'text',
113
+ text: JSON.stringify({
114
+ status: 'error',
115
+ message: `Failed to open log file: ${err instanceof Error ? err.message : String(err)}`,
116
+ }, null, 2),
117
+ },
118
+ ],
119
+ isError: true,
120
+ };
121
+ }
122
+ try {
123
+ const child = spawn(process.execPath, [guardCliScript, 'start'], {
124
+ detached: true,
125
+ stdio: ['ignore', logFd, logFd],
126
+ env: { ...process.env },
127
+ });
128
+ child.unref();
129
+ closeSync(logFd);
130
+ // Wait for PID file to confirm startup (up to 5 seconds)
131
+ let started = false;
132
+ let newPid = null;
133
+ const deadline = Date.now() + 5000;
134
+ while (Date.now() < deadline) {
135
+ if (existsSync(pidFile)) {
136
+ try {
137
+ const content = readFileSync(pidFile, 'utf-8').trim();
138
+ const parsed = parseInt(content, 10);
139
+ if (!isNaN(parsed)) {
140
+ process.kill(parsed, 0);
141
+ started = true;
142
+ newPid = parsed;
143
+ break;
144
+ }
145
+ }
146
+ catch {
147
+ // Not ready yet
148
+ }
149
+ }
150
+ await new Promise((r) => setTimeout(r, 300));
151
+ }
152
+ if (started) {
153
+ return {
154
+ content: [
155
+ {
156
+ type: 'text',
157
+ text: JSON.stringify({
158
+ status: 'started',
159
+ pid: newPid,
160
+ dataDir,
161
+ mode,
162
+ logFile: logPath,
163
+ message: `Guard engine started successfully (PID: ${newPid}).`,
164
+ }, null, 2),
165
+ },
166
+ ],
167
+ };
168
+ }
169
+ else {
170
+ return {
171
+ content: [
172
+ {
173
+ type: 'text',
174
+ text: JSON.stringify({
175
+ status: 'timeout',
176
+ dataDir,
177
+ mode,
178
+ logFile: logPath,
179
+ message: 'Guard engine was spawned but did not confirm startup within 5 seconds. Check the log file for details.',
180
+ }, null, 2),
181
+ },
182
+ ],
183
+ };
184
+ }
185
+ }
186
+ catch (err) {
187
+ closeSync(logFd);
188
+ return {
189
+ content: [
190
+ {
191
+ type: 'text',
192
+ text: JSON.stringify({
193
+ status: 'error',
194
+ message: `Failed to spawn guard process: ${err instanceof Error ? err.message : String(err)}`,
195
+ }, null, 2),
196
+ },
197
+ ],
198
+ isError: true,
199
+ };
200
+ }
55
201
  }
56
202
  /**
57
203
  * Execute panguard_guard_stop — stop the real-time threat monitoring daemon.
@@ -1 +1 @@
1
- {"version":3,"file":"guard-tools.js","sourceRoot":"","sources":["../../src/tools/guard-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;GAGG;AACH,SAAS,cAAc,CAAC,IAA6B;IACnD,OAAQ,IAAI,CAAC,SAAS,CAAY,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACnF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAA6B;IACnE,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,IAAI,GAAI,IAAI,CAAC,MAAM,CAAY,IAAI,UAAU,CAAC;IAEpD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,MAAM,EAAE,OAAO;oBACf,OAAO;oBACP,IAAI;oBACJ,OAAO,EACL,wGAAwG;oBAC1G,OAAO,EAAE,+BAA+B,IAAI,gBAAgB,OAAO,GAAG;oBACtE,IAAI,EAAE,kEAAkE;iBACzE,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAA6B;IAClE,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEhD,IAAI,GAAG,GAAkB,IAAI,CAAC;IAC9B,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACvD,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAEtC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAC7B,OAAO,GAAG,IAAI,CAAC;gBACf,wBAAwB;gBACxB,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAClD,CAAC;YAAC,MAAM,CAAC;gBACP,gDAAgD;gBAChD,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBAChD,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,oBAAoB;IACtB,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa;oBAC3C,GAAG;oBACH,OAAO,EAAE,OAAO;wBACd,CAAC,CAAC,sBAAsB,GAAG,0BAA0B;wBACrD,CAAC,CAAC,mDAAmD;iBACxD,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAA6B;IAC/D,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEhD,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,GAAG,GAAkB,IAAI,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACvD,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAChB,+DAA+D;YAC/D,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACrB,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,SAAS,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,2BAA2B;IAC3B,IAAI,MAAM,GAA4B,EAAE,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QACrD,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC7D,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAA4B,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,qBAAqB;IACvB,CAAC;IAED,qDAAqD;IACrD,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACvD,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,KAAK,EAAE;wBACL,OAAO,EAAE,SAAS;wBAClB,GAAG;wBACH,OAAO;wBACP,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS;wBACjC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI;qBAC7B;oBACD,MAAM,EAAE;wBACN,YAAY,EAAE,UAAU;qBACzB;oBACD,OAAO,EAAE,SAAS;wBAChB,CAAC,CAAC,mCAAmC,GAAG,WAAW,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,IAAI;wBAClF,CAAC,CAAC,sEAAsE;iBAC3E,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAA6B;IAC/D,MAAM,KAAK,GAAI,IAAI,CAAC,OAAO,CAAY,IAAI,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAI,IAAI,CAAC,UAAU,CAAY,IAAI,KAAK,CAAC;IACvD,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAErC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACtD,MAAM,MAAM,GAAc,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEzD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;gBAC1D,IAAI,QAAQ,KAAK,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,QAAQ,EAAE,CAAC;oBACzD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,6BAA6B;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kDAAkD;IACpD,CAAC;IAED,wCAAwC;IACxC,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAEvD,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,YAAY,EAAE,YAAY,CAAC,MAAM;oBACjC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;oBAC3B,MAAM,EAAE,YAAY;oBACpB,OAAO,EACL,YAAY,CAAC,MAAM,KAAK,CAAC;wBACvB,CAAC,CAAC,yCAAyC;wBAC3C,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM,4BAA4B;iBACzD,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"guard-tools.js","sourceRoot":"","sources":["../../src/tools/guard-tools.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"manage-tools.d.ts","sourceRoot":"","sources":["../../src/tools/manage-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAuBH;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;GAmDjE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;GAmCxE;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GAmD9D;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GAoGhE"}
1
+ {"version":3,"file":"manage-tools.d.ts","sourceRoot":"","sources":["../../src/tools/manage-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAmDH;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;GAmDjE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;GAqCxE;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GAmD9D;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GAoGhE"}
@@ -18,12 +18,38 @@ const logger = createLogger('panguard-mcp:manage');
18
18
  const IPV4_REGEX = /^(\d{1,3}\.){3}\d{1,3}$/;
19
19
  /** IPv6 validation regex — accepts compressed and full forms */
20
20
  const IPV6_REGEX = /^[0-9a-fA-F:]+$/;
21
+ /** Directories that are safe for Panguard to write into. */
22
+ const SAFE_BASES = [
23
+ os.homedir(),
24
+ os.tmpdir(),
25
+ process.cwd(),
26
+ // macOS: /tmp is a symlink to /private/tmp, distinct from os.tmpdir()
27
+ '/tmp',
28
+ '/private/tmp',
29
+ ];
30
+ /**
31
+ * Assert that a resolved path stays within an allowed base directory.
32
+ * Prevents path traversal attacks from MCP tool arguments.
33
+ */
34
+ function assertSafePath(resolved) {
35
+ const normalResolved = path.resolve(resolved);
36
+ const isAllowed = SAFE_BASES.some((base) => {
37
+ const normalBase = path.resolve(base);
38
+ return normalResolved === normalBase || normalResolved.startsWith(normalBase + path.sep);
39
+ });
40
+ if (!isAllowed) {
41
+ throw new Error(`Path traversal rejected: ${resolved} is outside allowed directories`);
42
+ }
43
+ }
21
44
  /**
22
45
  * Resolve the guard data directory from args or default.
23
46
  * 從參數或預設值解析守護資料目錄。
24
47
  */
25
48
  function resolveDataDir(args) {
26
- return args['dataDir'] ?? path.join(os.homedir(), '.panguard-guard');
49
+ const dataDir = args['dataDir'] ?? path.join(os.homedir(), '.panguard-guard');
50
+ const resolved = path.resolve(dataDir);
51
+ assertSafePath(resolved);
52
+ return resolved;
27
53
  }
28
54
  /**
29
55
  * Execute panguard_block_ip — manually block an IP address.
@@ -82,8 +108,10 @@ export async function executeGenerateReport(args) {
82
108
  const lang = (args['lang'] ?? 'en');
83
109
  const depth = (args['depth'] ?? 'full');
84
110
  try {
111
+ const resolvedOutput = path.resolve(output);
112
+ assertSafePath(resolvedOutput);
85
113
  const result = await runScan({ depth, lang });
86
- await generatePdfReport(result, output, lang);
114
+ await generatePdfReport(result, resolvedOutput, lang);
87
115
  return {
88
116
  content: [
89
117
  {
@@ -1 +1 @@
1
- {"version":3,"file":"manage-tools.js","sourceRoot":"","sources":["../../src/tools/manage-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manage-tools.js","sourceRoot":"","sources":["../../src/tools/manage-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: panguard
3
+ description: AI agent security platform — audit skills, scan for threats, and run 24/7 protection with 9,700+ detection rules
4
+ homepage: https://panguard.ai
5
+ license: MIT
6
+ metadata: { "openclaw": { "requires": { "bins": ["npx"] }, "install": [{ "id": "node", "kind": "node", "package": "@panguard-ai/panguard", "bins": ["panguard"], "label": "Install Panguard AI via npm" }] } }
7
+ ---
8
+
9
+ # Panguard AI — Security for AI Agents
10
+
11
+ Panguard protects AI agents from prompt injection, tool poisoning, data exfiltration, and 9 other threat categories using 9,700+ detection rules (Sigma + YARA + ATR).
12
+
13
+ ## Available Commands
14
+
15
+ ### Audit installed skills for security threats
16
+ ```bash
17
+ panguard audit skill .
18
+ ```
19
+ Scans all SKILL.md files in the current directory and subdirectories. Reports risk level, flagged patterns, and recommendations.
20
+
21
+ ### Quick security scan
22
+ ```bash
23
+ panguard scan
24
+ ```
25
+ Runs a fast security health check on the current system.
26
+
27
+ ### Full security scan with code analysis
28
+ ```bash
29
+ panguard scan --depth full
30
+ ```
31
+ Deep scan including SAST code analysis, dependency audit, and threat detection.
32
+
33
+ ### Start real-time protection (Guard)
34
+ ```bash
35
+ panguard guard start
36
+ ```
37
+ Starts the Guard engine as a background daemon. Monitors all agent activity in real-time using ATR (Agent Threat Rules), Sigma, and YARA rules.
38
+
39
+ ### Check Guard status
40
+ ```bash
41
+ panguard guard status
42
+ ```
43
+ Shows whether Guard is running, rule counts, and recent alerts.
44
+
45
+ ### Stop Guard
46
+ ```bash
47
+ panguard guard stop
48
+ ```
49
+
50
+ ### Show system status dashboard
51
+ ```bash
52
+ panguard status
53
+ ```
54
+ Displays a comprehensive status panel: Guard state, rule counts, threat stats, and connected platforms.
55
+
56
+ ### Show recent security alerts
57
+ ```bash
58
+ panguard guard alerts
59
+ ```
60
+
61
+ ## Workflow
62
+
63
+ When the user asks about security, skill auditing, or threat protection:
64
+
65
+ 1. If they want to **audit skills**: Run `panguard audit skill <path>` on the target directory
66
+ 2. If they want a **security scan**: Run `panguard scan` (add `--depth full` for thorough analysis)
67
+ 3. If they want **real-time protection**: Run `panguard guard start`
68
+ 4. If they want **status**: Run `panguard status`
69
+
70
+ ## Setup
71
+
72
+ If panguard is not installed, install it:
73
+ ```bash
74
+ npm install -g @panguard-ai/panguard
75
+ ```
76
+
77
+ Then configure for all AI agent platforms:
78
+ ```bash
79
+ panguard setup
80
+ ```
package/package.json CHANGED
@@ -1,27 +1,36 @@
1
1
  {
2
2
  "name": "@panguard-ai/panguard-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
+ "license": "MIT",
4
5
  "type": "module",
5
6
  "description": "MCP server for Panguard AI — control security from Claude/Cursor / 透過 Claude/Cursor 控制 Panguard 的 MCP 伺服器",
6
7
  "main": "./dist/index.js",
7
8
  "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": "./dist/index.js",
11
+ "./config": "./dist/config/index.js"
12
+ },
8
13
  "bin": {
9
14
  "panguard-mcp": "./dist/cli/index.js"
10
15
  },
11
16
  "publishConfig": {
12
17
  "access": "public"
13
18
  },
19
+ "engines": {
20
+ "node": ">=18.0.0"
21
+ },
14
22
  "files": [
15
23
  "dist",
24
+ "openclaw-skill",
16
25
  "package.json",
17
26
  "README.md"
18
27
  ],
19
28
  "dependencies": {
20
29
  "@modelcontextprotocol/sdk": "^1.0.0",
21
- "@panguard-ai/core": "0.3.1",
22
- "@panguard-ai/panguard-scan": "0.2.0",
23
- "@panguard-ai/panguard-skill-auditor": "0.1.0",
24
- "@panguard-ai/panguard-guard": "0.2.0"
30
+ "@panguard-ai/core": "0.3.2",
31
+ "@panguard-ai/panguard-scan": "0.2.1",
32
+ "@panguard-ai/panguard-skill-auditor": "0.1.2",
33
+ "@panguard-ai/panguard-guard": "0.2.1"
25
34
  },
26
35
  "devDependencies": {
27
36
  "@types/node": "^22.14.0",