mcpstead
mcpstead
MCP 게이트웨이
다수의 업스트림 MCP 서버를 전면에 내세우는 단일 다운스트림 /mcp 엔드포인트입니다. 재연결 기능이 포함된 지속적인 업스트림 연결, 정규화된 이름을 사용하는 도구 레지스트리, 클라이언트 Accept 헤더에 기반한 JSON 또는 SSE 응답, 업스트림별 인증, Prometheus 메트릭을 제공합니다.
설치
# npm (macOS, Linux, WSL)
npm i -g @ahkohd/mcpstead
# homebrew (macOS, Linux)
brew install ahkohd/tap/mcpstead
# cargo
cargo install mcpstead --locked --force
# verify
mcpstead --versionRelated MCP server: Mavryn
빠른 시작
# 1. write a config
mkdir -p ~/.config/mcpstead
cat > ~/.config/mcpstead/config.yaml <<'EOF'
host: 0.0.0.0
port: 8766
mcp:
auth:
mode: none
servers:
- name: example
url: http://127.0.0.1:3000/mcp
protocol: streamable
auth: none
EOF
# 2. run
mcpstead --config ~/.config/mcpstead/config.yaml그런 다음 모든 MCP 클라이언트를 http://127.0.0.1:8766/mcp로 지정하십시오.
Docker
docker build -t mcpstead .
docker run --rm \
-p 8766:8766 \
-v "$PWD/config:/etc/mcpstead:ro" \
mcpsteadDockerfile은 crates.io에서 설치합니다.
HTTP API
메서드 | 경로 | 목적 |
|
| HTTP JSON-RPC를 통한 MCP |
|
| 405 반환 |
|
| 다운스트림 세션 종료 |
|
| 업스트림 상태, 도구 수, 마지막 확인 시간, 재연결 횟수 |
|
| Prometheus 텍스트 형식 |
|
| 재시작 없이 설정 다시 로드 |
MCP 클라이언트 설정
로컬, 인증 없음:
mcpstead:
url: http://127.0.0.1:8766/mcp
tools:
resources: false
prompts: falseBearer 인증:
mcpstead:
url: http://127.0.0.1:8766/mcp
headers:
Authorization: Bearer ${MCPSTEAD_BEARER_TOKEN}
tools:
resources: false
prompts: false도구는 <server>__<tool>과 같은 정규화된 이름으로 나타나므로, 여러 업스트림이 중복된 도구 이름을 사용하더라도 충돌이 발생하지 않습니다.
인증
다운스트림 (클라이언트에서 mcpstead로)
기본값은 인증 없음입니다:
mcp:
auth:
mode: noneBearer 인증:
mcp:
auth:
mode: bearer토큰은 환경 변수에서 가져옵니다:
export MCPSTEAD_BEARER_TOKEN='replace-with-strong-secret'
mcpstead --config ~/.config/mcpstead/config.yaml클라이언트는 Authorization: Bearer <token>을 전송합니다. 토큰이 없거나 잘못된 경우 401이 반환됩니다. 설정의 mcp.auth.bearer_token은 시작 시 거부됩니다.
/health 및 /metrics는 인증 모드와 관계없이 열려 있습니다. 이는 토큰을 노출하지 않고 모니터링하기 위함입니다.
업스트림 (mcpstead에서 MCP 서버로)
servers 목록에서 서버별로 설정합니다. 세 가지 모드가 있습니다:
servers:
- name: local
url: http://127.0.0.1:3000/mcp
auth: none
- name: workflow
url: https://workflow.example/mcp-server/http
auth:
type: bearer
token_env: WORKFLOW_TOKEN
- name: custom
url: https://api.example/mcp
headers:
X-API-Key: '${EXAMPLE_KEY}'token_env는 시작 시 및 설정 다시 로드 시 지정된 환경 변수를 확인합니다.
설정
--config <path> 또는 MCPSTEAD_CONFIG 환경 변수로 설정 경로를 지정하십시오.
host: 0.0.0.0
port: 8766
mcp:
auth:
mode: none # none | bearer
session:
idle_ttl_seconds: 3600
gc_interval_seconds: 60
shutdown_grace_seconds: 5
servers:
- name: local
url: http://127.0.0.1:3000/mcp
protocol: streamable # streamable | sse | auto
required: false # if true, gateway won't start without this upstream
auth: none
reconnect:
max_attempts: 0 # 0 = infinite
backoff_base_ms: 1000
backoff_max_ms: 30000
tools:
ttl_seconds: 300
tls_skip_verify: false
quirks:
normalize_sse_events: true
inject_accept_header: 'application/json, text/event-stream'
metrics:
enabled: true
logging:
level: info핫 리로드
mcpstead는 다음 상황에서 재시작 없이 설정을 다시 로드합니다:
SIGHUP (
systemctl reload mcpstead또는kill -HUP <pid>)POST /-/reload(Bearer 모드에서 Bearer 인증으로 제한됨)
핫 리로드 가능 항목:
업스트림 목록
업스트림별 인증, 헤더, quirks, 재연결, 도구, URL, 프로토콜 및 TLS 설정
mcp.auth.mode및MCPSTEAD_BEARER_TOKENmetrics.enabled
재시작 필요 항목:
hostportlogging.levelmcp.session.*
다시 로드는 최선형(best-effort)으로 수행됩니다. 잘못된 설정은 거부되고 무시되며, 실행 중인 설정이 유지됩니다. 로그와 mcpstead_config_reloads_total{result="error"}에서 실패 여부를 확인하십시오.
MCP 세션 설정 키
mcp.session.idle_ttl_seconds- 이 시간(초) 동안 비활성 상태인 세션 제거 (기본값3600)mcp.session.gc_interval_seconds- 유휴 세션 GC 실행 간격 (기본값60)mcp.session.shutdown_grace_seconds- 최대 종료 처리 대기 시간 (기본값5)
업스트림별 설정 키
name- 필수, 도구 접두사로 사용됨url- 필수, MCP 엔드포인트protocol-streamable | sse | auto(기본값auto)required- 업스트림 초기화 실패 시 시작 차단 (기본값false)auth-none,bearer(token_env사용), 또는headers맵reconnect.max_attempts-0= 무제한 (기본값)reconnect.backoff_base_ms/backoff_max_ms- 지수 백오프 범위tools.ttl_seconds- 이 간격 후 캐시된tools/list새로 고침tls_skip_verify- 이 업스트림에 대해 TLS 인증서 확인 비활성화 (기본값false, 신뢰할 수 있는 로컬 네트워크에서만 사용)quirks.normalize_sse_events- 업스트림 SSE 응답에서event:줄 제거quirks.inject_accept_header- 업스트림으로 전송되는 Accept 헤더 재정의
관측 가능성
메트릭
/metrics는 Prometheus 형식의 카운터, 게이지 및 히스토그램을 노출합니다. 레이블 카디널리티는 소수의 제한된 업스트림 및 도구 집합을 가정하며, 도구 호출 시리즈는 (server, tool)로 키가 지정됩니다.
mcpstead_build_info{version="...",rust_version="...",git_sha="..."}
mcpstead_start_time_seconds
mcpstead_uptime_seconds
mcpstead_process_resident_memory_bytes
mcpstead_process_virtual_memory_bytes
mcpstead_process_cpu_seconds_total
mcpstead_process_open_fds
mcpstead_process_max_fds
mcpstead_process_threads
mcpstead_upstream_connected{server="..."}
mcpstead_upstream_tools_count{server="..."}
mcpstead_upstream_reconnects_total{server="..."}
mcpstead_upstream_last_seen_seconds{server="..."}
mcpstead_upstream_initialize_total{server="...",result="success|error"}
mcpstead_upstream_initialize_duration_seconds_bucket{server="...",le="..."}
mcpstead_upstream_health_checks_total{server="...",result="success|failure"}
mcpstead_upstream_reconnect_attempts_total{server="...",result="success|error"}
mcpstead_upstream_backoff_seconds_total{server="..."}
mcpstead_upstream_in_backoff{server="..."}
mcpstead_upstream_current_backoff_seconds{server="..."}
mcpstead_upstream_session_resets_total{server="...",reason="unknown_session|expired|terminated"}
mcpstead_upstream_tools_refresh_total{server="...",result="success|error"}
mcpstead_upstream_tools_refresh_duration_seconds_bucket{server="...",le="..."}
mcpstead_upstream_tools_last_refresh_timestamp_seconds{server="..."}
mcpstead_upstream_bytes_total{server="...",direction="sent|received"}
mcpstead_downstream_sessions_active
mcpstead_downstream_sessions_total
mcpstead_downstream_session_duration_seconds_bucket{le="..."}
mcpstead_downstream_session_terminations_total{reason="..."}
mcpstead_mcp_requests_total{method="...",result="success|error"}
mcpstead_mcp_request_duration_seconds_bucket{method="...",le="..."}
mcpstead_mcp_auth_attempts_total{result="success|failure"}
mcpstead_mcp_auth_failures_total{reason="..."}
mcpstead_config_reloads_total{result="success|error"}
mcpstead_config_last_reload_timestamp_seconds
mcpstead_tool_calls_total{server="...",tool="..."}
mcpstead_tool_call_errors_total{server="...",tool="...",reason="..."}
mcpstead_tool_call_duration_seconds_bucket{server="...",tool="...",le="..."}스크랩 설정
- job_name: mcpstead
metrics_path: /metrics
static_configs:
- targets: ['mcpstead:8766']상태 확인
curl http://127.0.0.1:8766/healthJSON 반환: 업스트림별 연결 상태, 도구 수, 마지막 성공적인 통신 시간, 재연결 횟수, 마지막 오류.
문제 해결
모든 도구 목록이 비어 있음 - 최소 하나 이상의 업스트림이
initialize에 실패했습니다./health에서 서버별 상태를 확인하고, 업스트림 URL, 인증 및 연결 가능 여부를 확인하십시오.간헐적인
SSE parse failed- 업스트림이 mcpstead가 인식하지 못하는 SSE 방식을 전송합니다. 해당 서버에 대해quirks.normalize_sse_events: true를 시도하거나quirks.inject_accept_header: 'application/json'을 설정하여 JSON을 강제하십시오.tools/call이 인증 오류를 반환함 - 업스트림이 Bearer 토큰을 거부했습니다.token_env가 시작 시 올바른 값으로 확인되는지 확인하고, 업스트림에서 예상하는 헤더 이름을 확인하십시오.자체 서명된 업스트림에 대한 TLS 핸드셰이크 오류 - 해당 서버에서
tls_skip_verify: true를 설정하십시오. 신뢰할 수 있는 로컬 네트워크에서만 안전합니다.Bearer 모드에서
/mcp로부터 401 반환 - 클라이언트가Authorization: Bearer <token>을 누락했거나 잘못된 토큰을 전송했습니다.MCPSTEAD_BEARER_TOKEN이 클라이언트가 전송하는 값과 일치하는지 확인하십시오./health에서 업스트림이 반복적으로 빨간색으로 표시됨 -mcpstead_upstream_reconnects_total및mcpstead_upstream_last_seen_seconds를 확인하십시오. 업스트림에 더 긴 복구 시간이 필요한 경우reconnect.backoff_max_ms를 조정하십시오.
This server cannot be deployed
Maintenance
Related MCP Connectors
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
MCP Gateway: wrap any MCP server with cold-start retries, uptime SLA, and per-execution MPP billing.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Authenticated MCP server for ClearPolicy policy and compliance workflows.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA gateway that aggregates multiple MCP servers into a single endpoint, namespacing their tools and forwarding calls, so an agent connects to one MCP to access the entire stack.MIT
- AlicenseNot gradedqualityCmaintenanceCentralized MCP control plane that proxies multiple upstream MCP servers with tool namespacing, filtering, policy enforcement, audit logging, and health checks.5 npmMIT
- FlicenseNot gradedqualityBmaintenanceA configurable MCP gateway that runs multiple Streamable HTTP MCP servers and exposes all their tools through a single endpoint, enabling tool aggregation and routing for MCP clients.1-
- FlicenseNot gradedqualityBmaintenanceA generic MCP gateway that aggregates multiple upstream MCP servers into a single FastMCP endpoint, configured via servers.json with support for tool subsetting, renaming, multi-instance routing, and pluggable authentication.-