jaysnote
18분

Agent는 Context7 MCP를 어떻게 선택하고 코드를 만드는가 — server instructions, tools/list, tools/call

Agent가 Context7을 선택하는 근거부터 tools/list로 도구를 발견하고 문서 검색 결과로 코드를 만드는 흐름까지 설명합니다.

Agent가 “Next.js 16에서 인증되지 않은 사용자를 로그인 화면으로 보내는 코드를 만들어줘”라는 요청을 받았다고 해봅시다. Agent는 왜 자기 기억만으로 답하지 않고 Context7을 찾아야 한다고 판단할까요? tools/list에서 발견한 함수는 어떤 순서로 쓰고, Context7이 돌려준 문서는 어떻게 최종 코드가 될까요?

핵심은 역할 분리입니다.

  • Context7 MCP Server는 자신이 맡은 영역과 사용할 수 있는 도구를 공개합니다.
  • LLM은 사용자 요청과 도구 설명을 비교해 무엇을 호출할지 결정합니다.
  • Agent Host는 LLM의 결정을 실제 MCP 요청으로 실행하고 결과를 다시 LLM에게 전달합니다.
  • LLM은 사용자 요청, 프로젝트 코드, 검색 문서를 함께 읽고 최종 코드를 만듭니다.

Context7이 최종 코드를 대신 쓰는 것이 아닙니다. Context7은 최신 문서 근거를 제공하고, LLM이 그 근거를 프로젝트 상황에 적용합니다.

이 글은 Context7 공식 저장소의 MCP Server 4.0.2, 커밋 769c6cd를 직접 빌드한 뒤 tools/list, resolve-library-id, query-docs를 호출해 확인했습니다.

Agent가 Context7의 용도를 아는 첫 번째 단서, server instructions

Context7 MCP Server는 연결될 때 이름과 버전만 알리는 것이 아닙니다. 서버 전체의 사용 지침인 instructions도 등록합니다. 공식 소스의 원문은 다음 문장으로 시작합니다.

Use this server to fetch current documentation whenever the user asks about a library, framework, SDK, API, CLI tool, or cloud service

뜻은 분명합니다. 사용자가 라이브러리, 프레임워크, SDK, API, CLI 도구, 클라우드 서비스에 관해 묻는다면 Context7에서 현재 문서를 가져오라는 지침입니다. React, Next.js, Prisma, Express, Tailwind, Django, Spring Boot처럼 잘 알려진 기술도 예외로 두지 않습니다.

지침이 정한 사용 범위는 다음과 같습니다.

사용자 요청Context7 사용이유
API 문법, 설정 방법사용라이브러리 문서에 정답이 의존함
특정 버전의 migration사용모델 학습 이후 변경됐을 수 있음
라이브러리 고유 오류 디버깅사용해당 제품의 현재 동작을 확인해야 함
CLI 명령과 옵션사용버전별 명령과 옵션이 달라질 수 있음
일반 리팩터링사용하지 않음외부 문서보다 프로젝트 코드가 근거임
비즈니스 로직 디버깅사용하지 않음라이브러리 문서가 핵심 원인이 아님
코드 리뷰, 일반 프로그래밍 개념사용하지 않음일반 추론과 코드 분석으로 해결할 영역임

따라서 Agent가 Context7의 존재를 갑자기 떠올리는 것이 아닙니다. MCP 연결에서 받은 서버 지침과 사용자의 질문을 비교합니다.

Agent가 사용자 요청을 보고 Context7 사용 여부와 도구 순서를 판단하는 흐름

예를 들어 “숫자 두 개를 더하는 함수를 만들어줘”는 일반 프로그래밍이므로 Context7을 부를 이유가 없습니다. “Next.js 16에서 redirect()를 어디서 호출할 수 있어?”는 특정 프레임워크, 버전, API 동작에 의존하므로 Context7의 담당 영역입니다.

여기에는 한 가지 구현상의 경계가 있습니다. Context7이 instructions를 제공해도 MCP Host가 그 지침을 LLM의 현재 컨텍스트에 반영하지 않으면 도구 선택에 직접 쓰이지 않을 수 있습니다. 서버가 지침을 제공하는 것과 Host가 그것을 모델에 노출하는 것은 서로 다른 단계입니다.

두 번째 단서, tools/list가 공개하는 도구 설명서

서버의 담당 영역을 알았다면 이제 어떤 기능을 쓸 수 있는지 알아야 합니다. MCP Client는 Context7에 다음 요청을 보냅니다.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}

tools/list는 도구를 실행하지 않습니다. 서버가 제공하는 도구의 이름, 설명, 입력 JSON Schema, annotation을 조회합니다. MCP Tools 명세는 목록이 길 때를 위한 pagination도 정의하지만, 현재 Context7은 두 도구만 반환합니다.

