
mcp-remote exposed to OS command injection
mcp-remote로컬(stdio) 서버만 지원하는 MCP 클라이언트를 인증 지원과 함께 원격 MCP 서버에 연결해 주는 도구입니다:
참고: 이것은 동작하는 개념 증명(proof-of-concept) 이므로 실험적으로 간주해야 합니다.
지금까지 대부분의 MCP 서버는 stdio 전송 방식을 사용하여 로컬에 설치되었습니다. 여기에는 몇 가지 장점이 있습니다. 클라이언트와 서버 모두 사용자가 실행 권한을 부여했기 때문에 서로를 암묵적으로 신뢰할 수 있습니다. API 키와 같은 비밀 정보는 환경 변수를 사용하여 추가할 수 있으며 머신을 벗어나지 않습니다. 또한 npx와 uvx를 기반으로 구축되어 사용자가 명시적인 설치 단계를 거치지 않아도 되었습니다.
하지만 웹으로 옮길 수 있는 대부분의 소프트웨어가 실제로 웹으로 옮겨진 데는 이유가 있습니다. 단 한 번의 배포로 모든 사용자에게 업데이트를 푸시할 수 있다면 버그를 찾고 수정하며 새 기능을 반복 개발하는 것이 훨씬 쉬워지기 때문입니다.
최신 MCP Authorization 사양이 도입되면서, 이제 사용자 노트북에서 코드를 실행하지 않고도 MCP 서버를 세상과 안전하게 공유할 수 있는 방법이 생겼습니다. 아니, 적어도 널리 쓰이는 MCP _클라이언트_들이 아직 이를 지원한다면 그렇게 할 수 있을 것입니다. 대부분은 stdio 전용이며, HTTP+SSE를 지원하는 클라이언트들조차 아직 필수 OAuth 흐름을 지원하지 않습니다.
바로 여기에 mcp-remote가 필요합니다. 선택한 MCP 클라이언트가 원격 인증 서버를 지원하게 되면 이 도구를 제거하면 됩니다. 그때까지는 이 한 줄짜리 명령을 넣고 원하는 MCP 클라이언트에 맞춰 사용하세요!
가장 널리 쓰이는 MCP 클라이언트(Claude Desktop, Cursor 및 Windsurf)는 모두 다음 구성 형식을 사용합니다:
{
"mcpServers": {
"remote-example": {
"command": "npx",
"args": [
"mcp-remote",
"https://remote.mcp.server/sse"
]
}
}
}
인증을 우회하거나 원격 서버에 대한 모든 요청에 사용자 지정 헤더를 포함하려면 --header CLI 인수를 전달하세요:
{
"mcpServers": {
"remote-example": {
"command": "npx",
"args": [
"mcp-remote",
"https://remote.mcp.server/sse",
"--header",
"Authorization: Bearer ${AUTH_TOKEN}"
],
"env": {
"AUTH_TOKEN": "..."
}
},
}
}
참고: Cursor 및 Claude Desktop(Windows)에는 npx를 호출할 때 args 내부의 공백을 이스케이프하지 못하는 버그가 있어 이러한 값이 망가질 수 있습니다. 다음과 같이 우회할 수 있습니다:
{
// 나머지 구성...
"args": [
"mcp-remote",
"https://remote.mcp.server/sse",
"--header",
"Authorization:${AUTH_HEADER}" // ':' 주위에 공백이 없음에 유의
],
"env": {
"AUTH_HEADER": "Bearer <auth-token>" // env 변수에서는 공백 허용
}
},
npx에서 오류가 발생하면 첫 번째 인수로 -y를 추가하여 mcp-remote 패키지 설치를 자동 승인해 보세요. "command": "npx",
"args": [
"-y"
"mcp-remote",
"https://remote.mcp.server/sse"
]
npx가 항상 최신 버전의 mcp-remote를 확인하도록 하려면 @latest 플래그를 추가하세요: "args": [
"mcp-remote@latest",
"https://remote.mcp.server/sse"
]
mcp-remote가 OAuth 리디렉션을 수신하는 포트(기본값 3334)를 변경하려면 서버 URL 뒤에 추가 인수를 지정하세요. 어떤 포트를 지정하든 해당 포트를 사용할 수 없으면 사용 가능한 포트가 무작위로 선택됩니다. "args": [
"mcp-remote",
"https://remote.mcp.server/sse",
"9696"
]
mcp-remote가 OAuth 콜백 URL로 등록하는 호스트(기본값 localhost)를 변경하려면 --host 플래그를 추가하세요. "args": [
"mcp-remote",
"https://remote.mcp.server/sse",
"--host",
"127.0.0.1"
]
--allow-http 플래그를 추가하세요. 참고: 트래픽을 가로챌 수 없는 보안 사설 네트워크에서만 사용해야 합니다. "args": [
"mcp-remote",
"http://internal-service.vpc/sse",
"--allow-http"
]
--debug 플래그를 추가하세요. 인증 과정, 연결 및 토큰 갱신에 대한 타임스탬프와 상세 정보가 포함된 자세한 로그가 ~/.mcp-auth/{server_hash}_debug.log에 기록됩니다. "args": [
"mcp-remote",
"https://remote.mcp.server/sse",
"--debug"
]
--enable-proxy 플래그를 추가하세요. 활성화하면 mcp-remote는 일반적인 환경 변수(예: HTTP_PROXY, HTTPS_PROXY, NO_PROXY)의 프록시 설정을 사용합니다. "args": [
"mcp-remote",
"https://remote.mcp.server/sse",
"--enable-proxy"
],
"env": {
"HTTPS_PROXY": "http://127.0.0.1:3128",
"NO_PROXY": "localhost,127.0.0.1"
}
--ignore-tool 플래그를 추가하세요. 지정된 패턴과 일치하는 도구가 tools/list 응답에서 필터링되고 tools/call 요청도 차단됩니다. * 와일드카드 패턴을 지원합니다. "args": [
"mcp-remote",
"https://remote.mcp.server/sse",
"--ignore-tool",
"delete*",
"--ignore-tool",
"remove*"
]
서로 다른 패턴을 무시하려면 여러 개의 --ignore-tool 플래그를 지정할 수 있습니다. 예시:
delete* - "delete"로 시작하는 모든 도구를 무시합니다 (예: deleteTask, deleteUser)*account - "account"로 끝나는 모든 도구를 무시합니다 (예: getAccount, updateAccount)exactTool - 정확히 "exactTool"이라는 이름의 도구만 무시합니다30초)을 변경하려면 --auth-timeout 플래그에 초 단위 값을 지정하세요. 서버 측 인증 프로세스에 시간이 오래 걸리는 경우 유용합니다. "args": [
"mcp-remote",
"https://remote.mcp.server/sse",
"--auth-timeout",
"60"
]
MCP Remote는 MCP 서버에 연결할 때 다양한 전송 전략을 지원합니다. 이를 통해 SSE(Server-Sent Events) 또는 HTTP 전송을 사용할지, 어떤 순서로 시도할지 제어할 수 있습니다.
--transport 플래그로 전송 전략을 지정하세요:
npx mcp-remote https://example.remote/server --transport sse-only
사용 가능한 전략:
http-first (기본값): HTTP 전송을 먼저 시도하고, HTTP가 404 오류로 실패하면 SSE로 폴백합니다sse-first: SSE 전송을 먼저 시도하고, SSE가 405 오류로 실패하면 HTTP로 폴백합니다http-only: HTTP 전송만 사용하며, 서버가 이를 지원하지 않으면 실패합니다sse-only: SSE 전송만 사용하며, 서버가 이를 지원하지 않으면 실패합니다MCP Remote는 mcp-remote 기본값을 사용하는 대신 정적 OAuth 클라이언트 메타데이터를 제공하는 것을 지원합니다. 이는 특정 클라이언트/소프트웨어 ID 또는 범위(scope)를 기대하는 OAuth 서버에 연결할 때 유용합니다.
--static-oauth-client-metadata 플래그와 함께 클라이언트 메타데이터를 JSON 문자열 또는 @ 접두사가 붙은 파일 경로로 제공하세요:
npx mcp-remote https://example.remote/server --static-oauth-client-metadata '{ "scope": "space separated scopes" }'
# node readfile을 사용하므로 cwd를 확신할 수 없다면 절대 경로를 사용하는 것이 좋습니다
npx mcp-remote https://example.remote/server --static-oauth-client-metadata '@/Users/username/Library/Application Support/Claude/oauth_client_metadata.json'
사양에 따라 서버는 OAuth 동적 클라이언트 등록을 지원하는 것이 권장되지만 필수는 아닙니다.
이러한 서버의 경우 MCP Remote는 대신 정적 OAuth 클라이언트 정보를 제공하는 것을 지원합니다. 이는 사전 등록된 클라이언트를 요구하는 OAuth 서버에 연결할 때 유용합니다.
--static-oauth-client-info 플래그와 함께 클라이언트 메타데이터를 JSON 문자열 또는 @ 접두사가 붙은 파일 경로로 제공하세요:
export MCP_REMOTE_CLIENT_ID=xxx
export MCP_REMOTE_CLIENT_SECRET=yyy
npx mcp-remote https://example.remote/server --static-oauth-client-info "{ \"client_id\": \"$MCP_REMOTE_CLIENT_ID\", \"client_secret\": \"$MCP_REMOTE_CLIENT_SECRET\" }"
# node readfile을 사용하므로 cwd를 확신할 수 없다면 절대 경로를 사용하는 것이 좋습니다
npx mcp-remote https://example.remote/server --static-oauth-client-info '@/Users/username/Library/Application Support/Claude/oauth_client_info.json'
Claude Desktop에 MCP 서버를 추가하려면 다음 위치에 있는 구성 파일을 편집해야 합니다:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.json아직 존재하지 않는다면 Settings > Developer에서 활성화해야 할 수 있습니다.
구성 파일의 변경 사항을 적용하려면 Claude Desktop을 다시 시작하세요. 다시 시작하면 입력 상자의 오른쪽 하단에 망치 아이콘이 표시되어야 합니다.
공식 문서. 구성 파일은 ~/.cursor/mcp.json에 있습니다.
버전 0.48.0부터 Cursor는 인증이 없는 SSE 서버를 직접 지원합니다. MCP 서버가 공식 MCP OAuth 인증 프로토콜을 사용한다면 여전히 "command" 서버를 추가하고 mcp-remote를 호출해야 합니다.
공식 문서. 구성 파일은 ~/.codeium/windsurf/mcp_config.json에 있습니다.
유효한 OAuth 클라이언트 역할을 포함하여 원격 MCP 서버를 구축하고 배포하는 방법에 대한 지침은 다음 리소스를 참조하세요:
특히 다음을 참조하세요:
agents 프레임워크를 사용하여 McpAgent를 정의하는 방법이러한 서버를 테스트하는 방법에 대한 자세한 내용은 다음도 참조하세요:
공유하고 싶은 리소스를 더 알고 계신가요? 이 Readme에 추가하고 PR을 보내주세요!
~/.mcp-auth 디렉토리 정리mcp-remote는 모든 자격 증명 정보를 ~/.mcp-auth(또는 MCP_REMOTE_CONFIG_DIR이 가리키는 위치)에 저장합니다. 지속적인 문제가 발생한다면 다음을 실행해 보세요:
rm -rf ~/.mcp-auth
그런 다음 MCP 클라이언트를 다시 시작하세요.
설치된 Node 버전이 18 이상인지 확인하세요. Claude Desktop은 다른 곳에 최신 버전이 설치되어 있어도 시스템의 Node 버전을 사용합니다.
claude_desktop_config.json을 수정할 때는 Claude를 완전히 다시 시작하는 것이 도움이 될 수 있습니다.
VPN 뒤에 있으면 문제가 발생할 수 있습니다. NODE_EXTRA_CA_CERTS 환경 변수를 CA 인증서 파일을 가리키도록 설정해 볼 수 있습니다. claude_desktop_config.json을 사용하는 경우 다음과 같이 보일 수 있습니다:
{
"mcpServers": {
"remote-example": {
"command": "npx",
"args": [
"mcp-remote",
"https://remote.mcp.server/sse"
],
"env": {
"NODE_EXTRA_CA_CERTS": "{your CA certificate file path}.pem"
}
}
}
}
tail -n 20 -F ~/Library/Logs/Claude/mcp*.logtail -n 20 -f "C:\Users\YourUsername\AppData\Local\Claude\Logs\mcp.log"Get-Content "C:\Users\YourUsername\AppData\Local\Claude\Logs\mcp.log" -Wait -Tail 20특히 토큰 갱신이나 인증 문제와 같은 복잡한 문제를 해결하려면 --debug 플래그를 사용하세요:
"args": [
"mcp-remote",
"https://remote.mcp.server/sse",
"--debug"
]
이렇게 하면 연결 및 인증 프로세스의 모든 단계에 대한 타임스탬프와 전체 정보가 포함된 상세 로그가 ~/.mcp-auth/{server_hash}_debug.log에 생성됩니다. 토큰 갱신, 노트북 절전/재개 문제 또는 인증 문제를 발견하면 지원을 요청할 때 이 로그를 제공하세요.
/callback URL에서 다음과 같은 오류가 반환되는 경우:
Authentication Error
Token exchange failed: HTTP 400
rm -rf ~/.mcp-auth를 실행하여 로컬에 저장된 상태와 토큰을 모두 지울 수 있습니다.
명령줄에서(MCP 서버가 아닌) 다음을 실행하세요:
npx -p mcp-remote@latest mcp-remote-client https://remote.mcp.server/sse
이 명령은 전체 인증 흐름을 실행하고 원격 URL에서 도구 및 리소스 목록을 가져오려고 시도합니다. rm -rf ~/.mcp-auth를 실행한 후 이 명령을 실행하여 오래된 자격 증명이 문제인지 확인해 보세요. 그렇지 않다면 이 로그에서 MCP 클라이언트의 로그보다 문제가 더 명확하게 드러날 것입니다.