@arcote.tech/arc-mcp-stdio
v0.8.25
Published
Transport stdio dla serwerów MCP Arc — most między klientem AI (stdio) a lokalnym serwerem aplikacji (HTTP)
Readme
@arcote.tech/arc-mcp-stdio
Transport stdio dla serwerów MCP aplikacji desktopowych Arc.
Problem
Klienci AI (Claude Desktop) uruchamiają serwery MCP jako proces i rozmawiają
z nimi po stdin/stdout. Lokalny serwer HTTP im nie wystarcza — konektory w UI
wymagają publicznego https. Typowe obejście, npx mcp-remote <url>, wymaga
zainstalowanego Node.js, czyli stawia barierę przed użytkownikiem, który chciał
tylko podłączyć narzędzie.
Rozwiązanie
Klient uruchamia binarkę aplikacji, którą użytkownik już ma. Most czyta JSON-RPC ze stdin i przekazuje go pod adres działającej instancji:
Klient AI ──stdio──► app --mcp-stdio ──HTTP──► działająca aplikacjaMost jest klientem aplikacji, nie drugim serwerem: nie otwiera bazy i nie ładuje stanu. Dzięki temu dziennik wywołań w aplikacji widzi każde pytanie modelu, a lokalna baza ma jednego pisarza.
Użycie
import { mcpStdio } from "@arcote.tech/arc-mcp-stdio";
export const myStdio = mcpStdio({
server: myMcpServer, // referencja, nie napis — ścieżka z fullPath
token: async (baseUrl) => { // aplikacja wie, jak zdobyć swój token
const res = await fetch(`${baseUrl}/route/auth`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ k: LOCAL_SECRET }),
});
return res.ok ? (await res.json()).token : null;
},
});
export const context = defineContext([myMcpServer, myStdio, /* … */]);Resztą zajmuje się runtime arc app: rozpoznaje flagę --mcp-stdio, znajduje
element w kontekście i podaje mu adres serwera oraz sposób podniesienia
aplikacji, gdy ta nie działa.
Podział odpowiedzialności
| Warstwa | Odpowiada za |
|---|---|
| ten pakiet | protokół po liniach, przekazanie do HTTP, mapowanie błędów |
| arc-cli (arc app) | flaga procesu, port, autostart powłoki, health-check |
| aplikacja | deklaracja elementu i sposób zdobycia tokenu |
Pakiet nie wie nic o Tauri ani o kształcie uwierzytelniania konkretnej aplikacji.
Zachowanie brzegowe
- Notyfikacje (wiadomości bez
id) idą do serwera, ale nie generują odpowiedzi. - Błąd transportu wraca jako JSON-RPC
error, nigdy jako cisza — milczenie zawiesiłoby klienta w oczekiwaniu. - 401 → jedno odświeżenie tokenu i ponowienie (klient AI nie ponawia sam).
- Brak połączenia →
ensureRunning(), potem jedna ponowna próba. - Wejście czytamy przez
getReader(), boReadableStreamw binarcebun build --compilenie maSymbol.asyncIterator(w zwykłym procesie Buna ma — ta różnica potrafi przejść testy i wywrócić wydanie).
Testy
bun test