실제 서버를 실행해 받은 핵심 결과는 다음과 같습니다.

{
  "ttlMs": 0,
  "cacheScope": "private",
  "tools": [
    {
      "name": "resolve-library-id",
      "title": "Resolve Context7 Library ID",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": { "type": "string" },
          "libraryName": { "type": "string" }
        },
        "required": ["query", "libraryName"]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true
      }
    },
    {
      "name": "query-docs",
      "title": "Query Documentation",
      "inputSchema": {
        "type": "object",
        "properties": {
          "libraryId": { "type": "string" },
          "query": { "type": "string" }
        },
        "required": ["libraryId", "query"]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true
      }
    }
  ]
}

도구 이름과 인자만으로는 사용 순서를 완전히 알 수 없습니다. 중요한 정보는 함께 반환되는 description입니다.

resolve-library-id

resolve-library-id({
  libraryName: string,
  query: string
})

libraryNameNext.js처럼 사람이 부르는 공식 이름입니다. query는 그 라이브러리에서 무엇을 찾으려는지를 나타냅니다. 단순히 이름만 찾는 것이 아니라 사용 목적도 함께 보내야 Context7이 관련도 높은 후보를 돌려줄 수 있습니다.

도구 설명은 query-docs를 호출하기 전에 이 도구로 정확한 Context7 library ID를 구하라고 지시합니다. 사용자가 이미 /org/project 또는 /org/project/version 형식의 ID를 제공했다면 이 단계는 생략할 수 있습니다.

후보를 고를 때는 이름 일치도, 설명의 관련성, 코드 snippet 수, source reputation, benchmark score, 요청한 버전의 존재 여부를 함께 봅니다. 도구가 첫 번째 후보를 최종 정답으로 강제하는 구조가 아니라, 후보를 받은 LLM이 선택합니다.

이름은 resolve지만 실제 반환값은 후보 목록이다

resolve-library-id라는 이름만 보면 서버가 library ID 하나를 확정해 반환하는 함수처럼 보입니다. 하지만 현재 구현은 검색 조건에 맞는 여러 library 후보를 반환하는 후보 검색기에 가깝습니다.

resolve-library-id({ libraryName, query })

여러 library 후보와 평가 정보

LLM이 가장 적합한 libraryId 선택

query-docs({ libraryId, query })

실제 Next.js 조회 결과도 하나가 아니었습니다.

Available Libraries:

- Title: Next.js
- Context7-compatible library ID: /vercel/next.js
- Code Snippets: 5847
- Source Reputation: High
- Benchmark Score: 88.22
- Versions: ...

----------

- Title: Next.js
- Context7-compatible library ID: /websites/nextjs
- Code Snippets: 5214
- Source Reputation: High
- Benchmark Score: 83.97

----------

- Title: Next.js Boilerplate
- Context7-compatible library ID: /ixartz/next-js-boilerplate
- Code Snippets: 448
- Source Reputation: High
- Benchmark Score: 58.58

현재 MCP 응답은 후보 배열을 별도의 structured JSON으로 주는 것이 아니라, content 안의 text로 정리해 반환합니다. LLM은 이 텍스트에 포함된 다음 정보를 읽고 최종 ID를 고릅니다.

후보 정보선택할 때 보는 이유
Library ID, Name사용자가 말한 라이브러리와 정확히 일치하는지 확인
Description질문의 사용 목적과 관련 있는 프로젝트인지 확인
Code Snippets참고할 수 있는 문서와 코드 coverage 확인
Source Reputation출처의 권위와 신뢰도 판단
Benchmark ScoreContext7이 제공하는 품질 지표 비교
Versions사용자가 요구한 버전이 실제로 있는지 확인

따라서 함수 이름의 resolve는 “서버가 하나를 확정한다”는 반환 형식을 뜻하지 않습니다. 후보 검색 결과를 근거로 Agent가 하나를 확정하는 전체 목적을 나타냅니다. 이름이 모호하거나 좋은 후보가 여러 개라면 도구 설명에 따라 Agent가 사용자에게 확인할 수도 있습니다.

query-docs

query-docs({
  libraryId: string,
  query: string
})

libraryId는 앞 단계에서 선택한 Context7 ID이고, query는 문서에서 찾을 구체적인 질문입니다. auth, hooks처럼 한 단어만 보내기보다 “Express.js에서 JWT 인증을 설정하는 방법”처럼 필요한 동작을 구체화해야 합니다.

