Quick Reference
MCP 연결은 agent가 외부 도구를 발견하게 하고, Agent SDK permission은 그 도구의 호출 승인을 정하며, MCP 서버의 token·읽기 전용 설정은 외부 시스템에서 실제로 할 수 있는 일을 제한합니다. 세 경계를 모두 좁혀야 읽기 전용 agent가 됩니다.
mcpServers 또는 .mcp.json
-> mcp__<server>__<tool> 이름으로 도구 발견
-> allowedTools: 지정 도구 자동 승인
-> permissionMode: dontAsk면 미승인 도구 거부
-> MCP 서버 token / role: 실제 외부 권한 제한const options = {
mcpServers: {
"claude-code-docs": {
type: "http",
url: "https://code.claude.com/docs/mcp",
},
},
allowedTools: ["mcp__claude-code-docs__*"],
permissionMode: "dontAsk",
};서버를 연결하는 방법
query()의 mcpServers에 stdio 또는 HTTP 서버를 직접 넣으면 그 agent 실행에만 연결할 수 있습니다. 프로젝트 공통 설정은 루트 .mcp.json에 둡니다. 기본 query() 설정은 project source를 읽지만, settingSources를 명시적으로 설정했다면 "project"를 포함해야 이 파일을 읽습니다. 두 방식은 연결 위치가 다를 뿐, 어떤 서버가 어떤 데이터·side effect를 제공하는지 확인해야 한다는 점은 같습니다.
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Search the Claude Code documentation for the current MCP transport options.",
options: {
settingSources: ["project"], // 값을 명시할 때 .mcp.json도 읽음
mcpServers: {
docs: { type: "http", url: "https://code.claude.com/docs/mcp" },
},
allowedTools: ["mcp__docs__*"],
permissionMode: "dontAsk",
},
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}환경 변수나 token은 .mcp.json과 source code에 평문으로 넣지 않습니다. 서버가 지원하는 환경 변수 참조, 비밀 저장소, 짧은 수명의 제한된 token을 사용합니다. init message에서 MCP 상태가 failed 또는 needs-auth면 그 서버 도구는 쓸 수 없으므로 연결부터 바로잡습니다.
도구 승인과 차단
MCP tool 이름은 mcp__<server-name>__<tool-name>입니다. allowedTools에 넣으면 그 이름의 호출은 자동 승인되지만, 이는 도구의 존재를 숨기거나 목록 밖 도구를 무조건 차단하는 allowlist가 아닙니다. permissionMode: "dontAsk"와 함께 써야 지정하지 않은 도구가 승인 화면으로 가지 않고 거부됩니다.
const readProjectFilesOnly = {
mcpServers: {
filesystem: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", process.cwd()],
},
},
allowedTools: [
"mcp__filesystem__read_file",
"mcp__filesystem__list_directory",
],
permissionMode: "dontAsk",
disallowedTools: ["Bash", "Edit"],
};와일드카드 mcp__server__*는 해당 서버가 나중에 추가하는 쓰기 도구까지 자동 승인할 수 있습니다. search, get, list처럼 필요한 읽기 도구 이름만 지정합니다. bypassPermissions는 allowedTools 제한을 우회할 수 있으므로 이 방식의 읽기 전용 agent와 함께 쓰지 않습니다.
서버의 실제 권한
Agent SDK permission은 Claude가 요청을 보낼 수 있는지 결정할 뿐입니다. DB 서버가 update를 허용하는 token으로 연결돼 있다면 SDK에서 query만 승인해도 query 안에 쓰기 SQL이 들어갈 수 있습니다. 서버 역할을 read-only로 만들고, 대상 데이터베이스·파일 경로·API scope·네트워크 egress를 서버 쪽에서도 제한합니다.
좋은 분리
SDK: mcp__db__select만 자동 승인
MCP 서버: read-only DB 계정, 허용 schema 제한
DB: 운영 write 권한 없는 credential
나쁜 분리
SDK: mcp__db__* 자동 승인
MCP 서버: 운영 관리자 token매 호출의 SQL, 경로, 대상 리포지토리처럼 인자까지 검사해야 하면 PreToolUse hook으로 차단 규칙을 둡니다. canUseTool callback은 hooks, deny 규칙, permission mode 등으로 이미 결정되지 않은 요청에만 호출될 수 있으므로, 절대적인 사전 검증만 맡기면 안 됩니다.
자주 틀리는 부분
settingSources를 명시적으로 설정하면서"project"를 빼면 SDK 실행은.mcp.json을 읽지 않습니다.allowedTools만으로 외부 시스템이 read-only가 되지 않습니다. 서버 token과 서비스 권한이 더 넓으면 실제 side effect가 남습니다.mcp__server__*를 편의상 쓰면 새로 추가된 도구까지 자동 승인될 수 있습니다. 특히 issue, 배포, DB, 메시징 서버에는 개별 도구 이름을 씁니다.failed,needs-auth상태를 tool permission 문제로 오해하지 않습니다. 서버 연결·인증부터 해결합니다.
참고 링크
3 sources