chore(bots): per-window MCP isolation via --strict-mcp-config
Каждое bot-окно грузит ТОЛЬКО нужные роли серверы (не все 7+ в каждом окне).
Выигрыш: не спавнить heavy-серверы зря (docker postgres в frontend/qa), right-size
eager-набор, чистый tool-surface на роль. (Контекст tool-search и так бережёт —
deferred ≈ бесплатно; это про процессы + eager + ясность.)
- .claude/mcp/{analyst,backend,frontend,reviewer,qa}.json — self-contained per-role
конфиги. Секреты НЕ инлайнятся: ${OBSIDIAN_API_KEY}/${GENDESIGN_DB_URI}/
${GLITCHTIP_TOKEN} через env-подстановку (.mcp.json env expansion, подтв. в доках).
Матрица: forgejo+obsidian+context7 eager везде; pg-gendesign eager у backend/reviewer,
deferred у analyst; UI (playwright/a11y/lighthouse/shadcn) только frontend/qa; fetch+
glitchtip у backend; glitchtip у qa.
- start-bot.ps1: извлекает MCP-секреты из ~/.claude.json (единый источник) → export →
запускает `claude --strict-mcp-config --mcp-config .claude/mcp/<role>.json`.
Main/интерактивное окно (без start-bot.ps1) по-прежнему видит полный .mcp.json+user.
This commit is contained in:
parent
f2adc7417a
commit
2df8f78747
6 changed files with 137 additions and 2 deletions
22
.claude/mcp/analyst.json
Normal file
22
.claude/mcp/analyst.json
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"obsidian": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": ["mcp-obsidian"],
|
||||||
|
"env": { "OBSIDIAN_API_KEY": "${OBSIDIAN_API_KEY}", "OBSIDIAN_HOST": "127.0.0.1", "OBSIDIAN_PORT": "27124" },
|
||||||
|
"alwaysLoad": true
|
||||||
|
},
|
||||||
|
"forgejo": {
|
||||||
|
"command": "C:/Users/user/tools/bin/forgejo-mcp.exe",
|
||||||
|
"args": ["-t", "stdio", "-url", "https://git.gendsgn.ru", "-debug=false"],
|
||||||
|
"alwaysLoad": true
|
||||||
|
},
|
||||||
|
"context7": { "type": "http", "url": "https://mcp.context7.com/mcp", "alwaysLoad": true },
|
||||||
|
"postgres-gendesign": {
|
||||||
|
"type": "stdio",
|
||||||
|
"command": "docker",
|
||||||
|
"args": ["run", "-i", "--rm", "-e", "DATABASE_URI", "crystaldba/postgres-mcp", "--access-mode=unrestricted"],
|
||||||
|
"env": { "DATABASE_URI": "${GENDESIGN_DB_URI}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
.claude/mcp/backend.json
Normal file
29
.claude/mcp/backend.json
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"obsidian": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": ["mcp-obsidian"],
|
||||||
|
"env": { "OBSIDIAN_API_KEY": "${OBSIDIAN_API_KEY}", "OBSIDIAN_HOST": "127.0.0.1", "OBSIDIAN_PORT": "27124" },
|
||||||
|
"alwaysLoad": true
|
||||||
|
},
|
||||||
|
"forgejo": {
|
||||||
|
"command": "C:/Users/user/tools/bin/forgejo-mcp.exe",
|
||||||
|
"args": ["-t", "stdio", "-url", "https://git.gendsgn.ru", "-debug=false"],
|
||||||
|
"alwaysLoad": true
|
||||||
|
},
|
||||||
|
"context7": { "type": "http", "url": "https://mcp.context7.com/mcp", "alwaysLoad": true },
|
||||||
|
"postgres-gendesign": {
|
||||||
|
"type": "stdio",
|
||||||
|
"command": "docker",
|
||||||
|
"args": ["run", "-i", "--rm", "-e", "DATABASE_URI", "crystaldba/postgres-mcp", "--access-mode=unrestricted"],
|
||||||
|
"env": { "DATABASE_URI": "${GENDESIGN_DB_URI}" },
|
||||||
|
"alwaysLoad": true
|
||||||
|
},
|
||||||
|
"fetch": { "command": "uvx", "args": ["mcp-server-fetch"] },
|
||||||
|
"glitchtip": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["-y", "mcp-glitchtip"],
|
||||||
|
"env": { "GLITCHTIP_TOKEN": "${GLITCHTIP_TOKEN}", "GLITCHTIP_ORGANIZATION": "gendesign", "GLITCHTIP_BASE_URL": "https://errors.gendsgn.ru" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
.claude/mcp/frontend.json
Normal file
20
.claude/mcp/frontend.json
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"obsidian": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": ["mcp-obsidian"],
|
||||||
|
"env": { "OBSIDIAN_API_KEY": "${OBSIDIAN_API_KEY}", "OBSIDIAN_HOST": "127.0.0.1", "OBSIDIAN_PORT": "27124" },
|
||||||
|
"alwaysLoad": true
|
||||||
|
},
|
||||||
|
"forgejo": {
|
||||||
|
"command": "C:/Users/user/tools/bin/forgejo-mcp.exe",
|
||||||
|
"args": ["-t", "stdio", "-url", "https://git.gendsgn.ru", "-debug=false"],
|
||||||
|
"alwaysLoad": true
|
||||||
|
},
|
||||||
|
"context7": { "type": "http", "url": "https://mcp.context7.com/mcp", "alwaysLoad": true },
|
||||||
|
"playwright": { "command": "npx", "args": ["-y", "@playwright/mcp@latest", "--cdp-endpoint=http://localhost:9222"] },
|
||||||
|
"a11y": { "command": "npx", "args": ["-y", "a11y-mcp"] },
|
||||||
|
"lighthouse": { "command": "npx", "args": ["-y", "-p", "@danielsogl/lighthouse-mcp", "lighthouse-mcp-server"] },
|
||||||
|
"shadcn": { "command": "npx", "args": ["shadcn@latest", "mcp"] }
|
||||||
|
}
|
||||||
|
}
|
||||||
23
.claude/mcp/qa.json
Normal file
23
.claude/mcp/qa.json
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"obsidian": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": ["mcp-obsidian"],
|
||||||
|
"env": { "OBSIDIAN_API_KEY": "${OBSIDIAN_API_KEY}", "OBSIDIAN_HOST": "127.0.0.1", "OBSIDIAN_PORT": "27124" },
|
||||||
|
"alwaysLoad": true
|
||||||
|
},
|
||||||
|
"forgejo": {
|
||||||
|
"command": "C:/Users/user/tools/bin/forgejo-mcp.exe",
|
||||||
|
"args": ["-t", "stdio", "-url", "https://git.gendsgn.ru", "-debug=false"],
|
||||||
|
"alwaysLoad": true
|
||||||
|
},
|
||||||
|
"playwright": { "command": "npx", "args": ["-y", "@playwright/mcp@latest", "--cdp-endpoint=http://localhost:9222"], "alwaysLoad": true },
|
||||||
|
"a11y": { "command": "npx", "args": ["-y", "a11y-mcp"] },
|
||||||
|
"lighthouse": { "command": "npx", "args": ["-y", "-p", "@danielsogl/lighthouse-mcp", "lighthouse-mcp-server"] },
|
||||||
|
"glitchtip": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["-y", "mcp-glitchtip"],
|
||||||
|
"env": { "GLITCHTIP_TOKEN": "${GLITCHTIP_TOKEN}", "GLITCHTIP_ORGANIZATION": "gendesign", "GLITCHTIP_BASE_URL": "https://errors.gendsgn.ru" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
.claude/mcp/reviewer.json
Normal file
23
.claude/mcp/reviewer.json
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"obsidian": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": ["mcp-obsidian"],
|
||||||
|
"env": { "OBSIDIAN_API_KEY": "${OBSIDIAN_API_KEY}", "OBSIDIAN_HOST": "127.0.0.1", "OBSIDIAN_PORT": "27124" },
|
||||||
|
"alwaysLoad": true
|
||||||
|
},
|
||||||
|
"forgejo": {
|
||||||
|
"command": "C:/Users/user/tools/bin/forgejo-mcp.exe",
|
||||||
|
"args": ["-t", "stdio", "-url", "https://git.gendsgn.ru", "-debug=false"],
|
||||||
|
"alwaysLoad": true
|
||||||
|
},
|
||||||
|
"context7": { "type": "http", "url": "https://mcp.context7.com/mcp", "alwaysLoad": true },
|
||||||
|
"postgres-gendesign": {
|
||||||
|
"type": "stdio",
|
||||||
|
"command": "docker",
|
||||||
|
"args": ["run", "-i", "--rm", "-e", "DATABASE_URI", "crystaldba/postgres-mcp", "--access-mode=unrestricted"],
|
||||||
|
"env": { "DATABASE_URI": "${GENDESIGN_DB_URI}" },
|
||||||
|
"alwaysLoad": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -49,9 +49,27 @@ if ($me -ne $bot) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# MCP-секреты для per-role конфига (.claude/mcp/<role>.json через ${VAR}-подстановку).
|
||||||
|
# Единый источник — существующий ~/.claude.json; в role-файлах секретов НЕТ.
|
||||||
|
$claudeJson = Join-Path $env:USERPROFILE ".claude.json"
|
||||||
|
if (Test-Path $claudeJson) {
|
||||||
|
$ms = (Get-Content $claudeJson -Raw | ConvertFrom-Json).mcpServers
|
||||||
|
if ($ms.obsidian) { $env:OBSIDIAN_API_KEY = $ms.obsidian.env.OBSIDIAN_API_KEY }
|
||||||
|
if ($ms.'postgres-gendesign') { $env:GENDESIGN_DB_URI = $ms.'postgres-gendesign'.env.DATABASE_URI }
|
||||||
|
if ($ms.glitchtip) { $env:GLITCHTIP_TOKEN = $ms.glitchtip.env.GLITCHTIP_TOKEN }
|
||||||
|
}
|
||||||
|
# fallback: obsidian-ключ может жить в project .mcp.json
|
||||||
|
if (-not $env:OBSIDIAN_API_KEY -and (Test-Path "$PSScriptRoot\..\.mcp.json")) {
|
||||||
|
$env:OBSIDIAN_API_KEY = (Get-Content "$PSScriptRoot\..\.mcp.json" -Raw | ConvertFrom-Json).mcpServers.obsidian.env.OBSIDIAN_API_KEY
|
||||||
|
}
|
||||||
|
|
||||||
|
$mcpConfig = (Resolve-Path "$PSScriptRoot\..\.claude\mcp\$Role.json").Path
|
||||||
|
|
||||||
Write-Host "OK bot=$bot" -ForegroundColor Green
|
Write-Host "OK bot=$bot" -ForegroundColor Green
|
||||||
Write-Host "OK forgejo MCP token set (FORGEJO_ACCESS_TOKEN) + git identity + forgejo-bot remote" -ForegroundColor Green
|
Write-Host "OK identity + tokens + forgejo-bot remote" -ForegroundColor Green
|
||||||
|
Write-Host "OK per-role MCP (--strict-mcp-config): $mcpConfig" -ForegroundColor Green
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "В окне Claude (Opus 4.8 для reviewer): /work-as-$Role -> затем /loop" -ForegroundColor Cyan
|
Write-Host "В окне Claude (Opus 4.8 для reviewer): /work-as-$Role -> затем /loop" -ForegroundColor Cyan
|
||||||
|
|
||||||
claude
|
# --strict-mcp-config: грузим ТОЛЬКО серверы этой роли (игнорируем .mcp.json + ~/.claude.json)
|
||||||
|
claude --strict-mcp-config --mcp-config "$mcpConfig"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue