mcp-dockhand
MCP Dockhand
Dockhand API를 MCP 도구로 노출하는 MCP(Model Context Protocol) 서버입니다. AI 어시스턴트를 통해 Docker 인프라 전체를 관리하세요.
API 적용 범위: 범위 내 Dockhand 엔드포인트의 88.7%(282/318)에 MCP 도구가 제공됩니다 — 영역별 전체 자동 업데이트 내역은 docs/coverage.md를 참조하세요.
Dockhand는 Hawser 에이전트를 통해 여러 Docker 호스트에 연결하는 Docker 관리 서버입니다. 이 MCP 서버는 모든 Dockhand 기능에 대한 완전한 프로그래밍 방식 액세스를 제공합니다.
기능
280개 이상의 MCP 도구 — Dockhand API 전체를 포괄합니다. 정확한 자동 업데이트 적용 범위는
docs/coverage.md를 참조하세요.스트리밍 가능한 HTTP 전송(MCP Spec 2025-03-26) — Docker 컨테이너 호스팅용
세션 기반 인증 — 401 발생 시 자동 재로그인
SSE 지원 — 배포 작업(start, stop, down, restart)용
환경 필터 — 모든 컨테이너/스택/이미지/네트워크/볼륨 엔드포인트에 적용
Docker 지원 — 멀티 스테이지 빌드, 비루트 사용자, 헬스 체크 포함
Related MCP server: dockhand-mcp
빠른 시작
Docker(권장)
docker run -d \
--name mcp-dockhand \
-p 8080:8080 \
-e DOCKHAND_URL=https://your-dockhand-server.com \
-e DOCKHAND_USERNAME=your-username \
-e DOCKHAND_PASSWORD=your-password \
ghcr.io/strausmann/mcp-dockhand:latestDocker Compose
services:
mcp-dockhand:
image: ghcr.io/strausmann/mcp-dockhand:latest
container_name: mcp-dockhand
restart: unless-stopped
ports:
- "8080:8080"
environment:
- DOCKHAND_URL=https://your-dockhand-server.com
- DOCKHAND_USERNAME=your-username
- DOCKHAND_PASSWORD=your-password소스에서 빌드
git clone https://github.com/strausmann/mcp-dockhand.git
cd mcp-dockhand
npm install
npm run build
DOCKHAND_URL=https://your-server.com DOCKHAND_USERNAME=admin DOCKHAND_PASSWORD=secret npm start구성
변수 | 필수 | 기본값 | 설명 |
| 예 | - | Dockhand 서버 URL |
| 예 | - | Dockhand 사용자 이름 |
| 예 | - | Dockhand 비밀번호 |
| 아니요 |
| MCP 서버 포트 |
| 아니요 |
| 유지된 MCP 세션이 만료되기 전 비활성 제한 시간 |
| 아니요 |
| 만료된 세션 제거 간격(세션 TTL로 제한됨) |
| 아니요 |
| 최대 유지 세션 수. |
| 아니요 |
| 수신 주소. 게시된 Docker 포트( |
| 아니요 | (설정 안 됨 — Host 검사 비활성화) |
|
| 아니요 | (설정 안 됨 — Origin 검사 비활성화) |
|
| 아니요 | (설정 안 됨 — 엔드포인트 무인증) | 모든 |
| 아니요 |
|
|
| 아니요 | (비어 있음) |
|
전송 보안
/mcp는 기본적으로 0.0.0.0:8080에 바인딩되며(MCP_HOST 참조), MCP_ALLOWED_HOSTS, MCP_ALLOWED_ORIGINS, MCP_AUTH_TOKEN 중 어느 것도 설정하지 않은 기본 상태에서는 Host/Origin 검사 없이 모든 요청을 인증 없이 수락합니다. 이는 mcp-dockhand가 항상 가져온 동작이며, 의도적으로 기본값으로 유지됩니다. 기본적으로 검사를 활성화하면 localhost/127.0.0.1(LAN IP, 리버스 프록시, Docker 네트워크 별칭)로 서버에 접근하지 않는 모든 클라이언트의 요청이 거부되어 기존 배포가 일상적인 업데이트에서 중단될 수 있습니다.
이 기능을 켜야 합니다 — /mcp가 자신의 머신 루프백 인터페이스 외부에서 접근 가능해지면 말입니다. 서버는 하나의 Dockhand 관리자 자격 증명을 보유하며 모든 도구 호출이 해당 신원으로 수행되므로, MCP 세션을 열 수 있는 사람은 누구나 Docker를 제어할 수 있습니다(컨테이너 exec, create_container를 통한 호스트 바인드 마운트, 파일 읽기/쓰기, 저장된 git 자격 증명). 보호가 구성되지 않은 경우 서버는 시작 시 [security] WARNING을 기록하여 알림을 제공합니다. 세 가지 독립적인 옵트인 계층을 사용할 수 있습니다:
호스트 허용 목록 (
MCP_ALLOWED_HOSTS). 비어 있지 않은 값으로 설정하면/mcp에 대한 모든 요청(POST,GET,DELETE)은Host헤더가 허용 목록과 일치하지 않는 한403으로 거부됩니다. 이는 DNS 리바인딩에 대한 1차 방어선입니다. 악성 웹 페이지는 허용 목록이 수락하는 Host 값으로 운영자의 브라우저가 서버에 도달하게 만들 수 없습니다. 클라이언트가 실제로 서버에 도달하는 방식에 맞게 설정하세요. 문서화된 로컬 설정에서는localhost:8080/127.0.0.1:8080, 또는localhost를 통하지 않고 주소로 직접 연결하는 경우(아래 mcp-proxy 원격 서버 설정 포함) 클라이언트가 보내는 정확한host:port(예:100.100.50.40:8222)로 설정하세요. 이 설정을 잘못하면 모든 요청이403 Invalid Host header로 거부됩니다. 메시지를 확인하면 서버가 본 Host 값을 알 수 있습니다.출처 허용 목록 (
MCP_ALLOWED_ORIGINS). 설정하면 목록에 없는Origin헤더를 보내는 모든 요청은403으로 거부됩니다.Origin헤더가 없으면 항상 통과합니다(SDK 자체 MCP 클라이언트와 대부분의 비브라우저 도구는 이를 보내지 않으므로). 따라서 브라우저 기반 클라이언트가/mcp에 직접 통신하는 경우에만 유용합니다. 실제로 DNS 리바인딩을 막는 것은 위의 Host 허용 목록입니다.Bearer 토큰 (
MCP_AUTH_TOKEN). 설정하면 모든/mcp요청은Authorization: Bearer <token>을 포함해야 하며, 그렇지 않으면401로 거부됩니다. 비교는 상수 시간에 수행됩니다. 운영자 자신의 머신 이상에서 접근 가능한 모든 배포에 대해 Host 허용 목록과 함께 권장됩니다.
# .env — recommended configuration once /mcp is reachable beyond loopback
MCP_ALLOWED_HOSTS=dock-mcp.internal.example.com
# or, connecting directly by address instead of a hostname:
#MCP_ALLOWED_HOSTS=100.100.50.40:8222
MCP_AUTH_TOKEN=<a long random secret, e.g. `openssl rand -hex 32`>CrowdSec으로 서버 보안
서버는 모든 요청(거부된 요청 포함)에 대해 nginx 형식의 액세스 줄을 stdout으로 기록하고, 구조화된 애플리케이션 로그는 stderr로 보냅니다. CrowdSec은 기본 제공 컬렉션으로 액세스 줄을 구문 분석하므로 사용자 지정 파서가 필요하지 않습니다.
CrowdSec 에이전트를 실행 중인 호스트에 수집 파일을 추가하세요:
source: docker
container_name:
- mcp-dockhand
labels:
type: docker
program: nginx-mcp두 라벨 모두 필수이며, 어느 하나를 잊어도 뚜렷하게 실패하지 않습니다.
type: docker는 Docker의 JSON 봉투를 푸는 crowdsecurity/docker-logs를 활성화합니다.
program: nginx-mcp는 program이 nginx로 시작하는 항목과 일치하는 crowdsecurity/nginx-logs를
활성화합니다. -mcp 접미사는 이 소스를 다른 nginx 소스와 구별되게 합니다. 라벨 하나가 없으면
체인은 그저 아무것도 생성하지 않으며, 이를 보고하는 것도 없습니다.
연결이 완료되면 기본 제공 시나리오가 적용됩니다:
시나리오 | 여기서의 의미 |
|
|
| 사용자 에이전트를 바꿔가며 보내는 요청 홍수 |
403도 주시할 가치가 있습니다. 요청이 MCP_ALLOWED_HOSTS 또는 MCP_ALLOWED_ORIGINS 검사를
통과하지 못했다는 뜻이며, 이것이 여기서 DNS 리바인딩 시도가 보이는 모습입니다.
기본 제공 401 시나리오는
POST만 집계합니다. 해당 필터는evt.Parsed.verb == 'POST'— 하나의 리터럴이지 목록이 아닙니다. 이 서버는/mcp에서POST,GET,DELETE를 제공하며, bearer 검사는 세 가지 모두보다 앞서 실행됩니다. 따라서GET /mcp또는DELETE /mcp에 잘못된 토큰을 보내면POST와 똑같이401을 반환하지만LePresidente/http-generic-401-bf는 이를 절대 집계하지 않습니다.GET /mcp로MCP_AUTH_TOKEN을 추측하는 사람은 이 시나리오에 보이지 않습니다.이것은 이 시나리오를 사용하는 모든 nginx 배포에 공통된 업스트림 시나리오의 속성입니다. 이 서버의 로그 형식으로 고칠 수 있는 문제가 아닙니다. 이를 해결하려면
verb필터를 제거하거나 이 서버가 응답하는 세 가지 메서드와 일치하는 로컬 시나리오를 추가하세요. 그 전까지는 위 표의 행을 "POST/mcp에 대한 반복된401"로 취급하세요.
이 기능을 활성화하기 전에
TRUSTED_PROXIES를 설정하세요. 리버스 프록시 뒤에서는 모든 요청이 프록시의 주소에서 도착합니다.TRUSTED_PROXIES가 없으면 그 주소가 기록되므로 CrowdSec이 내리는 첫 번째 차단이 프록시를 제거하고, 그 뒤의 모든 사용자도 함께 제거합니다. 프록시가 통신하는 주소나 서브넷으로 설정하세요.이 설정은 반대 방향에서도 동일하게 신중하게 적용됩니다. 전달 헤더는 해당 목록의 피어에서만 신뢰됩니다. 무조건 신뢰하면 직접 호출자가 임의의 제3자를 지목하여 그 제3자가 차단되도록 할 수 있습니다.
예상되는 부작용 하나: 구조화된 JSON 줄은 컨테이너의 로그 스트림을 공유하고 동일한
program 라벨을 가지므로 nginx 패턴에 맞지 않아 cscli metrics에서 unparsed로 집계됩니다.
이는 오류가 아니라 잡음입니다. 경고도, 결정도 없습니다.
MCP 클라이언트 구성
Claude Desktop / Claude Code
MCP 설정에 추가하세요:
{
"mcpServers": {
"dockhand": {
"url": "http://localhost:8080/mcp"
}
}
}서버가 bearer 토큰을 강제하는 경우 (
MCP_AUTH_TOKEN설정 — 전송 보안 참조), 클라이언트는 이를Authorization헤더로 보내야 하며, 그렇지 않으면 모든 요청이401로 거부됩니다. Claude Code의.mcp.json에headers블록을 추가하세요. 토큰이 (종종 버전 관리되는) 구성 파일에 절대 저장되지 않도록 환경 변수를 참조하세요:{ "mcpServers": { "dockhand": { "type": "http", "url": "http://your-server:8080/mcp", "headers": { "Authorization": "Bearer ${DOCKHAND_MCP_TOKEN}" } } } }토큰은 암호화된 전송을 통해서만 보내세요. 공유 네트워크에서 평문
http://로 보내는 bearer는 도청될 수 있습니다. 리버스 프록시에서 TLS를 종료하거나 WireGuard/Tailscale/VPN 링크를 통해 서버에 도달하세요(그러면 앱 계층 HTTP가 터널에 의해 암호화됩니다).Claude Code가 실행되는 환경에서
DOCKHAND_MCP_TOKEN을 내보내세요(예: 시작 전에source하는 gitignored.env에서). 연결하는Host/host:port는, 해당 허용 목록이 설정된 경우 서버의MCP_ALLOWED_HOSTS에도 있어야 합니다. Claude Desktop의 경우(기본 구성에는headers필드가 없음) 아래의 mcp-proxy 해결 방법을 통해 토큰을 전달하세요. mcp-proxy는 자체 환경/인자를 통해Authorization헤더를 전달합니다.
원격 서버 사용 시 Claude Desktop (mcp-proxy)
Claude Desktop은 위의 기본 "url" 구성을 사용하여 원격 mcp-dockhand 서버(localhost가
아닌)에 연결하지 못할 수 있습니다. 엔드포인트 자체는 연결 가능하지만요. 증상은 Claude Desktop에서
일반적인 "not a valid MCP server" 오류가 발생하는 반면, 동일한 URL에 대한 일반 브라우저/curl
요청은 {"error":"Invalid or missing session ID"}를 올바르게 반환하는 것입니다. 이는 원격
Streamable HTTP 서버를 사용하는 Claude Desktop의 알려진 제한 사항이지 mcp-dockhand 버그가
아닙니다.
해결 방법: 연결을 mcp-proxy로 감싸세요. 이 도구는 Streamable HTTP를 stdio로 변환하며, Claude Desktop이 안정적으로 처리하는 전송 방식입니다:
{
"mcpServers": {
"dockhand": {
"command": "/path/to/mcp-proxy",
"args": ["--transport", "streamablehttp", "http://your-server:8080/mcp"]
}
}
}모든 도구는 프록시를 통해 정상적으로 로드되고 작동합니다. 이 문제를 보고하고 해결 방법을 공유해 주신 @deadrubberboy 님께 감사드립니다 (#90).
도구 참조
컨테이너 (27개 도구)
도구 | 설명 |
| 환경의 모든 컨테이너 나열 |
| 컨테이너 세부 정보 가져오기 |
| Docker inspect (전체 세부 정보) |
| 컨테이너 로그 가져오기 |
| 리소스 사용량 통계 가져오기 |
| 실행 중인 프로세스 가져오기 |
| 컨테이너 시작 |
| 컨테이너 중지 |
| 컨테이너 다시 시작 |
| 컨테이너 일시 중지 |
| 컨테이너 일시 중지 해제 |
| 컨테이너 이름 바꾸기 |
| 컨테이너 설정 업데이트 |
| 새 컨테이너 생성 |
| 사용 가능한 셸 나열 |
| 터미널 exec 세션 생성(execId + WS connectionInfo) — 일회성 명령을 실행하거나 출력을 반환하지 않음 — Dockhand API에는 그러한 엔드포인트가 없음 |
| 컨테이너 내부 파일 탐색 |
| 컨테이너에서 파일 읽기 |
| 컨테이너에 빈 파일 또는 디렉터리 생성(내용 없음 — 그 용도로는 |
| 컨테이너에서 파일 삭제 |
| 컨테이너에서 파일 이름 바꾸기 |
| 파일 권한 변경 |
| 이미지 업데이트 확인 |
| 보류 중인 업데이트 가져오기 |
| 컨테이너 일괄 업데이트 |
| 컨테이너, 이미지, 볼륨, 네트워크 또는 스택 전반에 걸쳐 대량 수명 주기 작업(시작/중지/다시 시작/제거 등) 실행 |
| 컨테이너 디스크 크기 가져오기 |
| 집계된 통계 가져오기 |
스택 (21개 도구)
도구 | 설명 |
| 모든 스택 나열 |
| 스택 세부 정보 가져오기 |
| 스택 생성 및 선택적으로 배포 |
| 스택 시작 (compose up) |
| 스택 중지 (compose stop) |
| 스택 다시 시작 |
| 스택 내리기 (compose down) |
| 스택 삭제 |
| compose 파일 읽기 |
| compose 파일 업데이트 |
| 환경 변수 읽기 |
| 환경 변수 업데이트(기본적으로 병합 — 부분 업데이트에 안전하며, 모두 덮어쓰려면 |
| 원시 .env 파일 읽기 |
| 환경 변수 검증 |
| 파일 시스템에서 스택 검색 |
| 추적되지 않는 스택 채택 |
| 스택을 새 경로로 이동 |
| 스택 소스 가져오기 |
| 기본 경로 가져오기 |
| 경로 제안 가져오기 |
| 스택 경로 검증 |
이미지 (9개 도구)
도구 | 설명 |
| 모든 이미지 나열 |
| 이미지 세부 정보 가져오기 |
| 이미지 레이어 기록 가져오기 |
| 이미지에 태그 지정 |
| 이미지 제거 |
| 이미지 가져오기 |
| 이미지 푸시 |
| 취약점 검사 (Trivy/Grype) |
| 이미지를 tarball로 내보내기 |
환경 (18개 도구)
도구 | 설명 |
| 모든 환경 나열 |
| 환경 세부 정보 가져오기 |
| 환경 생성 |
| 환경 업데이트 |
| 환경 삭제 |
| 연결 테스트 |
| 저장하지 않고 테스트 |
| 소켓 자동 감지 |
| 시간대 가져오기 |
| 시간대 설정 |
| 업데이트 확인 설정 가져오기 |
| 업데이트 확인 설정 지정 |
| 이미지 정리 설정 가져오기 |
| 이미지 정리 설정 지정 |
| 알림 나열 |
| 알림 생성 |
| 알림 가져오기 |
| 알림 삭제 |
네트워크 (7개 도구)
도구 | 설명 |
| 모든 네트워크 나열 |
| 네트워크 세부 정보 가져오기 |
| 네트워크 검사 |
| 네트워크 생성 |
| 네트워크 제거 |
| 컨테이너 연결 |
| 컨테이너 연결 해제 |
볼륨 (9개 도구)
도구 | 설명 |
| 모든 볼륨 나열 |
| 볼륨 세부 정보 가져오기 |
| 볼륨 검사 |
| 볼륨의 파일 탐색 |
| 볼륨에서 파일 읽기 |
| 탐색 세션 해제 |
| 볼륨 복제 |
| 볼륨 내보내기 |
| 볼륨 제거 (파괴적 작업) |
Git 스택 (15개 도구)
도구 | 설명 |
| Git 기반 스택 나열 |
| Git 스택 세부 정보 가져오기 |
| Git 스택 배포 (SSE) |
| 원격 저장소와 동기화 |
| Git 연결 테스트 |
| 환경 파일 가져오기 |
| 웹훅 트리거 |
| 웹훅 세부 정보 가져오기 |
| Git 자격 증명 나열 |
| Git 자격 증명 생성 |
| 자격 증명 세부 정보 가져오기 |
| 자격 증명 업데이트 |
| 자격 증명 삭제 |
| Git 저장소 나열 |
| 저장소 구성 생성 |
대시보드 및 활동 (8개 도구)
도구 | 설명 |
| 대시보드 통계 가져오기 |
| 표시 기본 설정 가져오기 |
| 표시 기본 설정 지정 |
| 활동 피드 가져오기 |
| 컨테이너 활동 |
| 활동 이벤트 |
| 활동 통계 |
| 컨테이너의 병합된 로그 |
인증 및 Hawser (12개 도구)
도구 | 설명 |
| 세션 상태 확인 |
| 인증 제공자 나열 |
| 인증 설정 가져오기 |
| OIDC 제공자 생성 |
| OIDC 제공자 가져오기 |
| OIDC 제공자 테스트 |
| LDAP 제공자 생성 |
| LDAP 제공자 가져오기 |
| LDAP 제공자 테스트 |
| Hawser 토큰 나열 |
| Hawser 토큰 생성 |
| Hawser 토큰 해지 |
감사 (4개 도구)
도구 | 설명 |
| 감사 로그 가져오기 |
| 감사 이벤트 유형 가져오기 |
| 사용자별 감사 데이터 |
| 감사 로그 내보내기 |
알림 (8개 도구)
도구 | 설명 |
| 알림 나열 |
| 알림 생성 |
| 알림 가져오기 |
| 알림 업데이트 |
| 알림 삭제 |
| 알림 테스트 |
| 저장하지 않고 테스트 |
| 지정된 이벤트 유형 + 페이로드에 대한 실제 테스트 이벤트 트리거 |
레지스트리 (10개 도구)
도구 | 설명 |
| 레지스트리 나열 |
| 레지스트리 추가 |
| 레지스트리 세부 정보 가져오기 |
| 레지스트리 업데이트 |
| 레지스트리 삭제 |
| 기본값으로 설정 |
| 레지스트리 검색 |
| 카탈로그 가져오기 |
| 레지스트리에서 이미지 가져오기 |
| 이미지 태그 가져오기 |
시스템 및 설정 (19개 도구)
도구 | 설명 |
| 서버 상태 |
| 데이터베이스 상태 |
| 호스트 정보 |
| 시스템 정보 |
| 디스크 사용량 |
| 시스템 파일 나열 |
| 시스템 파일 읽기 |
| 변경 로그 |
| 종속성 |
| 일반 설정 |
| 설정 업데이트 |
| 테마 설정 |
| 테마 업데이트 |
| 스캐너 설정 |
| 스캐너 업데이트 |
| 라이선스 정보 |
| 이름과 키로 라이선스 활성화 |
| Prometheus 메트릭 |
| 모든 리소스 정리 |
사용자, 역할 및 기본 설정 (20개 도구)
도구 | 설명 |
| 사용자 나열 |
| 사용자 생성 |
| 사용자 세부 정보 가져오기 |
| 사용자 업데이트 |
| 사용자 삭제 |
| MFA 상태 |
| MFA 활성화 |
| MFA 비활성화 |
| 사용자 역할 가져오기 |
| 사용자에게 역할 하나 할당 (일괄 교체 없음) |
| 사용자에게서 역할 하나 해제 |
| 역할 나열 |
| 이름 + 권한 객체로 역할 생성 |
| 역할 가져오기 |
| 역할 업데이트 |
| 역할 삭제 |
| 자신의 프로필 가져오기 |
| 자신의 프로필 업데이트 |
| 즐겨찾기 가져오기 |
| 즐겨찾기 설정 |
| 구성 세트 나열 |
일정 (9개 도구)
도구 | 설명 |
| 일정 나열 |
| 설정 가져오기 |
| 설정 업데이트 |
| 실행 기록 |
| 실행 세부 정보 |
| 일정 가져오기 |
| 즉시 실행 |
| 활성화/비활성화 |
| 시스템 일정 전환 |
자동 업데이트 (3개 도구)
도구 | 설명 |
| 모든 자동 업데이트 설정 가져오기 |
| 컨테이너 자동 업데이트 가져오기 |
| 자동 업데이트 정책 설정 |
자가 진단 / 메타 도구 (6개 도구)
이 MCP 서버 자체에 대한 진단으로, 위의 Dockhand API 도구와는 구별됩니다 —
클라이언트나 운영자가 "Dockhand가 정상인가?"가 아니라 "이 서버가 정상이고 올바르게 구성되었는가?"라고
묻는 경우에 유용합니다. 이 여섯 개 도구는 모두 입력 인수를 받지 않으며, 위 표의 도구들이 그런 것처럼
단일 Dockhand 엔드포인트를 래핑하지 않습니다 (get_tool_manifest와
get_runtime_stats는 Dockhand 엔드포인트를 전혀 호출하지 않습니다) — src/tools/meta.ts 참조.
도구 | 설명 |
| 이 서버 자체의 버전, git SHA, 빌드 날짜, 가동 시간, MCP 프로토콜 버전, 그리고 연결된 Dockhand URL/서버 버전 |
| 이 서버의 실행 중인 버전을 최신 GitHub 릴리스와 비교 (TTL 캐시됨) |
| 등록된 모든 도구를 해당 Dockhand |
| 종단 간 진단: Dockhand 연결 가능성, 자격 증명 유효성, 환경별 실시간 연결 가능성 확인 ( |
| 필수 |
| 이 서버의 프로세스 내 카운터: 총/도구별 호출 및 오류 횟수, 가동 시간, 마지막 오류의 도구/메시지/타임스탬프 |
참고:
check_for_update는 api.github.com(GitHub의 releases API)에 대한 아웃바운드 네트워크 액세스가 필요합니다. 해당 API에 도달할 수 없으면 실패하는 대신 updateAvailable: null로 저하됩니다.
어떤 메타 도구도 비밀 값을 노출하지 않습니다. validate_config는 필수 환경 변수가 존재하는지(부울)와 인증되는지(부울 + 원시 HTTP 상태 코드, 예: 200/401)만 보고하며 자격 증명 값 자체는 절대 보고하지 않습니다. self_check도 동일한 방식으로 인증 유효성을 보고합니다. get_runtime_stats의 lastError는 도구 이름, 오류 메시지, 타임스탬프만 담고 있으며 호출 인수나 응답 페이로드는 절대 담지 않습니다. 단, 해당 오류 메시지가 완전히 불투명한 것은 아닙니다. 실패한 Dockhand API 호출의 경우 업스트림 HTTP 상태와 응답 본문의 일부가 포함될 수 있으며(DockhandClient 자체의 Dockhand API error: ... returned <status>: <body> 메시지를 통해) 이후 get_runtime_stats를 호출하는 모든 MCP 클라이언트에 반향됩니다. 반드시 원래 오류를 발생시킨 클라이언트일 필요는 없습니다. 요청 본문이나 자격 증명 값은 절대 포함되지 않으며, 저장되기 전에 500자로 잘리므로(줄임표 표시 포함) 과도하게 큰 업스트림 응답이 통째로 반향되지 않습니다.
중요 참고 사항
update_stack_env — 병합 vs 교체 의미론
Dockhand REST 엔드포인트 PUT /api/stacks/{name}/env는 **교체 의미론(replace-semantics)**을 가집니다. 변수의 부분 목록을 제출하면 스택의 다른 모든 변수가 조용히 삭제됩니다. 단일 변수 업데이트가 다른 모든 것을 삭제해 버릴 수 있습니다.
우발적인 데이터 손실을 방지하기 위해 이 MCP 도구는 기본적으로 **병합 모드(merge mode)**를 사용합니다.
GET /api/stacks/{name}/env를 통해 현재 변수 목록을 가져옵니다.키별로 들어오는 변수를 병합합니다(키 충돌 시 새 값이 기존 값을 덮어씁니다).
병합된 전체 목록을
PUT으로 다시 작성합니다.
# Safe partial update — only MY_VAR changes, all others preserved
update_stack_env(environmentId=1, name="my-stack", variables=[{key: "MY_VAR", value: "new"}])
# Explicit full replacement — all other variables are deleted
update_stack_env(environmentId=1, name="my-stack", variables=[...], mode="replace")전체 변수 집합을 의도적으로 교체하려는 경우에만 mode="replace"를 사용하세요.
Environment ID 필수
대부분의 Docker 리소스 엔드포인트(컨테이너, 스택, 이미지, 네트워크, 볼륨)는 environmentId 매개변수를 필요로 합니다. 이는 Dockhand API의 ?env=<id> 쿼리 매개변수에 매핑됩니다. 이 값이 없으면 엔드포인트는 빈 배열을 반환합니다.
SSE 응답
배포 작업(start, stop, down, restart, restart가 포함된 compose update)은 Server-Sent Events를 반환합니다. MCP 서버는 이를 자동으로 파싱하여 최종 결과를 반환합니다.
인증
서버는 세션 기반 쿠키 인증을 사용합니다. 다음과 같이 자동으로 처리합니다.
첫 번째 요청 시 로그인
세션 쿠키를 메모리에 저장
401 응답 시 재인증
세션 타임아웃(24시간) 처리
문제 해결
LOG_LEVEL=debug로 시작하세요. 그러면 모든 Dockhand 요청이 엔드포인트, 상태 코드, 기간과 함께 표시되며, 단일 호출의 모든 줄은 하나의 call 식별자를 공유합니다. grep으로 검색하면 전체 시퀀스를 얻을 수 있습니다. req 식별자는 해당 줄들을 시작한 액세스 줄에 연결하고, sid는 한 클라이언트가 전체 세션 동안 수행한 모든 작업을 포괄합니다. 클라이언트를 통한 요청의 경우 ms는 전체 요청 기간입니다. 응답 본문이 읽히는 시간까지 포함하며 응답 헤더가 도착할 때까지의 시간만이 아닙니다. 따라서 느리거나 중단된 스트리밍 응답(예: 배포의 SSE 출력)이 실제로 얼마나 소요되었는지 반영합니다. 그리고 bytes는 실제로 읽힌 본문의 크기입니다. (로그인 및 self-check 프로브는 클라이언트를 부트스트랩하며 이를 통해 라우팅할 수 없으므로, 해당 줄은 bytes 필드 없이 헤더 도달 시간까지만 기록합니다.) 실패한 Dockhand 요청은 추가로 errType을 담은 warn 줄을 기록합니다. errType은 예외 이름(예: TimeoutError, TypeError)으로, 자유 텍스트가 아닌 제한된 어휘이므로 오류 유형별로 실패를 필터링할 수 있습니다. 이 warn 줄은 요청 자체가 응답 도착 전에 실패한 경우와 응답 본문 읽기가 중간에 실패한 경우(예: SSE 스트림이 중간에 타임아웃에 도달한 경우) 모두 발생하며, 어느 쪽이든 ms는 실패까지 걸린 시간을 반영합니다.
개발
# Install dependencies
npm install
# Type check
npm run typecheck
# Build
npm run build
# Run in development mode
DOCKHAND_URL=https://your-server.com \
DOCKHAND_USERNAME=admin \
DOCKHAND_PASSWORD=secret \
npm run dev린팅
npm run lint는 두 가지 규칙(no-unused-vars 및 no-explicit-any)으로 src/와 tests/를 린트합니다. typescript-eslint는 고정된 typescript@^7.0.2 컴파일러를 지원하지 않기 때문에 — 피어 경고가 아니라 TS 7.0에서 하드 throw합니다. typescript-eslint#10940 참조 — 린트는 고정된 TypeScript 5가 들어 있는 일회용 node:22 컨테이너 내부에서 실행됩니다(언어는 TS 5/6/7에서 동일하며 컴파일러만 다릅니다). src/, tests/ 및 eslint.config.js를 읽기 전용으로 마운트하므로 실행하려면 Docker가 필요합니다. 동일한 스크립트가 CI에서 하드 게이트로 실행됩니다. 사용되지 않는 import/로컬 변수는 추가로 TS 7에서 tsc가 기본적으로 잡아냅니다(tsconfig.tests.json의 noUnusedLocals/noUnusedParameters, npm run typecheck:tests를 통해).
라이선스
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceExposes over 130 Dockhand API endpoints as tools to manage Docker infrastructure through AI assistants. It enables comprehensive control over containers, stacks, networks, and volumes across multiple environments and hosts.29MIT
- AlicenseNot gradedqualityFmaintenanceExposes the Dockhand Docker management API as tools for LLMs, enabling container, stack, image, volume, and network management via natural language.3MIT
- FlicenseNot gradedqualityCmaintenanceAn MCP server that gives any LLM client the ability to list, inspect, start, stop, and monitor Docker containers on the host machine.1
- FlicenseBqualityBmaintenanceAn MCP server that gives LLMs direct control over a local Docker daemon, enabling container, image, volume, network, and Compose stack management through natural language.234
Related MCP Connectors
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
MCP server exposing the Backtest360 engine API as tools for AI agents.
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/d7eeem/mcp-dockhand'
If you have feedback or need assistance with the MCP directory API, please join our Discord server