서로 독립적인 주제도 한 query에 몰아넣지 않습니다. Next.js의 routing, auth, caching을 모두 알아봐야 한다면 주제별로 나누어 호출하는 편이 낫습니다. 다만 세 개가 어떻게 상호작용하는지 묻는 질문이라면 하나로 묶을 수 있습니다.

두 도구의 설명에는 한 질문당 최대 세 번까지만 호출하라는 제한도 들어 있습니다. 이는 Agent가 같은 검색을 끝없이 반복하지 않도록 주는 실행 지침입니다.

LLM은 결정하고 Host는 실행한다

도구 목록을 받은 뒤의 역할 구분이 가장 중요합니다.

주체하는 일하지 않는 일
LLM질문 해석, 도구 선택, 인자 작성, 결과 해석, 코드 생성MCP 프로세스와 네트워크를 직접 실행하지 않음
Agent Host도구를 LLM에 노출, MCP 요청 실행, 결과를 컨텍스트에 추가어떤 코드가 정답인지 독자적으로 판단하지 않음
MCP Clienttools/list, tools/call 메시지 송수신최종 코드를 만들지 않음
Context7 MCP Serverlibrary 후보와 관련 문서, 코드 예제, 출처 반환사용자의 프로젝트에 맞는 최종 코드를 대신 작성하지 않음

Context7 MCP 연결, 도구 발견, 검색, 컨텍스트 주입, 코드 생성의 실제 메시지 흐름

LLM이 resolve-library-id를 호출하고 싶다고 판단하면 구조화된 tool call을 만듭니다. Agent Host는 그 선택을 다음 MCP 요청으로 바꿉니다.

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "resolve-library-id",
    "arguments": {
      "libraryName": "Next.js",
      "query": "Next.js 16에서 인증되지 않은 사용자를 로그인 화면으로 redirect하는 방법"
    }
  }
}

LLM이 만든 것은 “이 도구를 이 인자로 호출하고 싶다”는 요청입니다. 실제 함수 실행과 네트워크 통신은 Host 안의 MCP Client가 담당합니다.

실제 요청 하나를 끝까지 따라가 보기

사용자 요청은 다음과 같습니다.

Next.js 16에서 로그인하지 않은 사용자를
/dashboard에서 /login으로 보내는 코드를 만들어줘.

1. Context7을 사용할지 판단한다

Agent는 질문에서 네 가지 신호를 찾습니다.

  • Next.js: 특정 프레임워크
  • 16: 특정 버전
  • 인증 redirect: 프레임워크 고유 동작
  • 코드를 만들어 달라는 요청: 현재 API를 프로젝트 코드에 적용해야 함

이는 Context7 서버 지침의 “프레임워크, API 문법, 설정, 버전별 사용법” 범위와 일치합니다.

2. 정확한 library ID가 있는지 확인한다

사용자는 Next.js라는 이름만 말했고 /vercel/next.js 같은 Context7 ID는 주지 않았습니다. query-docs 설명에 적힌 선행 조건에 따라 resolve-library-id부터 호출합니다.

{
  "name": "resolve-library-id",
  "arguments": {
    "libraryName": "Next.js",
    "query": "Next.js 16 authentication redirect for unauthenticated users"
  }
}

2026년 8월 21일 실제 호출에서는 /vercel/next.js, /websites/nextjs, Next.js boilerplate 같은 후보가 반환됐습니다. 당시 /vercel/next.js에는 5,847개 code snippet, High source reputation, 88.22 benchmark score가 표시됐습니다. 이 수치는 Context7의 index가 갱신되면 달라질 수 있습니다.

Agent는 이름과 공식성, 문서 coverage, 점수, 사용 가능한 버전을 비교해 /vercel/next.js를 선택합니다.

3. 사용자 요청을 문서 검색 질문으로 좁힌다

사용자의 전체 요청을 그대로 보내기보다 문서에서 확인할 한 가지 주제로 좁힙니다.

{
  "name": "query-docs",
  "arguments": {
    "libraryId": "/vercel/next.js",
    "query": "How to redirect unauthenticated users from protected routes in Next.js 16"
  }
}

Context7은 해당 library 안에서 질문과 관련된 설명과 예제 코드를 찾아 MCP tool result로 반환합니다. 실제 redirect() 조회에서는 Server Action에서 mutation 이후 이동하는 예제, redirect(path, type) 설명, Route Handler에서 redirect하는 예제, 원본 Next.js 문서 경로가 함께 돌아왔습니다.

4. Host가 검색 결과를 현재 컨텍스트에 넣는다

이 시점의 LLM 입력에는 다음 정보가 함께 들어갑니다.

