Skip to main content
Glama

toolchain-mcp

MCP server (stdio) dla Claude Code integrujący toolchain: GitLab, Jira, Redmine, Mattermost i Harbor — plus composite tools (xref_*) łączące dane między systemami (np. "co wiadomo o tickecie X" jednym zapytaniem zamiast czterech). Connector danego serwisu włącza się automatycznie gdy w środowisku ustawiony jest komplet jego zmiennych — brak konfiguracji = zero toolí tego serwisu, zero szumu w liście dostępnych narzędzi.

Connectory i toole (~32)

Aktualną listę (z podziałem R/W) daje node scripts/list-tools.mjs po zbudowaniu projektu i ustawieniu env — patrz Smoke test. Stan na dziś:

Connector

Toole

gitlab (13.8.4 CE)

gitlab_list_mrs, gitlab_get_mr, gitlab_get_mr_diff, gitlab_list_mr_discussions, gitlab_reply_mr_discussion [W], gitlab_list_pipelines, gitlab_get_job_log, gitlab_get_file, gitlab_search

jira (7.7.1 Server)

jira_search, jira_get_issue, jira_add_comment [W], jira_list_transitions, jira_find_user, jira_list_projects

redmine (redmine.example.com)

redmine_list_issues, redmine_get_issue, redmine_add_note [W], redmine_list_projects, redmine_search, redmine_whoami

mattermost (mattermost.example.com, 10.11.18)

mm_search_posts, mm_get_channel_posts, mm_get_thread, mm_post_message [W], mm_find_channel, mm_find_user

harbor (harbor.example.com)

harbor_list_repositories, harbor_list_artifacts, harbor_get_vulnerabilities

xref (composite, differentiator)

xref_ticket (Jira ∨ Redmine → agregacja z GitLab/MM), xref_find_user (login → lookup w Jira/GitLab/MM)

[W] = write tool, wyłączany przez TOOLCHAIN_MCP_READ_ONLY=1 (patrz niżej).

Related MCP server: AlibabaCloud DevOps MCP Server

Wymagania

  • Node.js ≥ 20

  • Dostęp sieciowy do serwisów, które integrujesz. Jeśli któraś instancja jest w sieci wewnętrznej / za VPN (typowo GitLab, Jira, Harbor), zestaw połączenie zanim odpalisz serwer. Instancje publiczne nie wymagają VPN-a.

Instalacja

git clone ssh://git@gitlab.kodownik.co:2424/kodowniki/toolchain-mcp.git
cd toolchain-mcp
npm ci
npm run build

Build kompiluje TypeScript do dist/ (tsc -p tsconfig.build.json) — serwer, scripts/list-tools.mjs i scripts/smoke.mjs importują z dist/, nie z src/.

Konfiguracja

Wszystkie zmienne mają prefiks TOOLCHAIN_MCP_ (gołe GITLAB_URL itp. kolidują ze zmiennymi środowiska deweloperów). Connector jest aktywny tylko gdy ustawiony jest komplet jego zmiennych credentialowych — URL ma sensowny default i nie musi być podawany.

Zmienna

Default

Uwagi

TOOLCHAIN_MCP_GITLAB_URL

https://gitlab.example.com

TOOLCHAIN_MCP_GITLAB_TOKEN

PAT scope api lub read_api

TOOLCHAIN_MCP_JIRA_URL

https://jira.example.com

TOOLCHAIN_MCP_JIRA_USERNAME / TOOLCHAIN_MCP_JIRA_PASSWORD

basic auth (7.7.1 bez PAT)

TOOLCHAIN_MCP_REDMINE_URL

https://redmine.example.com

TOOLCHAIN_MCP_REDMINE_API_KEY

z /my/account

TOOLCHAIN_MCP_MM_URL

https://mattermost.example.com

TOOLCHAIN_MCP_MM_TOKEN

bot token LUB session token — najłatwiej npm run mm-login (GitLab-SSO-only, patrz niżej)

TOOLCHAIN_MCP_MM_TEAM

default team (nazwa-handle)

TOOLCHAIN_MCP_HARBOR_URL

https://harbor.example.com

TOOLCHAIN_MCP_HARBOR_USER / TOOLCHAIN_MCP_HARBOR_PASSWORD

robot account (robot$... — uwaga na $ w shellu)

TOOLCHAIN_MCP_READ_ONLY

0

1 = write-toole nie są rejestrowane

TOOLCHAIN_MCP_CA_FILE

