MINARA

MCP 서버 연결

`mcp/servers.json` 으로 외부 MCP 서버를 Agent 에 연결

Agent 는 부팅 시 Model Context Protocol 서버에 연결합니다. 해당 도구들은 내장 도구와 동일한 ToolRegistry 로 들어가며 기본적으로 defer_loading: true 가 표시됩니다 (schema 는 모델이 tool_search 를 호출할 때에만 가져옵니다).

두 개의 파일 위치

서버 설정은 두 곳에서 읽혀 병합됩니다:

  • 사용자 전역: <dataDir>/mcp/servers.json, 기본값 ~/.minara/mcp/servers.json. MINARA_DATA_DIR 로 디렉터리를 덮어쓸 수 있습니다. 개인 자격 증명과 모든 저장소에서 사용 가능하길 원하는 서버를 둡니다. mcp/servers.json 이 없으면 기존 경로 <dataDir>/mcp.json 도 읽으므로 기존 설정은 그대로 동작합니다.
  • 프로젝트 로컬: <repo>/.minara/mcp/servers.json. cwd 에서 위로 올라가며 가장 가까운 .minara/ 디렉터리 (.git/ 와 같은 레벨) 를 찾아 해석합니다. 단일 저장소에 개발 URL 또는 테넌트별 token 을 고정하고 싶을 때 사용. 기존 경로 <repo>/.minara/mcp.json 도 동일한 폴백입니다.

id 가 충돌하면 프로젝트 항목이 이깁니다. 따라서 저장소는 전역에 선언된 서버의 authTokenEnvurl 을 덮어쓸 수 있습니다.

두 파일은 동일한 스키마를 공유합니다:

{
  "mcpServers": {
    "slack": {
      "url": "https://mcp.example.com/slack/",
      "authTokenEnv": "SLACK_MCP_TOKEN",
      "headers": { "X-Tenant": "acme" }
    },
    "etherscan": {
      "url": "https://mcp.example.com/etherscan/",
      "timeoutMs": 60000,
      "subagent": {
        "systemPrompt": "EVM 블록 익스플로러 질의 전담.",
        "maxSteps": 10
      }
    }
  }
}

JSON 키가 서버 id 가 되어 mcp_<id>_* 도구명 접두사로 사용됩니다. 같은 서버를 다른 별칭으로 두 번 등록해야 할 경우 항목 안에 "id" 필드를 명시하면 키보다 우선합니다.

필드

필드필수설명
urlStreamable-HTTP MCP 엔드포인트. SSE 전용 엔드포인트는 미지원.
authTokenEnv아니오bearer token 을 담은 환경 변수 이름. 연결 시 환경에서 해석하여 Authorization: Bearer <token> 로 전송. secret 을 디스크에 남기지 않으므로 authToken 보다 우선.
authToken아니오bearer token 리터럴 값. 존재하면 읽지만, 이 파일을 쓰는 도구 (minara mcp add, chat 내 설치 경로) 는 inline token 을 거부하고 authTokenEnv 를 요구합니다. 신뢰할 수 있는 호스트에서 직접 작성한 파일은 여전히 사용 가능.
headers아니오모든 요청에 병합되는 추가 HTTP 헤더. secret 헤더 값 (Authorization, X-Api-Key) 은 환경 변수를 참조해야 합니다. 예: "Authorization": "Bearer ${SLACK_MCP_TOKEN}".
timeoutMs아니오단일 호출 타임아웃. 기본 30000.
label아니오로그용 표시명. 기본은 id.
maxTools아니오서버당 등록 도구 수 상한. 기본 64.
include아니오원격 도구 이름 화이트리스트. 외 나머지는 폐기.
subagent아니오설정 시 해당 서버 도구들을 단일 mcp_<id>_query 로 묶어 내부 agent 루프로 구동. 도구가 많은 서버에서 페르소나 + 스텝 예산으로 메인 루프를 깔끔하게 유지할 때 유용.

잘못된 항목 (url 누락, 타입 오류) 은 로그를 남기고 건너뜁니다 : 한 항목이 깨졌다고 다른 서버 연결이 막히지 않습니다.

우선순위

  1. MCP_SERVERS 환경 변수 : 서버 설정 JSON 배열. 두 파일 위치 를 모두 쇼트서킷합니다. 테스트나 secrets manager 가 블롭을 직접 주입하는 컨테이너 배포에서 사용.
  2. 병합된 서버 설정 : 전역 <dataDir>/mcp/servers.json 과 프로젝트 로컬 <repo>/.minara/mcp/servers.json 을 병합 (각각 같은 레벨의 기존 경로 mcp.json 으로 폴백). id 가 충돌하면 프로젝트 항목이 전역을 덮어쓰고, id 가 다른 항목은 합집합이 됩니다.
  3. v1 서버별 URL 환경 변수 : MCP_EVM_RPC_URL, MCP_ETHERSCAN_URL, MCP_SOLSCAN_URL, MCP_GOPLUS_URL. 각각 독립적으로 게이트되며, 앞 두 계층이 모두 비어 있을 때만 참고됩니다.

디스크에 설정 파일이 있어도 MCP_SERVERS=… 는 항상 파일 계층을 쇼트서킷하므로 재현성이 유지됩니다.

보안

secret 을 설정 파일에 쓰지 마세요. 인증은 authTokenEnv (환경 변수 이름) 로 표현하고, token 은 연결 시 환경에서 해석됩니다. 이 파일을 쓰는 도구 (minara mcp add 와 chat 내 설치 경로) 가 이를 강제합니다. inline authToken 도, 리터럴 값을 담은 secret 헤더도 거부하므로 token 이 Agent 를 거쳐 디스크에 도달하지 않습니다.

신뢰할 수 있는 호스트에서 직접 작성한 파일은 여전히 리터럴 authToken 을 담을 수 있고 loader 가 읽습니다. 공유 호스트에서는 authTokenEnv 를 우선하세요. 꼭 리터럴 token 을 저장해야 한다면:

  • chmod 600 ~/.minara/mcp/servers.jsonchmod 600 <repo>/.minara/mcp/servers.json.
  • 또는 MCP_SERVERS 로 secrets manager (Vault, AWS Secrets Manager, doppler 등) 에서 주입하고 설정 파일을 비워둡니다.
  • 프로젝트 로컬 파일은 저장소 협업자와 token 을 공유하고 싶지 않다면 .minara/.gitignore 에 추가합니다.

관측

부팅 로그는 module: "app", action: mcp_initialized 라인에서 연결된 서버와 도구 수를 보고합니다. 서버 단위 실패는 mcp_server_connect_failed 로 표시됩니다.

REPL 의 pnpm dev -- status (또는 대응되는 HTTP gateway 엔드포인트) 에서 현재 MCP 상태 배열을 확인할 수 있습니다.

목차