@securityreviewai/securityreview-kit 0.1.33 → 0.1.35

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.
package/README.md CHANGED
@@ -29,7 +29,7 @@ npx @securityreviewai/securityreview-kit init --switch-project
29
29
  |---|---|---|---|
30
30
  | Cursor | `cursor` | `.cursor/mcp.json` | `.cursor/rules/srai-security-review.mdc`, `.cursor/rules/ctm_sync_rule.mdc`, `.cursor/commands/ctm_sync.md`, `.cursor/agents/ctm_sync.md`, `.cursor/commands/create-ide-workflow.md`, `.cursor/commands/srai-profile.md`, `.cursor/skills/threat-modelling/SKILL.md` |
31
31
  | Claude Code | `claude` | `.claude/settings.json` | `CLAUDE.md` |
32
- | VS Code Copilot | `vscode` | `.vscode/mcp.json` | `.github/copilot-instructions.md` |
32
+ | VS Code Copilot | `vscode` | `.vscode/mcp.json` | `.github/copilot-instructions.md`, `.github/skills/guardrails-profiler/SKILL.md`, `.github/skills/guardrails-selection/SKILL.md` |
33
33
  | Windsurf | `windsurf` | `.windsurf/mcp_config.json` | `.windsurf/rules/srai-security-review.md` |
34
34
  | Codex | `codex` | `.codex/config.toml` | `AGENTS.md` |
35
35
  | Gemini CLI | `gemini` | `.gemini/settings.json` | `GEMINI.md` |
@@ -51,6 +51,9 @@ Options:
51
51
  --switch-project Fetch projects and only update mapped workspace rules
52
52
  --skip-mcp Skip MCP server config installation
53
53
  --skip-rules Skip workspace rule installation