사용자 요청
+ 프로젝트의 package.json과 기존 인증 코드
+ Context7에서 받은 Next.js 문서와 예제
+ Agent의 시스템, 개발자 지침

이것은 모델 재학습이나 장기 기억 수정이 아닙니다. 현재 요청을 처리하는 동안 검색 결과를 추가 컨텍스트로 읽는 것입니다.

5. LLM이 프로젝트에 맞는 코드를 만든다

문서 예제가 그대로 정답이 되는 것은 아닙니다. LLM은 프로젝트에서 실제로 쓰는 인증 방식, cookie 이름, 보호할 경로, 설치된 Next.js 버전을 함께 확인해야 합니다. Context7 문서가 API 사용법을 알려줘도 session cookie가 이 프로젝트의 진짜 인증 기준인지는 프로젝트 코드에서 확인해야 합니다.

따라서 최종 코드는 다음 세 근거가 합쳐진 결과입니다.

근거제공하는 정보
사용자 요청무엇을 만들 것인가
프로젝트 코드이 저장소에서 어떻게 연결할 것인가
Context7 검색 문서현재 API를 정확히 어떻게 사용할 것인가

코드를 만든 뒤에는 type check, test, build처럼 프로젝트에 맞는 검증을 별도로 수행해야 합니다. Context7 검색 성공은 코드의 정답을 보장하지 않습니다.

사용자가 ID를 직접 주면 식별 단계는 사라진다

다음처럼 요청했다고 해봅시다.

/vercel/next.js 문서를 확인해서 App Router의 redirect 사용법을 알려줘.

이미 Context7 ID가 있으므로 Agent는 resolve-library-id를 생략하고 바로 호출할 수 있습니다.

{
  "name": "query-docs",
  "arguments": {
    "libraryId": "/vercel/next.js",
    "query": "How to use redirect in the App Router"
  }
}

특정 버전 ID를 알고 있다면 /vercel/next.js/v16.2.9처럼 넘길 수도 있습니다. 단, 그 버전이 resolve-library-id 결과에 실제로 존재하는지는 먼저 확인하는 편이 안전합니다.

tools/list가 있어도 도구 선택이 항상 보장되지는 않는다

tools/list는 선택지를 공개하지만 선택을 강제하지는 않습니다. LLM의 도구 선택은 사용자 요청, 시스템 지침, 서버 지침, 도구 설명, 현재 컨텍스트의 영향을 받습니다.

상황예상 동작더 강한 보장이 필요할 때
사용자가 Context7 사용을 직접 요청Context7 선택 가능성이 매우 높음사용자 지시를 그대로 실행
시스템 지침이 현재 문서 확인을 요구라이브러리 질문마다 일관되게 사용조직 정책으로 명시
서버 instructions만 제공Host가 LLM에 전달할 때 영향을 줌Host의 전달 여부 확인
tools/list 설명만 제공질문과 설명의 의미가 맞으면 선택도구 이름과 설명을 명확히 작성
일반 리팩터링 요청Context7을 생략하는 것이 정상프로젝트 코드 분석에 집중

“라이브러리 API를 사용할 때는 Context7로 현재 문서를 먼저 확인한다”는 규칙이 필요하다면 Agent의 시스템 또는 개발자 지침에도 명시하는 편이 확실합니다. MCP 서버가 자기 용도를 설명하는 것과 Agent 운영 정책이 사용을 요구하는 것은 서로 다른 강도의 신호입니다.

정리

Agent와 Context7의 실제 흐름은 다음과 같습니다.

  1. MCP 연결에서 Context7의 담당 영역과 서버 지침을 받습니다.
  2. tools/list로 도구 이름, 설명, 입력 스키마를 발견합니다.
  3. LLM이 사용자 질문과 지침을 비교해 Context7 사용 여부를 판단합니다.
  4. 정확한 ID가 없으면 resolve-library-id로 후보를 찾고 LLM이 하나를 고릅니다.
  5. query-docs에 library ID와 한 가지 구체적인 질문을 보냅니다.
  6. Context7이 관련 문서, 코드 예제, 출처를 반환합니다.
  7. Agent Host가 그 결과를 LLM의 현재 컨텍스트에 추가합니다.
  8. LLM이 사용자 요구, 프로젝트 코드, 검색 문서를 결합해 코드를 만듭니다.
  9. Agent가 프로젝트에 맞는 test, build, type check로 결과를 검증합니다.

instructionsContext7을 언제 사용할지 알려주고, tools/listContext7에서 무엇을 어떤 입력으로 사용할지 알려줍니다. tools/call은 LLM의 선택을 실제 검색으로 바꾸고, 검색 결과는 최종 코드의 근거가 됩니다.

참고 자료

관련 글

← 목록으로