MCP 서버 개발 가이드라인
GitLab v19.3요약
이 페이지는 GitLab MCP 서버를 개발하고 사용하는 방법에 대한 정보를 포함합니다. 더 자세한 로깅을 위해 mcp-remote 명령에 --debug를 추가합니다. Claude Desktop은 지원되지 않는 버전의 Node.js를 사용합니다.
이 페이지는 GitLab MCP 서버를 개발하고 사용하는 방법에 대한 정보를 포함합니다.
개발 환경 설정#
개발 환경을 설정하려면:
- GDK에서 HTTPS 활성화 및 구성.
node를 설치하고mcp-remote를 전역으로 설치합니다. GDK에는 Node.js가 포함되어 있지만 설치된 AI 어시스턴트는 GDK 버전을 사용할 수 없습니다.- AI 어시스턴트를 MCP 서버에 연결.
디버깅 및 문제 해결#
Cursor 디버그#
더 자세한 로깅을 위해 mcp-remote 명령에 --debug를 추가합니다. 출력을 열고 MCP:SERVERNAME을 선택하여 MCP 서버 로그를 확인합니다. 아래 예시의 경우 MCP:user-GitLab-GDK입니다.
{
"mcpServers": {
"GitLab-GDK": {
"command": "npx",
"args": [
"mcp-remote",
"https://gdk.test:3443/api/v4/mcp",
"--debug"
],
"env": {
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}
}
}
Claude Desktop 디버그#
Node.js 버전 확인#
Claude Desktop은 지원되지 않는 버전의 Node.js를 사용합니다. 특정 버전을 사용하는 커스텀 래퍼 스크립트를 생성합니다:
#!/bin/bash
# Force use of your Node.js version
NODE_BIN="/PATH_TO_NODE_INSTALL/node/22.17.0/bin/node"
MCP_REMOTE_BIN="/PATH_TO_NODE_INSTALL/node/22.17.0/bin/mcp-remote"
# Run mcp-remote with your Node.js
exec "$NODE_BIN" "$MCP_REMOTE_BIN" "$@"
Claude Desktop 구성에서 래퍼 스크립트를 사용합니다.
{
"mcpServers": {
"GitLab-GDK": {
"command": "/PATH_TO_REMOTE_WRAPPER_SCRIPT/mcp-remote-wrapper",
"args": [
"https://gdk.test:3443/api/v4/mcp",
"--debug"
],
"env": {
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}
}
}
mcp-remote 디버그#
AI 어시스턴트 외부에서 mcp-remote에서 GDK로의 인증을 테스트합니다:
NODE_TLS_REJECT_UNAUTHORIZED=0 npx mcp-remote https://gdk.test:3443/api/v4/mcp --debug
브랜치를 전환하면 로그에 UNABLE_TO_VERIFY_LEAF_SIGNATURE 오류를 포함한 인증 문제가 발생할 수 있습니다. 체인의 신뢰할 수 없는 인증서 오류는 TLS를 사용하는 GDK 인스턴스에 특정합니다. 이 오류는 npx를 통한 Node.js 및 mcp-remote 라이브러리의 https 클라이언트에서 발생합니다. https 클라이언트는 번들된 인증 기관 목록 외부에서 서명된 인증서를 신뢰하지 않습니다.
인증 문제가 발생하면 최후의 수단으로 ~/.mcp-auth 디렉토리를 삭제하면 mcp-remote에 대해 저장된 자격증명이 초기화됩니다. AI 어시스턴트가 MCP 서버에 다시 연결할 때 브라우저 창이 열려 인증을 묻습니다.
rm -rf ~/.mcp-auth
MCP 인스펙터로 디버그#
MCP 인스펙터는 MCP 서버를 테스트하고 디버깅하기 위한 대화형 개발자 도구입니다.
다음 명령은 서버에 연결하고 MCP 도구를 나열하고 실행하기 위한 직관적인 Web UI를 엽니다:
npx -y @modelcontextprotocol/inspector npx
개발 워크플로우#
유용한 링크#
새 도구 추가#
도구 제안 프로세스#
현재 개발 가이드라인은 초기 개발 단계에 있습니다. 커스텀 및 집계 도구에 대한 도구 개발 표준을 계속 확립하면서 구현 전에 제안된 도구를 평가하고 새 MCP 도구를 계획하는 팀을 안내하기 위해 임시 mcp-tool-review-board 위원회를 만들었습니다.
새 도구를 추가하려면 MCP 도구 제안 이슈를 생성하고 템플릿 지침을 따르세요.
도구 구현 위치는 GitLab 리소스와의 상호작용에 따라 달라집니다:
- GitLab 리소스와 상호작용하는 도구는 궁극적으로 MCP 서버에 있어야 하지만, 단기 또는 긴급한 필요의 경우 에이전트 플랫폼에 구현할 수 있습니다.
- GitLab 리소스와 상호작용하지 않는 도구는 에이전트 플랫폼에 구현해야 합니다.
MCP 서버 기능을 에이전트 플랫폼에 통합하는 작업을 진행 중입니다. 이 이슈를 통해 진행 상황을 추적할 수 있습니다.
모든 엔지니어가 도구 제안 프로세스를 따르고 사용 사례에 대한 명확한 설명을 제공하도록 강력히 권장합니다.
도구 이름 지정 및 통합 규칙#
도구를 추가하거나 통합할 때는 도구 표면을 작고 예측 가능하게 유지하기 위해 다음 규칙을 따르세요. 이 규칙은 기능을 잃지 않으면서 도구 수와 토큰 오버헤드를 줄입니다.
동사 클래스: 모든 도구 이름은 verb_object 형태를 사용하며, 동사는 작업 클래스를 나타냅니다:
- 단일 객체에는
get_, 컬렉션에는list_를 사용합니다. - 생성 및 업데이트 필드 변형에는
save_를 사용합니다.id의 존재 여부가 해당 작업이 생성 작업인지 업데이트 작업인지를 정의합니다. 생성 시 필수인 파라미터는 도구 정의에 그렇게 표시해야 합니다. 의도적인 예외:save_도구는 필드 변형이 아닌 수명 주기 액션(예:retry,cancel)을action파라미터 뒤에 묶을 수도 있습니다. 단, 해당 액션이 그 도구가 생성하는 것과 동일한 리소스에서 동작하고 자체 전용 도구를 둘 만하지 않은 경우에 한합니다. 상위 식별자가 아니라 리소스 자체의 ID 존재 여부로 라우팅하세요. 예를 들어save_pipeline은pipeline_id가 없으면 생성으로,pipeline_id가 있고action이 함께 전달되면 해당 파이프라인에 대한 수명 주기 전환으로 처리합니다. 이를 도구 설명에 문서화하고 의도적인 예외로 기록하세요(아래 참조). - 실제 삭제 작업에는
delete_를 사용합니다. 더 나은 거버넌스 처리를 위해 이를save_에 묶어서는 안 됩니다. add_또는 이 패턴에서 벗어난 다른 형태는 커밋, 브랜치, 세션처럼 일반적인 CRUD 형태를 갖지 않는 객체에 예약되어 있습니다(예:add_commit,add_branch).
리소스 식별: 모든 프로젝트 범위 도구는 동일한 방식으로 대상을 식별합니다. 각 도구는 자체 입력 스키마에 url, project_id 및 리소스의 내부 ID를 선언합니다. 이러한 파라미터를 해석하려면 Mcp::Tools::Concerns::UrlParser 및 Mcp::Tools::Concerns::ResourceFinder concern을 포함하세요. 호출자는 다음 중 하나를 제공합니다:
url- 전체 경로를 인코딩한 전체 GitLab URL(예:https://gitlab.com/group/project/-/merge_requests/1), 또는- ID 그룹 -
project_id(숫자 ID 또는gitlab-org%2Fgitlab과 같은 URL 인코딩된 경로)와 리소스의 내부 ID(merge_request_iid,work_item_iid,commit_sha등).
프로젝트 식별자와 내부 ID는 별도의 파라미터로 유지하세요. 이들을 단일 id로 묶지 마세요. 이들은 서로 다른 값이며(iid/sha는 프로젝트 범위로 지정되어 project_id 없이는 의미가 없습니다), url은 이미 이들을 하나로 합쳐주는 단일 값 편의 수단입니다. url과 ID가 모두 제공되면 서로 교차 검증되며 불일치 시 오류가 발생합니다. 작업 항목 도구는 동일한 그룹에서 group_id 또는 project_id를 허용합니다.
선택적 파라미터: Base::BaseService는 선택적 파라미터에 대한 명시적 null 또는 "" 값을 키가 생략된 것과 동일하게 처리하므로, 모든 스키마 속성을 채우는 호출자도 선택적 enum 파라미터에 대한 검증을 통과합니다.
읽기(단일 대 컬렉션):
- 하나의 상위 객체로 범위가 지정된 패싯은 별도의
list_*도구가 아니라include파라미터를 통해 해당 객체의get_도구에 통합됩니다(예:include: ["diffs"]를 사용하는get_merge_request). 유효한 값은diffs,commits,notes,pipelines,discussions입니다. 호출당 하나의 패싯만 지원하더라도include를 열거형 값의 배열로 선언하고maxItems로 제한하세요. 나중에 그 상한을 올리는 것은 추가적인 변경이지만, 파라미터를 문자열에서 배열로 바꾸는 것은 기존 호출자를 중단시킵니다. 단일 패싯으로 범위가 지정된 필터(job_status)를 포함하여 이 패턴을 구현한 예시는get_pipeline(include: ["jobs"]/["downstream_pipelines"]/["bridge_jobs"])을 참조하세요. - 자체적으로 조회할 수 있는 독립적인 컬렉션은 자체
list_도구를 갖습니다(예:list_merge_requests,list_pipelines). - 패싯 범위 페이지네이션은
get_리더에 위치하며 관련된include값에만 적용됩니다. 이를 파라미터 설명에 문서화하세요. - diff가 페이로드의 대부분을 차지하는 diff 포함 읽기에는
detail열거형(none/stats/full_patch)을 추가하세요(예:get_commit의diff패싯과get_merge_request의diffs패싯). 더 적합한 조절 수단이 이미 있는 곳에는detail을 소급 적용하지 마세요. 파일 내용은 줄 페이지네이션(offset/limit)을, 작업 로그는 바이트 페이지네이션(byte_offset/byte_limit)을 사용하는데, 이러한 API에는 diff 방식의 상세 수준이 없기 때문입니다. - 한 패싯이 다른 패싯의 부분집합인 경우 새 패싯이나 새 도구보다 필터 파라미터를 선호하세요(예: 별도의
failing_jobs패싯 대신job_status: failed필터).
페이지네이션: 도구의 페이지네이션 방식은 서버 전역의 단일 규칙을 강요하는 대신 그 도구가 감싸는 엔드포인트의 방식을 그대로 따릅니다. 방식 간 변환을 하지 마세요(예: 페이지 번호를 불투명한 커서로 감싸지 마세요). 오프셋 페이지네이션 위에 합성한 커서는 커서 안정성을 얻지 못한 채 메커니즘만 숨기고, 엔드포인트가 제공하는 보장에 대해 호출자를 오해하게 만듭니다.
- REST 기반 도구는
page(1부터 시작, 기본값1)와per_page(기본값20, 최대100)를 사용하는 오프셋 페이지네이션을 사용하며,page,per_page,has_more를 포함하는metadata객체를 반환합니다.list_repository_tree,list_branches,list_commits,list_pipelines,search와 같은 도구에 적용됩니다. - GraphQL 기반 도구는
first(기본값20, 최대100)와after(불투명한 커서)를 사용하는 네이티브 커서 페이지네이션을 사용하며,endCursor와hasNextPage를 포함하는pageInfo객체를 반환합니다.list_work_items,list_merge_requests와 같은 도구에 적용됩니다. - 콘텐츠 리더는 항목 페이지네이션 대신 페이로드에 맞는 범위 윈도우를 사용합니다. 파일 내용은 줄 페이지네이션(
offset/limit)을, 작업 로그는 바이트 페이지네이션(byte_offset/byte_limit)을 사용합니다. 다음 윈도우를 가져오는 방법을 호출자에게 알려주는system_instruction을 반환하세요. get_리더의 패싯 범위 페이지네이션에는 패싯 이름을 접두사로 붙이며(예:get_merge_request의notes_page/notes_per_page,get_commit의comments_page/comments_per_page), 해당 패싯을 지원하는 엔드포인트의 방식을 따릅니다.
확산보다 통합:
- 리소스별 검색 도구를 추가하는 대신 범위가 지정된 검색 변형들을
scope파라미터가 있는 통합search도구로 병합하세요.
의도적인 예외를 문서화하세요. 도구가 의도적으로 규칙을 위반하는 경우(일회성 액션 동사, 하나의 리소스에 대한 두 번째 write_ 도구), 실수로 오인되지 않도록 제안서에 의도적임을 기록하세요.
REST API 경로에서 도구 구현#
이 머지 리퀘스트는 API 경로에서 MCP 도구를 만드는 프로세스를 정의합니다.
API 경로 정의에 다음 route_setting을 추가합니다:
route_setting :mcp, tool_name: :get_issue, params: [:id, :issue_iid], resource_name: "issue"
- 도구 목록에
get_issue도구를 추가하고 실행을 활성화합니다. - 도구 및 파라미터 설명은 OpenAPI 경로 정의에서 가져옵니다.
- 허용된 파라미터는
params인수로 필터링됩니다. 예를 들어,id와issue_iid만 공개되고 허용됩니다. - 도구가 호출될 때 경로 코드는 전달된 파라미터와 함께 직접 실행됩니다.
- 선택적
resource_name필드는 리소스별 404 오류 메시지를 제공합니다(예: 일반적인"404 Not Found"대신"404 Issue Not Found")."issue"또는"merge request"와 같은 소문자 문자열을 사용합니다. 렌더링된 메시지에서는 첫 글자가 대문자로 표시됩니다.
이 머지 리퀘스트는 더 많은 예시를 제공합니다.
집계된 REST API 도구 구현#
집계된 API 도구는 여러 관련 API 도구를 단일 통합 인터페이스로 결합하여 도구 수를 줄이고 사용자 경험을 향상시킵니다. 검색 도구는 전역, 그룹, 프로젝트 검색을 하나의 도구로 통합하여 이 패턴을 보여줍니다.
집계 도구를 사용해야 하는 경우:
비슷한 목적을 제공하지만 다른 범위(전역, 그룹, 프로젝트)에서 작동하는 여러 API 엔드포인트가 있을 때 집계 도구를 사용하세요. 이는 세 개의 도구 대신 하나의 도구를 제시하여 LLM의 인지 부하를 줄입니다.
구현 단계:
Mcp::Tools::Base::AggregatedService를 상속하는 집계 서비스 클래스를 생성합니다:
module Mcp
module Tools
class ExampleAggregatedService < Base::AggregatedService
include Gitlab::Utils::StrongMemoize
extend ::Gitlab::Utils::Override
register_version '0.1.0', {
description: 'My example aggregated tool',
input_schema: {
type: 'object',
properties: {},
required: []
}
}
override :tool_name
def self.tool_name
'new_tool'
end
override :select_tool
def select_tool(args)
tool_name = if args[:group_id]
:example_tool_for_group
elsif args[:project_id]
:example_tool_for_project
end
tools.find { |tool| tool.name.to_sym == tool_name }
end
override :transform_arguments
def transform_arguments(args)
if args[:group_id]
args.merge(id: args[:group_id])
elsif args[:project_id]
args.merge(id: args[:project_id])
else
args
end
end
end
end
end
- 경로 정의에서 기본 API 도구를 집계기에 등록합니다:
route_setting :mcp, tool_name: :example_tool_for_group, params: [:id], aggregators: [::Mcp::Tools::ExampleAggregatedService]
route_setting :mcp, tool_name: :example_tool_for_project, params: [:id], aggregators: [::Mcp::Tools::ExampleAggregatedService]
Mcp::Tools::Manager는aggregators가 지정된 경로를 스캔하고 수집된 도구로 집계기 클래스를 인스턴스화하여 집계된 도구를 자동으로 발견합니다.
GraphQL 기반 도구 구현#
GitLab GraphQL API를 사용하는 MCP 도구의 경우 GraphQL 통합 가이드라인을 참조하세요.
AI 코딩 어시스턴트로 GraphQL 기반 도구를 스캐폴딩하려면 gitlab-mcp-tool-builder 스킬을 사용하세요. 이 스킬은 이 페이지와 GraphQL 통합 가이드라인의 지침을 요약하고, 흔히 겪는 함정을 추가로 담고 있으며, 도구 클래스, 서비스 클래스, .graphql 작업 파일, 매니저 등록, 스펙 작성 과정을 안내합니다. 이 저장소에는 .claude/skills/gitlab-mcp-tool-builder/에 이 스킬이 포함되어 있으므로 따로 설치할 것이 없습니다:
- Claude Code와 GitLab Duo CLI는 세션 시작 시 이 스킬을 발견합니다. 어시스턴트에게 GraphQL MCP 도구를 빌드하거나 스캐폴딩하도록 요청하거나, 스킬을 이름으로 직접 호출하세요. GitLab Duo CLI가 스킬을 발견하고 실행하는 방법은 에이전트 스킬을 참조하세요.
AGENTS.md규칙을 따르는 어시스턴트는.agents/skills심볼릭 링크를 통해 동일한 스킬을 로드합니다.
가이드라인이 신뢰할 수 있는 원본입니다. 스킬과 가이드라인이 서로 다를 경우 가이드라인을 따르고 스킬을 업데이트하세요.
커스텀 도구 구현#
API 노출과 별도로 유지해야 하는 별도 기능을 가진 도구의 경우 독립적인 클래스를 정의할 수 있습니다(이 예시 참조).
AI 에이전트 아키텍처에서의 도구 확산 위험#
너무 많은 도구 추가 시 핵심 문제#
- 성능 저하
- 컨텍스트 팽창: 모든 도구 정의(이름, 설명, JSON 스키마)가 모델의 프롬프트 컨텍스트에 추가되어 입력 토큰 수가 증가합니다.
- 지연 시간 증가: 더 큰 프롬프트는 응답 시간을 늦춥니다.
- 더 높은 비용: 더 많은 토큰 = 요청당 더 높은 API 비용
- 정확도 저하: 연구에 따르면 더 많은 컨텍스트와 더 많은 도구 모두 에이전트 성능을 저하시킵니다.
- 궤적 저하: 더 긴 추론 경로가 필요한 에이전트는 도구 확산과 함께 더 빠르게 저하됩니다.
- 도구 선택 혼란
- 결정 복잡성: 더 많은 도구는 모델이 올바른 도구를 선택하기 어렵게 합니다.
- 파라미터 설계 문제: LLM이 훈련된 공개 형식(프로젝트 경로, IID) 대신 내부 ID(GitLab 전역 ID 등)를 사용하면 도구 사용 효과가 줄어듭니다.
- 유사한 도구 간의 모호성: 모델은 유사한 목적의 도구(예: 로컬 대 원격 파일 작업)를 구분하는 데 어려움을 겪습니다.
- 사용자 경험 영향
- 도구 체이닝 소음: 더 많은 도구는 단일 요청에서 더 많은 도구 호출로 이어져 소음과 산만함을 만듭니다.
- 느린 응답: 처리 시간 증가는 사용자 만족도에 영향을 미칩니다.
- 잘못된 도구 선택: 잘못된 도구 선택은 잘못되거나 관련 없는 응답으로 이어집니다.
도구 추가 전에 개발자가 답해야 할 질문#
- 필요성: 이것이 정말 새로운 기능인가, 아니면 파라미터 조정으로 기존 도구가 처리할 수 있는가?
- 통합 가능성: 이 기능이 열거형이나 파라미터를 사용하여 기존 도구와 병합될 수 있는가?
- 파라미터 설계: 모델의 훈련 데이터와 일치하는 공개적으로 인식 가능한 식별자를 사용하는가?
- 평가 전략: 이 도구가 전반적인 에이전트 성능을 향상시키는지 저하시키는지 측정하는 방법은?
- 컨텍스트 관리: 이 도구의 정의가 실제 추론에 사용 가능한 컨텍스트 창에 어떻게 영향을 미치는가?
- 도구 라우팅: 이 도구가 메인 에이전트 도구 세트보다 특수 서브 에이전트의 일부여야 하는가?
- 권한 모델: 이 도구가 권한/가격 모델과 어떻게 상호작용하는가? 복잡성을 만드는가?
- 의미론적 구별: 이 도구가 도구 세트의 다른 도구들과 명확하게 구별될 수 있는가?
더 많은 도구가 항상 더 좋은 것은 아닙니다. 연구에 따르면 컨텍스트 크기와 도구 수 모두 수익이 감소하며 결국 성능 저하로 이어집니다. 도구 세트를 지속적으로 확장하는 대신 도구 통합, 특수 서브 에이전트 또는 동적 도구 라우팅을 고려하세요.
기존 도구 수정#
MCP 도구는 소비자에 대한 호환성 변경을 방지하기 위해 시맨틱 버저닝을 사용합니다. 도구를 수정할 때 이 머지 리퀘스트에서 도입된 버저닝 시스템을 사용하세요.
버저닝이 중요한 이유:
LLM과 AI 에이전트는 도구 스키마를 캐시하고 특정 도구 동작을 기반으로 워크플로우를 구축합니다. 도구 파라미터, 설명 또는 출력 형식의 변경은 기존 통합을 중단시킬 수 있습니다. 버저닝은 하위 호환성을 유지하면서 안전한 발전을 허용합니다.
버전 등록 패턴:
집계된 API, 커스텀 및 GraphQL 도구의 경우 register_version을 사용하여 버전을 등록합니다:
module Mcp
module Tools
class GetServerVersionService < Base::CustomService
register_version '0.1.0', {
description: 'Get the current version of MCP server.',
input_schema: {
type: 'object',
properties: {},
required: []
}
}
def perform_v0_1_0(_arguments = {})
data = { version: Gitlab::VERSION, revision: Gitlab.revision }
formatted_content = [{ type: 'text', text: data[:version] }]
::Mcp::Tools::Base::Response.success(formatted_content, data)
end
override :perform_default
def perform_default(arguments = {})
perform_v0_1_0(arguments)
end
end
end
end
새 버전 추가:
도구의 동작을 수정해야 할 때:
- 업데이트된 메타데이터로 새 버전을 등록합니다:
register_version '0.2.0', {
description: 'Get version with additional metadata.',
input_schema: {
type: 'object',
properties: {
include_metadata: {
type: 'boolean',
description: 'Include additional metadata'
}
},
required: []
}
}
- 버전별 메서드를 구현합니다:
def perform_v0_2_0(arguments = {})
data = {
version: Gitlab::VERSION,
revision: Gitlab.revision
}
if arguments[:include_metadata]
data[:metadata] = { build_date: Time.current }
end
formatted_content = [{ type: 'text', text: data[:version] }]
::Mcp::Tools::Base::Response.success(formatted_content, data)
end
- 최신 버전을 사용하도록
perform_default를 업데이트합니다:
override :perform_default
def perform_default(arguments = {})
perform_v0_2_0(arguments)
end
API 도구의 경우:
API 도구는 자동으로 버전 0.1.0을 기본값으로 사용합니다. 필요한 경우 경로 설정에 버전을 지정할 수 있습니다:
route_setting :mcp, tool_name: :get_issue,
params: [:id, :issue_iid],
version: '1.0.0'
경로에서의 API 도구는 도구당 단일 버전을 사용합니다. 여러 버전이 필요한 도구의 경우 커스텀 도구로 구현하는 것을 고려하세요.
버전 지원 정책:
프레임워크는 버전이 지정되지 않은 경우 자동으로 최신 버전을 사용합니다. 소비자는 도구 호출 중에 특정 버전을 요청할 수 있습니다. 버전을 폐기할 때는 다중 버전 호환성 가이드라인을 따르세요.
도구 이름 변경#
도구 이름 변경은 하위 호환성을 유지하기 위해 도구 별칭을 사용해야 합니다. 연결된 클라이언트는 도구 이름을 캐시하며 도구 이름이 변경될 때 자동으로 새로 고치지 않습니다. 이 머지 리퀘스트에서 도입된 별칭 시스템은 기존 통합을 중단하지 않고 우아한 이름 변경을 허용합니다.
별칭이 필요한 이유:
MCP 클라이언트는 tools/list에서 도구 목록을 캐시하며 도구가 변경될 때 자동으로 다시 가져오지 않습니다. 도구 이름을 변경하면 클라이언트가 존재하지 않는 도구 이름을 호출하여 오류나 무한 대기가 발생합니다. MCP 사양은 변경 사항을 클라이언트에 알리기 위해 notifications/tools/list_changed를 지원하지만 GitLab MCP 서버는 이를 구현하지 않습니다(이 이슈에서 추적 중).
구현 단계:
- 도구 클래스에서
tool_aliases를 오버라이드하여 이전 이름을 포함합니다:
module Mcp
module Tools
class RenamedService < Base::AggregatedService
override :tool_name
def self.tool_name
'new_name'
end
override :tool_aliases
def self.tool_aliases
['old_name']
end
end
end
end
route_setting :mcp를 통해 정의된 API 도구의 경우, 클래스 메서드를 오버라이드하는 대신 tool_aliases: 설정으로 별칭을 선언합니다. ApiTool은 모든 경로가 공유하는 단일 클래스이므로 별칭은 경로별로 지정해야 합니다:
route_setting :mcp, tool_name: :new_name,
params: [:id],
tool_aliases: [:old_name]
-
새 도구 이름을 사용하도록 모든 참조를 업데이트합니다:
tool_name:이 있는 경로 설정- 테스트 파일
- 문서
- 하드코딩된 도구 이름 참조
-
Mcp::Tools::Manager는get_tool호출 중에 별칭을 자동으로 해결하므로 이전 이름을 사용하는 클라이언트는 계속 작동합니다.
중요 사항:
list_tools는 별칭이 아닌 표준 도구 이름만 반환합니다.- 별칭은 모든 도구 유형에서 작동합니다. 커스텀, GraphQL 및 집계된 도구는 도구 클래스에서
self.tool_aliases를 오버라이드합니다. API 도구는tool_aliases:경로 설정을 통해 별칭을 선언합니다. aggregators:도 함께 설정하는 경로에서tool_aliases:는 효과가 없습니다. 집계된 도구의 별칭은 집계기 클래스의self.tool_aliases에서 가져옵니다.- 별칭 해결은 모든 도구 레지스트리를 확인하는
Manager#resolve_alias에서 발생합니다. - 클라이언트가 도구 목록을 새로 고칠 충분한 시간이 지난 후 향후 릴리스에서 별칭을 제거할 계획입니다.
폐기 타임라인:
릴리스 M: 별칭 추가 및 도구 이름 변경 릴리스 M+1: 클라이언트가 도구 목록을 새로 고칠 시간이 지난 후 별칭 제거
이 접근법은 도구 이름 변경 중에 연결된 클라이언트에 대한 무중단을 보장합니다.
집계된 도구에서 액션 분리#
여러 작업을 하나의 파라미터(예: action 또는 불리언 플래그) 뒤에 묶은 집계된 도구는 list/save 분리 규칙에 따라 컬렉션 읽기 액션을 위한 전용 list_ 도구를 가질 수 있습니다. 이름 변경과 달리 호출 형태가 바뀌므로(호출자가 더 이상 선택자 파라미터를 전달하지 않음) 도구 별칭으로는 동작을 보존할 수 없습니다. 이전 액션을 사용하던 호출자는 새 도구로 명시적으로 마이그레이션해야 합니다.
MCP 서버 도구에서 이전 도구의 블록에 [Removed] 항목을 추가해 어떤 액션이 어느 도구로 이동했는지 기록하고, 새 도구에 대한 일반적인 [Introduced] 항목도 함께 문서화하세요. 예시는 해당 페이지의 list_pipelines 및 manage_pipeline 항목을 참조하세요.