54
+ --profile-repo Run the guardrails profiler after init
55
+ --profiler-copilot-login
56
+ Run GitHub Copilot CLI login before VS Code Copilot profiling
54
57
  ```
55
58
 
56
59
  ### `@securityreviewai/securityreview-kit init --switch-project`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@securityreviewai/securityreview-kit",
3
- "version": "0.1.33",
3
+ "version": "0.1.35",
4
4
  "description": "Bootstrap security-review-mcp for AI IDEs and CLI tools",
5
5
  "author": "Debarshi Das <debarshi.das@we45.com>",
6
6
  "license": "UNLICENSED",
package/src/cli.js CHANGED
@@ -26,8 +26,8 @@ export function run() {
26
26
  .option('--switch-project', 'Fetch projects and only update mapped workspace rules')
27
27
  .option('--skip-mcp', 'Skip MCP server config installation')
28
28
  .option('--skip-rules', 'Skip workspace rule installation')
29
- .option('--skip-ide-cli-install', 'Do not install Cursor / Claude Code / Codex CLIs when those targets are selected')
30
- .option('--profile-repo', 'After init, run the guardrails profiler agent (non-interactive; needs cursor, claude, or codex target)')
29
+ .option('--skip-ide-cli-install', 'Do not install Cursor / Copilot / Claude Code / Codex CLIs when those targets are selected')
30
+ .option('--profile-repo', 'After init, run the guardrails profiler agent (non-interactive; needs cursor, vscode, claude, or codex target)')
31
31
  .option('--no-profile-repo', 'Skip the optional profiler agent step after init')
32
32
  .option(
33
33
  '--profiler-no-trust',
@@ -37,6 +37,10 @@ export function run() {
37
37
  '--profiler-cursor-login',
38
38
  'Before Cursor profiling, run `agent login` (or `cursor-agent login`) in this terminal (then profiling runs in the same init)',
39
39
  )
40
+ .option(
41
+ '--profiler-copilot-login',
42
+ 'Before VS Code Copilot profiling, run `copilot login` in this terminal',
43
+ )
40
44
  .option(
41
45
  '--profiler-quiet',
42
46
  'When profiling, use the standard progress message (default; retained for compatibility)',
@@ -6,6 +6,7 @@ import { ensureIdeClisForTargets } from '../utils/ide-cli-install.js';
6
6
  import { writeGuardrailsSkillBundles } from '../utils/guardrails-profiler-bundle.js';
7
7
  import {
8
8
  pickProfilerAgentTarget,
9
+ runCopilotLogin,
9
10
  runCursorAgentLogin,
10
11
  runProfilerAgent,
11
12
  } from '../utils/profiler-agent.js';
@@ -359,7 +360,7 @@ export async function initCommand(options) {
359
360
  if (bundlePaths.length === 0) {
360
361
  console.log(
361
362
  chalk.dim(
362
- ' (Guardrails skills are only written for Cursor, Claude Code, and Codex targets.)',
363
+ ' (Guardrails skills are only written for Cursor, VS Code Copilot, Claude Code, and Codex targets.)',
363
364
  ),
364
365
  );
365
366
  }
@@ -409,7 +410,7 @@ export async function initCommand(options) {
409
410
  if (!agentTarget) {
410
411
  console.log(
411
412
  chalk.yellow(
412
- ' \u26a0 Profiling needs Cursor, Claude Code, or Codex in your targets. Add one and re-run, or run the guardrails-init-profile command in your IDE.',
413
+ ' \u26a0 Profiling needs Cursor, VS Code Copilot, Claude Code, or Codex in your targets. Add one and re-run, or run the guardrails-init-profile command in your IDE.',
413
414
  ),
414
415
  );
415
416
  } else {
@@ -453,11 +454,44 @@ export async function initCommand(options) {
453
454
  }
454
455
  console.log('');
455
456
  }
457
+ } else if (agentTarget === 'vscode') {
458
+ console.log(
459
+ chalk.dim(
460
+ ' Copilot: profiling uses the VS Code MCP config and Copilot CLI tool approvals for this folder.',
461
+ ),
462
+ );
463
+
464
+ let runLogin = Boolean(options.profilerCopilotLogin);
465
+ if (!runLogin && interactive) {
466
+ runLogin = await confirm({
467
+ message:
468
+ 'Run GitHub Copilot CLI login in this terminal now? (Same init — profiling runs next. Choose No if already signed in.)',
469
+ default: true,
470
+ });
471
+ }
472
+ if (runLogin) {
473
+ console.log('');
474
+ console.log(chalk.bold.white(' GitHub Copilot CLI login'));
475
+ console.log(chalk.dim(' Complete the browser or device-code prompt, then return here.\n'));
476
+ const loginResult = runCopilotLogin(cwd);
477
+ if (loginResult.ok) {
478
+ console.log(chalk.green(' \u2713 GitHub Copilot CLI login step finished.'));
479
+ } else {
480
+ console.log(
481
+ chalk.yellow(
482
+ ` \u26a0 Copilot login exited with status ${loginResult.status ?? 'unknown'}. Profiling will still be attempted; sign in and re-run init if it fails.`,
483
+ ),
484
+ );
485
+ }
486
+ console.log('');
487
+ }
456
488
  } else {
457
489
  console.log(chalk.dim(' (Sign-in or approvals may be required in your terminal.)'));
458
490
  }
459
491
  console.log('');
460
- const showProfilerOutput = Boolean(options.profilerVerbose || options.profilerNoTrust);
492
+ const showProfilerOutput = Boolean(
493
+ options.profilerVerbose || (agentTarget === 'cursor' && options.profilerNoTrust),
494
+ );
461
495
  if (showProfilerOutput) {
462
496
  console.log(chalk.dim(' Profiling in progress. Agent output is visible for this run...'));
463
497
  } else {
@@ -499,6 +533,24 @@ export async function initCommand(options) {
499
533
  ' • Want interactive trust instead of `--trust`: run `securityreview-kit init ... --profiler-no-trust` and answer the prompts, then profile again.',
500
534
  ),
501
535
  );
536
+ } else if (agentTarget === 'vscode') {
537
+ console.log('');
538
+ console.log(chalk.dim(' Typical fixes:'));
539
+ console.log(
540
+ chalk.dim(
541
+ ' • Not signed in: re-run `securityreview-kit init` and choose Yes for GitHub Copilot CLI login, or pass `--profiler-copilot-login` with `--profile-repo`.',
542
+ ),
543
+ );
544
+ console.log(
545
+ chalk.dim(
546
+ ' • CLI missing: install GitHub Copilot CLI and verify `copilot --version`.',
547
+ ),
548
+ );
549
+ console.log(
550
+ chalk.dim(
551
+ ' • MCP missing: re-run init with VS Code selected and MCP installation enabled so `.vscode/mcp.json` is written.',
552
+ ),
553
+ );
502
554
  }
503
555
  }
504
556
  }
@@ -17,7 +17,7 @@ Configured SRAI project name: `<SRAI_PROJECT_NAME>`
17
17
 
18
18
  Do not skip MCP upload when credentials and MCP are available.
19
19
 
20
- Do **not** ask the user to verbally approve MCP for `security-review-mcp`. The repo’s **`.cursor/cli.json`** should list `Mcp(security-review-mcp:*)` under `permissions.allow`; call the MCP tools directly.
20
+ Do **not** ask the user to verbally approve MCP for `security-review-mcp`. The init-time profiler runner passes the CLI-specific MCP configuration and approval settings where supported; call the MCP tools directly.
21
21
 
22
22
  ## Cursor CLI (scripted)
23
23
 
@@ -30,3 +30,11 @@ Add `--output-format stream-json --stream-partial-output` only when you need ver
30
30
  During `securityreview-kit init`, choose **Yes** when asked to run Cursor login in-terminal, or pass **`--profiler-cursor-login`** with **`--profile-repo`** so login and profiling stay in one run.
31
31
 
32
32
  You can still sign in manually with `agent login` (or `cursor-agent login`). To handle trust/login interactively in the terminal, omit `--trust` and `--approve-mcps`.
33
+
34
+ ## GitHub Copilot CLI (scripted)
35
+
36
+ From the repo root, non-interactive runs should load the SRAI MCP server and allow the tools needed to scan, write profile files, and call MCP:
37
+
38
+ `copilot -p "<your profiling instructions>" --additional-mcp-config '{"mcpServers":{"security-review-mcp":{"type":"stdio","command":"npx","args":["-y","@securityreviewai/security-review-mcp@latest"]}}}' --allow-all`
39
+
40
+ During `securityreview-kit init`, choose **Yes** when asked to run GitHub Copilot CLI login, or pass **`--profiler-copilot-login`** with **`--profile-repo`** so `copilot login` and profiling stay in one run.
@@ -11,7 +11,7 @@ Configured SRAI project name: `<SRAI_PROJECT_NAME>`
11
11
 
12
12
  ## Canonical paths
13
13
 
14
- - **This skill & signal registry (read-only):** `<GUARDRAILS_SKILL_DIR>/` — e.g. `.cursor/skills/guardrails-profiler`, `.claude/skills/guardrails-profiler`, or `.codex/skills/guardrails-profiler` depending on where this file was installed.
14
+ - **This skill & signal registry (read-only):** `<GUARDRAILS_SKILL_DIR>/` — e.g. `.cursor/skills/guardrails-profiler`, `.github/skills/guardrails-profiler`, `.claude/skills/guardrails-profiler`, or `.codex/skills/guardrails-profiler` depending on where this file was installed.
15
15
  - **Signal registry file:** `<GUARDRAILS_SKILL_DIR>/references/signal-registry.json`
16
16
  - **Local guardrails file:** `.guardrails/profile.json`
17
17
  - **Combined manifest (project root):** `profile.json` — includes guardrails profile, vibe profile fields for MCP, and default pack payload
@@ -131,7 +131,7 @@ Write **`profile.json`** at the project root with **only** these parts:
131
131
 
132
132
  3. Call **`write_default_pack`** with `project_id` and the payload from **`profile.json.default_guardrail_pack`** (match the MCP tool’s schema).
133
133
 
134
- 4. **MCP approval:** Do **not** ask the user to “approve MCP” or “say you approve” for `security-review-mcp`. Security Review Kit installs **`.cursor/cli.json`** with `Mcp(security-review-mcp:*)` in `permissions.allow` so Cursor CLI runs tools without that prompt. Invoke `find_project_by_name`, `update_vibe_profile`, and `write_default_pack` directly. If a call still fails with permissions, report the error and suggest verifying Cursor **auto-run** / CLI permissions — not a conversational approval step.
134
+ 4. **MCP approval:** Do **not** ask the user to “approve MCP” or “say you approve” for `security-review-mcp`. Security Review Kit passes the configured MCP server and approval settings during init-time profiling where the CLI supports it (for example Cursor CLI permissions and Copilot CLI `--additional-mcp-config` / `--allow-all`). Invoke `find_project_by_name`, `update_vibe_profile`, and `write_default_pack` directly. If a call still fails with permissions, report the exact CLI permission error — not a conversational approval step.
135
135
 
136
136
  5. Confirm success: paths written (`profile.json`, `.guardrails/profile.json`) and whether both MCP calls succeeded, or the exact error.
137
137
 
@@ -149,4 +149,4 @@ If there are no signals:
149
149
 
150
150
  ## IDE-Specific Notes
151
151
 
152
- When run from Cursor Agent CLI, Claude Code, or Codex CLI, set `profiled_by` to a stable id (`agent` or `cursor-agent`, `claude`, `codex`).
152
+ When run from Cursor Agent CLI, GitHub Copilot CLI, Claude Code, or Codex CLI, set `profiled_by` to a stable id (`agent` or `cursor-agent`, `copilot`, `claude`, `codex`).
@@ -1,4 +1,5 @@
1
1
  import { join } from 'node:path';
2
+ import { GUARDRAILS_SELECTION_SKILL_REL_DIR } from '../../utils/constants.js';
2
3
  import { upsertSentinelBlock } from '../../utils/fs-helpers.js';
3
4
  import { getRuleContent } from './content.js';
4
5
 
@@ -7,7 +8,10 @@ import { getRuleContent } from './content.js';
7
8
  */
8
9
  export function generate(cwd, options = {}) {
9
10
  const filePath = join(cwd, '.github', 'copilot-instructions.md');
10
- const content = getRuleContent(options);
11
+ const content = getRuleContent({
12
+ ...options,
13
+ guardrailsSelectionSkillDir: GUARDRAILS_SELECTION_SKILL_REL_DIR.vscode,
14
+ });
11
15
  const action = upsertSentinelBlock(filePath, content);
12
16
  return { filePath, action };
13
17
  }
@@ -63,6 +63,7 @@ export const TARGET_NAMES = Object.keys(TARGETS);
63
63
  export const GUARDRAILS_PROFILER_SKILL_REL_DIR = {
64
64
  cursor: '.cursor/skills/guardrails-profiler',
65
65
  claude: '.claude/skills/guardrails-profiler',
66
+ vscode: '.github/skills/guardrails-profiler',
66
67
  codex: '.codex/skills/guardrails-profiler',
67
68
  };
68
69
 
@@ -70,6 +71,7 @@ export const GUARDRAILS_PROFILER_SKILL_REL_DIR = {
70
71
  export const GUARDRAILS_SELECTION_SKILL_REL_DIR = {
71
72
  cursor: '.cursor/skills/guardrails-selection',
72
73
  claude: '.claude/skills/guardrails-selection',
74
+ vscode: '.github/skills/guardrails-selection',
73
75
  codex: '.codex/skills/guardrails-selection',
74
76
  };
75
77
 
@@ -1,7 +1,7 @@
1
1
  import { spawnSync } from 'node:child_process';
2
2
  import { augmentPathEnv, resolveCursorAgentExecutable } from './cursor-agent-path.js';
3
3
 
4
- const AGENT_CLI_TARGETS = new Set(['cursor', 'claude', 'codex']);
4
+ const AGENT_CLI_TARGETS = new Set(['cursor', 'claude', 'vscode', 'codex']);
5
5
 
6
6
  function commandOk(cmd, args = ['--version'], env = process.env) {
7
7
  const r = spawnSync(cmd, args, { stdio: 'ignore', env });
@@ -13,7 +13,7 @@ function runShell(script) {
13
13
  }
14
14
 
15
15
  /**
16
- * Ensure Cursor / Claude Code / Codex CLIs are present when those targets are selected.
16
+ * Ensure Cursor / Claude Code / Copilot / Codex CLIs are present when those targets are selected.
17
17
  * Installation uses vendor scripts or npm where appropriate.
18
18
  */
19
19
  export function ensureIdeCliForTarget(target, options = {}) {
@@ -89,6 +89,47 @@ export function ensureIdeCliForTarget(target, options = {}) {
89
89
  : { target, ok: false, message: 'Codex CLI npm install failed' };
90
90
  }
91
91
 
92
+ if (target === 'vscode') {
93
+ if (commandOk('copilot', ['--version'], augmentPathEnv())) {
94
+ return { target, ok: true, already: true };
95
+ }
96
+ if (skipInstall) {
97
+ return {
98
+ target,
99
+ ok: false,
100
+ message:
101
+ 'GitHub Copilot CLI not found (`copilot`). Install from https://docs.github.com/copilot/how-tos/copilot-cli/set-up-copilot-cli/install-copilot-cli.',
102
+ };
103
+ }
104
+ if (process.platform === 'win32') {
105
+ const r = runShell('winget install GitHub.Copilot');
106
+ if (r.status !== 0) {
107
+ return { target, ok: false, message: 'GitHub Copilot CLI winget install failed' };
108
+ }
109
+ return commandOk('copilot', ['--version'], augmentPathEnv())
110
+ ? { target, ok: true }
111
+ : {
112
+ target,
113
+ ok: false,
114
+ message:
115
+ 'GitHub Copilot CLI (`copilot`) not found after install; open a new shell or ensure it is on PATH and re-run init',
116
+ };
117
+ }
118
+ const r = runShell('curl -fsSL https://gh.io/copilot-install | bash');
119
+ if (r.status !== 0) {
120
+ return { target, ok: false, message: 'GitHub Copilot CLI install script failed' };
121
+ }
122
+ if (!commandOk('copilot', ['--version'], augmentPathEnv())) {
123
+ return {
124
+ target,
125
+ ok: false,
126
+ message:
127
+ 'GitHub Copilot CLI (`copilot`) not found after install; open a new shell or ensure the install directory is on PATH and re-run init',
128
+ };
129
+ }
130
+ return { target, ok: true };
131
+ }
132
+
92
133
  return { target, ok: true, skipped: true };
93
134
  }
94
135
 
@@ -1,8 +1,10 @@
1
1
  import { spawnSync } from 'node:child_process';
2
- import { GUARDRAILS_PROFILER_SKILL_REL_DIR } from './constants.js';
2
+ import { join } from 'node:path';
3
+ import { GUARDRAILS_PROFILER_SKILL_REL_DIR, MCP_SERVER_NAME } from './constants.js';
3
4
  import { augmentPathEnv, resolveCursorAgentExecutable } from './cursor-agent-path.js';
5
+ import { readJson } from './fs-helpers.js';
4
6
 
5
- const PREFERRED_ORDER = ['cursor', 'claude', 'codex'];
7
+ const PREFERRED_ORDER = ['cursor', 'vscode', 'claude', 'codex'];
6
8
 
7
9
  function commandOk(cmd, args = ['--version'], env = process.env) {
8
10
  const r = spawnSync(cmd, args, { stdio: 'ignore', env });
@@ -48,6 +50,28 @@ export function runCursorAgentLogin(cwd) {
48
50
  return { ok: r.status === 0, status: r.status, message: r.status !== 0 ? spawnErr : undefined };
49
51
  }
50
52
 
53
+ /**
54
+ * Run GitHub Copilot CLI OAuth login in the current terminal (stdio inherited).
55
+ * `copilot login` exits after the device-flow succeeds, so init can continue into profiling.
56
+ */
57
+ export function runCopilotLogin(cwd) {
58
+ const env = augmentPathEnv(process.env);
59
+ if (!commandOk('copilot', ['--version'], env)) {
60
+ return {
61
+ ok: false,
62
+ status: null,
63
+ message:
64
+ 'GitHub Copilot CLI not found (`copilot`). Install from https://docs.github.com/copilot/how-tos/copilot-cli/set-up-copilot-cli/install-copilot-cli.',
65
+ };
66
+ }
67
+ const r = spawnSync('copilot', ['login'], { cwd, stdio: 'inherit', env });
68
+ const spawnErr = r.error ? r.error.message : null;
69
+ if (r.status === null && spawnErr) {
70
+ return { ok: false, status: null, message: spawnErr };
71
+ }
72
+ return { ok: r.status === 0, status: r.status, message: r.status !== 0 ? spawnErr : undefined };
73
+ }
74
+
51
75
  export function pickProfilerAgentTarget(targets) {
52
76
  for (const t of PREFERRED_ORDER) {
53
77
  if (targets.includes(t)) {
@@ -128,9 +152,61 @@ export function runProfilerAgent(
128
152
  return buildProfilerResult(r);
129
153
  }
130
154
 
155
+ if (target === 'vscode') {
156
+ if (!commandOk('copilot', ['--version'], env)) {
157
+ return { ok: false, message: 'copilot not on PATH' };
158
+ }
159
+
160
+ const mcpConfig = buildCopilotAdditionalMcpConfig(cwd);
161
+ if (!mcpConfig) {
162
+ return {
163
+ ok: false,
164
+ message:
165
+ 'VS Code MCP config not found for security-review-mcp. Re-run init with MCP installation enabled.',
166
+ };
167
+ }
168
+
169
+ const args = [
170
+ '-p',
171
+ prompt,
172
+ '--additional-mcp-config',
173
+ mcpConfig,
174
+ '--allow-all',
175
+ ];
176
+ if (streamProgress) {
177
+ args.push('--output-format', 'json');
178
+ }
179
+ const r = spawnSync('copilot', args, opts);
180
+ return buildProfilerResult(r);
181
+ }
182
+
131
183
  return { ok: false, message: 'unsupported agent target' };
132
184
  }
133
185
 
186
+ export function buildCopilotAdditionalMcpConfig(cwd) {
187
+ const vscodeMcp = readJson(join(cwd, '.vscode', 'mcp.json'));
188
+ const sourceServer =
189
+ vscodeMcp?.mcpServers?.[MCP_SERVER_NAME] || vscodeMcp?.servers?.[MCP_SERVER_NAME];
190
+
191
+ if (!sourceServer || typeof sourceServer !== 'object') {
192
+ return null;
193
+ }
194
+
195
+ const server = { ...sourceServer };
196
+ if (!server.type) {
197
+ server.type = 'stdio';
198
+ }
199
+ if (!Array.isArray(server.tools)) {
200
+ server.tools = ['*'];
201
+ }
202
+
203
+ return JSON.stringify({
204
+ mcpServers: {
205
+ [MCP_SERVER_NAME]: server,
206
+ },
207
+ });
208
+ }
209
+
134
210
  function buildProfilerResult(result) {
135
211
  if (result.error) {
136
212
  return { ok: false, status: result.status, message: result.error.message };
@@ -0,0 +1,41 @@
1
+ import { mkdirSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { test } from 'node:test';
5
+ import assert from 'node:assert/strict';
6
+ import {
7
+ buildCopilotAdditionalMcpConfig,
8
+ pickProfilerAgentTarget,
9
+ } from './profiler-agent.js';
10
+
11
+ test('pickProfilerAgentTarget supports VS Code Copilot', () => {
12
+ assert.equal(pickProfilerAgentTarget(['vscode']), 'vscode');
13
+ assert.equal(pickProfilerAgentTarget(['codex', 'vscode']), 'vscode');
14
+ });
15
+
16
+ test('buildCopilotAdditionalMcpConfig converts VS Code MCP config', () => {
17
+ const cwd = join(tmpdir(), `securityreview-kit-${Date.now()}`);
18
+ mkdirSync(join(cwd, '.vscode'), { recursive: true });
19
+ writeFileSync(
20
+ join(cwd, '.vscode', 'mcp.json'),
21
+ JSON.stringify({
22
+ servers: {
23
+ 'security-review-mcp': {
24
+ type: 'stdio',
25
+ command: 'npx',
26
+ args: ['-y', '@securityreviewai/security-review-mcp@latest'],
27
+ env: {
28
+ SECURITY_REVIEW_API_URL: 'https://api.example.test',
29
+ SECURITY_REVIEW_API_TOKEN: 'token',
30
+ },
31
+ },
32
+ },
33
+ }),
34
+ );
35
+
36
+ const converted = JSON.parse(buildCopilotAdditionalMcpConfig(cwd));
37
+
38
+ assert.deepEqual(Object.keys(converted.mcpServers), ['security-review-mcp']);
39
+ assert.equal(converted.mcpServers['security-review-mcp'].command, 'npx');
40
+ assert.deepEqual(converted.mcpServers['security-review-mcp'].tools, ['*']);
41
+ });