dodatkowy CA (alternatywa: NODE_EXTRA_CA_CERTS)

TOOLCHAIN_MCP_<SVC>_INSECURE_TLS

0

per-serwis opt-out z weryfikacji TLS (NIGDY globalny NODE_TLS_REJECT_UNAUTHORIZED=0)

TOOLCHAIN_MCP_TIMEOUT_MS

15000

timeout HTTP

Jak zdobyć każdy token

GitLab (gitlab.example.com) — zalogowany w GitLab → Settings → Access Tokens → nowy Personal Access Token, scope read_api (albo api jeśli chcesz też gitlab_reply_mr_discussion). Wklej do TOOLCHAIN_MCP_GITLAB_TOKEN.

Jira (jira.example.com, wersja 7.7.1)PAT-ów tu nie ma (weszły dopiero w Jirze 8.14+). Auth to zwykłe login+hasło domenowe AD, więc TOOLCHAIN_MCP_JIRA_USERNAME / TOOLCHAIN_MCP_JIRA_PASSWORD to Twój login i hasło domenowe.

⚠️ Uwaga na rotację hasła. Gdy zmienisz hasło domenowe , serwer z nadal starym hasłem w env zacznie dostawać 401 — kilka prób ze złym hasłem może zablokować konto AD i/lub włączyć CAPTCHA-blokadę logowania w Jirze. Po każdej rotacji hasła natychmiast zaktualizuj TOOLCHAIN_MCP_JIRA_PASSWORD (i zrestartuj serwer MCP w Claude Code).

Redmine (redmine.example.com) — zaloguj się w przeglądarce → Moje kontoKlucz dostępu API (jeśli sekcji nie widać, REST API nie jest włączone dla Twojego konta — poproś admina o włączenie). Wklej do TOOLCHAIN_MCP_REDMINE_API_KEY.

Mattermost (mattermost.example.com) — logowanie na tym serwerze jest wyłącznie przez GitLab SSO (OAuth do osobnej instancji mattermost.example.com), więc zwykłego tokenu API nie da się wygenerować z ustawień konta. Trzy ścieżki (od najwygodniejszej):

  • Helper (zalecane): uruchom npm run mm-login — otworzy się okno przeglądarki (systemowy Chrome), zalogujesz się raz jak zwykle (GitLab SSO + ewentualne 2FA), a skrypt wyłuska token sesji MMAUTHTOKEN i wypisze export TOOLCHAIN_MCP_MM_TOKEN='…'. Dodaj --write, by od razu zapisał go do ~/.secrets (plik dostaje chmod 600). Jeśli chcesz eval wyniku, wołaj node scripts/mm-gitlab-login.mjs bezpośrednio (nie npm run …, bo npm dokłada baner na stdout). Profil przeglądarki jest trwały (~/.cache/toolchain-mcp/mm-profile), więc przy odświeżaniu wygasłego tokenu zwykle wystarczy jedno kliknięcie. Zero haseł w plikach, zero ryzyka lockoutu konta (login robi prawdziwa przeglądarka). Wymaga devDependency playwright + systemowego Chrome (lub npx playwright install chromium).

  • Docelowo (bez wygasania): poproś admina Mattermost o bot account — token bota nie wygasa, w przeciwieństwie do tokenu sesji.

  • Ręcznie: zaloguj się w przeglądarce na mattermost.example.com, DevTools → ApplicationCookies → skopiuj wartość ciasteczka MMAUTHTOKEN. To token sesji — wygasa; po wygaśnięciu mm_* zwracają 401.

Harbor (harbor.example.com) — poproś admina projektu demo w Harborze o robot account (robot$<nazwa> + hasło). Uwaga: nazwa robota zawiera znak $ — w shellu i w .env cytuj wartość w pojedynczym cudzysłowie, żeby powłoka nie próbowała go rozwinąć jako zmienną.

Podpięcie do Claude Code

Wariant A — claude mcp add (per-użytkownik, nie trafia do repo):

claude mcp add toolchain \
  --env TOOLCHAIN_MCP_GITLAB_TOKEN=... \
  --env TOOLCHAIN_MCP_JIRA_USERNAME=... --env TOOLCHAIN_MCP_JIRA_PASSWORD=... \
  --env TOOLCHAIN_MCP_REDMINE_API_KEY=... \
  --env TOOLCHAIN_MCP_MM_TOKEN=... --env TOOLCHAIN_MCP_MM_TEAM=myteam \
  --env TOOLCHAIN_MCP_HARBOR_USER=... --env TOOLCHAIN_MCP_HARBOR_PASSWORD=... \
  -- node /ABSOLUTNA/SCIEZKA/DO/toolchain-mcp/dist/index.js

