feat(plugin): точка входа лаунчера и объявление MCP-сервера
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"kompas": {
|
||||
"command": "powershell",
|
||||
"args": ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass",
|
||||
"-File", "${CLAUDE_PLUGIN_ROOT}/scripts/launch-kompas-mcp.ps1"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#requires -Version 5.1
|
||||
# Точка входа MCP-сервера КОМПАС-3D.
|
||||
# ИНВАРИАНТ: до запуска сервера в stdout не уходит ни байта — stdout занят JSON-RPC.
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
|
||||
$exe = $null
|
||||
try {
|
||||
if (-not [string]::IsNullOrWhiteSpace($env:KOMPAS_MCP_EXE)) {
|
||||
$exe = $env:KOMPAS_MCP_EXE
|
||||
}
|
||||
else {
|
||||
Import-Module (Join-Path $PSScriptRoot 'KompasMcpBootstrap.psm1') -Force
|
||||
$lockPath = Join-Path (Split-Path -Parent $PSScriptRoot) 'server.lock.json'
|
||||
$lock = Read-KompasMcpLock -Path $lockPath
|
||||
$exe = Resolve-KompasMcpExecutable -Lock $lock
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $exe)) {
|
||||
throw "не найден сервер: $exe"
|
||||
}
|
||||
}
|
||||
catch {
|
||||
[Console]::Error.WriteLine("kompas-mcp launcher: $($_.Exception.Message)")
|
||||
exit 1
|
||||
}
|
||||
|
||||
& $exe @args
|
||||
$serverExit = $LASTEXITCODE
|
||||
exit $serverExit
|
||||
@@ -0,0 +1,35 @@
|
||||
BeforeAll {
|
||||
$script:Launcher = Join-Path $PSScriptRoot '..' '..' 'plugin' 'scripts' 'launch-kompas-mcp.ps1'
|
||||
}
|
||||
|
||||
Describe 'launch-kompas-mcp.ps1' {
|
||||
It 'не сорит в stdout: наружу идёт только вывод сервера' {
|
||||
$env:KOMPAS_MCP_EXE = $env:ComSpec
|
||||
try {
|
||||
$out = & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File $script:Launcher /c echo PONG
|
||||
($out | Where-Object { $_.Trim().Length -gt 0 }) -join "`n" | Should -Be 'PONG'
|
||||
} finally { Remove-Item Env:\KOMPAS_MCP_EXE -ErrorAction SilentlyContinue }
|
||||
}
|
||||
|
||||
It 'пробрасывает код возврата сервера' {
|
||||
$env:KOMPAS_MCP_EXE = $env:ComSpec
|
||||
try {
|
||||
& powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File $script:Launcher /c exit 42 | Out-Null
|
||||
$LASTEXITCODE | Should -Be 42
|
||||
} finally { Remove-Item Env:\KOMPAS_MCP_EXE -ErrorAction SilentlyContinue }
|
||||
}
|
||||
|
||||
It 'падает с кодом 1 и сообщением в stderr, когда путь из KOMPAS_MCP_EXE не существует' {
|
||||
$env:KOMPAS_MCP_EXE = 'C:\нет\такого\kompas-mcp.exe'
|
||||
try {
|
||||
# Примечание: "2>&1 1>$null" — стандартная идиома для изоляции stderr у cmdlet'ов,
|
||||
# но для внешнего процесса (powershell.exe) PowerShell разрешает "1>$null" раньше
|
||||
# слияния "2>&1", и объединённый поток тоже уходит в NUL (проверено эмпирически:
|
||||
# $stderr.Count == 0 при обеих раскладках операторов). В этом сценарии скрипт падает
|
||||
# до вызова сервера и ничего не пишет в stdout, поэтому достаточно "2>&1" без null-редиректа.
|
||||
$stderr = & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File $script:Launcher 2>&1
|
||||
$LASTEXITCODE | Should -Be 1
|
||||
($stderr | Out-String) | Should -Match 'kompas-mcp launcher'
|
||||
} finally { Remove-Item Env:\KOMPAS_MCP_EXE -ErrorAction SilentlyContinue }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user