Podaj tylko zmienne serwisów, z których faktycznie korzystasz — pominięty serwis po prostu nie zarejestruje swoich toolí.

Wariant B — .mcp.json (scope project, commitowalny bez sekretów): skopiuj .mcp.json.example do .mcp.json, popraw ścieżkę do dist/index.js. Wartości ${TOOLCHAIN_MCP_*} ekspandują się z env Twojej powłoki w momencie startu Claude Code — same sekrety zostają w Twoim ~/.secrets/.env, nie w repo.

Read-only mode

TOOLCHAIN_MCP_READ_ONLY=1 — write-toole (gitlab_reply_mr_discussion, jira_add_comment, redmine_add_note, mm_post_message) w ogóle nie są rejestrowane w serwerze (twardy wycinacz, nie tylko hint w opisie). Włącz gdy chcesz podpiąć serwer koledze/agentowi bez ryzyka przypadkowego posta czy komentarza.

TLS intranetu

Certyfikaty serwisów wewnętrznych bywają self-signed. Trzy sposoby obsługi, od najbezpieczniejszego:

  1. NODE_EXTRA_CA_CERTS=/sciezka/do/ca.pem — standardowa zmienna Node, dorzuca CA globalnie do procesu.

  2. TOOLCHAIN_MCP_CA_FILE=/sciezka/do/ca.pem — analogiczne, tylko dla dispatcherów HTTP tego serwera.

  3. TOOLCHAIN_MCP_<SVC>_INSECURE_TLS=1 (np. TOOLCHAIN_MCP_JIRA_INSECURE_TLS=1) — wyłącza weryfikację TLS, ale tylko dla wskazanego serwisu.

Nigdy nie używaj globalnego NODE_TLS_REJECT_UNAUTHORIZED=0 — wyłącza weryfikację TLS dla całego procesu Node, łącznie z ruchem do serwisów, których to nie dotyczy.

Smoke test

Po npm run build, z ustawionym env (i VPN dla serwisów w sieci wewnętrznej):

npm run smoke

Odpytuje po jednym lekkim, nieszkodliwym endpoincie na serwis (/version, /myself, /users/current.json, /users/me, /projects?page_size=1). Serwis bez ustawionych zmiennych → SKIP (brak env), nie liczy się jako błąd. Exit code 0 gdy wszystkie skonfigurowane serwisy odpowiadają OK, 1 gdy którykolwiek zwrócił błąd — użyteczne po każdej rotacji tokenu, żeby sprawdzić od razu wszystkie na raz zamiast czekać na pierwszy failing tool call. Uruchamiany ręcznie, nie w CI (wymaga żywej sieci wewnętrznej).

Troubleshooting

  • Jira 401 / komunikat o degraded mode — connector Jira po pierwszym 401/403 przechodzi w tryb degraded do końca życia procesu (ochrona przed lockoutem konta) i przestaje wysyłać requesty. Jeśli komunikat wspomina CAPTCHA (X-Authentication-Denied-Reason: CAPTCHA_CHALLENGE) — zaloguj się raz ręcznie w przeglądarce na jira.example.com, rozwiąż CAPTCHĘ, potem zrestartuj serwer MCP. Jeśli to zwykłe 401 — sprawdź czy hasło w TOOLCHAIN_MCP_JIRA_PASSWORD nie jest przeterminowane po rotacji.

  • Redmine 401 — albo TOOLCHAIN_MCP_REDMINE_API_KEY jest nieprawidłowy/wygasł (wygeneruj nowy w Moje konto), albo REST API jest wyłączone dla Twojego konta po stronie admina (poproś o włączenie).

  • Mattermost 401 — najczęściej wygasł MMAUTHTOKEN (sesja z ciasteczka ma ograniczony czas życia). Wyciągnij nowy token wg instrukcji wyżej albo poproś admina o bot account, żeby problem zniknął na stałe.

  • 401 z Jiry a toole xref_* dalej strzelająxref_* robi własne wywołania HTTP i NIE podlega degraded-mode connectora Jira (świadoma odchyłka — patrz komentarz w src/xref.ts). Przy nieaktualnym haśle nie wołaj xref_ticket w pętli (ryzyko lockoutu konta) — najpierw popraw TOOLCHAIN_MCP_JIRA_PASSWORD.

Related MCP Connectors

Related MCP Servers