MCP Actions Backend
MCP Actions Backend은 Actions Registry에 등록된 액션을 MCP 도구로 노출합니다.
출처: 문서
본문
MCP Actions Backend은 Actions Registry에 등록된 액션을 MCP 도구로 노출합니다.
설치
이 플러그인은 @backstage/plugin-mcp-actions-backend 패키지를 통해 설치됩니다. 백엔드 패키지에 추가하려면 다음 명령을 실행하세요.
루트 디렉토리에서
yarn --cwd packages/backend add @backstage/plugin-mcp-actions-backend
그런 다음 백엔드에 플러그인을 추가하세요.
packages/backend/src/index.ts
const backend = createBackend();// ...backend.add(import('@backstage/plugin-mcp-actions-backend'));// ...backend.start();
Actions 구성
MCP 도구로 노출하고 싶은 플러그인 목록으로 pluginSources 구성을 채우세요.
backend: actions: pluginSources: - 'catalog' - 'my-custom-plugin'
액션 필터링에 대한 자세한 내용은 filtering actions 문서를 참조하세요.
Action 속성
액션을 등록할 때 attributes 필드를 설정해 액션의 동작을 설명하세요. 이렇게 하면 클라이언트가 정보에 입각한 결정을 내릴 수 있습니다. 예를 들어 파괴적인 액션을 호출하기 전에 사용자에게 경고하거나, 읽기 전용 액션을 확인 없이 실행하도록 허용합니다.
기본값은 보수적입니다. 설정되지 않으면 액션은 비멱등(non-idempotent)이고 읽기 전용이 아닌 것으로 간주됩니다. destructive는 readOnly가 true가 아닌 한 true로 기본 설정되며, readOnly가 true인 경우 false로 기본 설정됩니다. 기본값이 액션의 기능을 나타내지 않을 때는 명시적으로 설정하세요.
전체 속성 정의와 기본값은 Action Attributes Reference를 참조하세요.
단일 MCP 서버 이름과 설명
다음 구성으로 Backstage MCP 서버의 이름과 설명을 설정할 수 있습니다.
app-config.yaml
mcpActions: name: 'My Company Backstage' # defaults to "backstage" description: 'Tools for managing your software catalog, creating new services from templates, and exploring your developer portal' # optional
tip
이름과 설명을 정할 때 다음을 염두에 두세요. 설명은 이 서버를 사용할지 결정하는 AI 에이전트의 관점에서 "이 도구들로 무엇을 할 수 있나요?"에 답해야 합니다 — "이 서버는 무엇인가요?"가 아니라요. 즉 Backstage의 기능(catalog, scaffolder 등)을 설명해야 하며, MCP 프로토콜이나 서버 정체성을 설명해서는 안 됩니다.
서버 지침
MCP 클라이언트가 서버와 그 도구를 어떻게 사용해야 하는지 설명하는 지침을 제공할 수 있습니다. 서버는 초기화 중에 이 지침을 클라이언트에게 반환합니다.
app-config.yaml
mcpActions: instructions: 'Inspect existing catalog entities before creating new components.'
이름이 있는 서버(named servers)의 경우 각 서버에 대해 별도로 지침을 구성하세요.
이름 공간이 있는 도구 이름
기본적으로 MCP 도구 이름은 플러그인 간 충돌을 피하기 위해 플러그인 ID 접두사를 포함합니다. 예를 들어 my-custom-plugin이 greet-user로 등록한 액션은 my-custom-plugin.greet-user로 노출됩니다.
하위 호환성을 위해 짧은 이름이 필요하다면 이를 비활성화할 수 있습니다.
app-config.yaml
mcpActions: namespacedToolNames: false
여러 MCP 서버
기본적으로 플러그인은 사용 가능한 모든 액션을 노출하는 단일 MCP 서버를 /api/mcp-actions/v1에서 제공합니다. mcpActions.servers를 구성하면 액션을 여러 개의 집중된 서버로 나눌 수 있으며, 각 키가 별도의 MCP 서버 엔드포인트가 됩니다.
app-config.yaml
mcpActions: servers: catalog: name: 'Backstage Catalog' description: 'Tools for interacting with the software catalog' instructions: 'Inspect catalog entities before making changes.' filter: include: - id: 'catalog:*' scaffolder: name: 'Backstage Scaffolder' description: 'Tools for creating new software from templates' instructions: 'Use this server after checking the catalog.' filter: include: - id: 'scaffolder:*'
이렇게 하면 두 개의 MCP 서버 엔드포인트가 생성됩니다.
-
http://localhost:7007/api/mcp-actions/v1/catalog -
http://localhost:7007/api/mcp-actions/v1/scaffolder
각 서버는 어떤 액션이 노출될지 제어하기 위해 액션 ID에 대한 glob 패턴이 있는 include 필터 규칙을 사용합니다. 예를 들어 id: 'catalog:*'는 catalog 플러그인이 등록한 모든 액션과 일치합니다.
기본 서버(/api/mcp-actions/v1)는 mcpActions.servers가 구성되어 있는지 여부와 관계없이 항상 사용 가능하며, 등록된 모든 액션을 항상 노출합니다. 이름이 있는 서버는 그것의 부분 집합이므로, 액션은 기본 서버와 원하는 만큼의 이름 있는 서버에 동시에 노출될 수 있습니다.
필터 규칙
include 및 exclude 필터 규칙은 액션 ID에 대한 glob 패턴과 속성 일치를 지원합니다. exclude 규칙이 include 규칙보다 우선합니다. include 규칙이 지정되면 액션은 노출되기 위해 최소한 하나의 include 규칙과 일치해야 합니다.
app-config.yaml
mcpActions: servers: catalog: name: 'Backstage Catalog' filter: include: - id: 'catalog:*' exclude: - attributes: destructive: true
인증 구성
기본적으로 Backstage 백엔드는 모든 요청에 인증을 요구합니다.
정적 토큰을 사용한 외부 접근
warning
이는 디바이스 인증이 완료될 때까지의 임시 해결 방법입니다.
앱 구성에서 정적 토큰으로 외부 접근을 구성하세요.
app-config.yaml
backend: auth: externalAccess: - type: static options: token: ${MCP_TOKEN} subject: mcp-clients accessRestrictions: - plugin: mcp-actions - plugin: catalog
안전한 토큰을 생성하세요.
node -p 'require("crypto").randomBytes(24).toString("base64")'
MCP_TOKEN 환경 변수를 설정하고 MCP 클라이언트가 다음을 보내도록 구성하세요.
Authorization: Bearer ***
외부 접근 토큰과 서비스 간 인증에 대한 자세한 내용은 Service-to-Service Auth 문서를 참조하세요.
OAuth 인증
MCP Actions Backend은 MCP 사양에 기반한 Client ID Metadata Documents(CIMD)를 지원합니다.
CIMD에는 다음 요구 사항이 있습니다.
-
새 프론트엔드 시스템(New Frontend System)을 사용해야 합니다.
-
@backstage/plugin-auth-backend플러그인이 구성되어 있어야 합니다. -
새
@backstage/plugin-auth프론트엔드 플러그인이 구성되어 있어야 합니다.
새 @backstage/plugin-auth 프론트엔드 플러그인을 설치하고 구성하려면 다음 단계를 따르세요.
@backstage/plugin-auth프론트엔드 플러그인을 설치합니다.
yarn --cwd packages/app add @backstage/plugin-auth
- 기능 발견(feature discovery)을 사용하면 플러그인이 자동으로 추가됩니다. 명시적 등록을 선호한다면, 다음과 같이 플러그인을 기능으로 등록하세요.
packages/app/src/App.tsx
import authPlugin from '@backstage/plugin-auth';const app = createApp({ features: [ // ...other features authPlugin, ],});
Client ID Metadata Documents
Client ID Metadata Documents(CIMD)는 MCP 서버에 권장되는 OAuth 인증 방법입니다. MCP 사양은 CIMD를 기본 클라이언트 등록 접근 방식으로 지정하며, SHOULD 수준의 규범적 언어를 사용합니다.
CIMD를 사용하면 MCP 클라이언트 설정에서 토큰을 수동으로 구성할 필요가 없습니다. 대신 클라이언트가 사용자를 대신해 토큰을 요청할 수 있습니다. MCP 서버를 Cursor나 Claude 같은 MCP 클라이언트에 추가하면, Backstage 인스턴스(auth 플러그인 기반)에 승인을 요구하는 팝업이 열립니다.
auth-backend 플러그인에서 auth.clientIdMetadataDocuments.enabled 플래그를 사용해 CIMD를 활성화하세요.
app-config.yaml
auth: clientIdMetadataDocuments: enabled: true # Optional: override which client_id URLs are allowed. # Defaults to Claude, VS Code, ChatGPT Codex, and the built-in Backstage CLI. # Note: setting this replaces the Claude, VS Code, and ChatGPT Codex # defaults entirely. The built-in CLI client is always allowed, since # this backend serves its metadata document itself. # allowedClientIdPatterns: # - 'https://claude.ai/*' # - 'https://vscode.dev/*' # - 'https://chatgpt.com/oauth/codex/*/client.json' # - 'https://my-custom-client.example.com/*' # Optional: override which redirect URIs are allowed. # Defaults to loopback addresses (localhost, 127.0.0.1, [::1]). # allowedRedirectUriPatterns: # - 'http://localhost:*/*' # - 'http://127.0.0.1:*/*' # - 'http://[::1]:*/*'
동적 클라이언트 등록(더 이상 사용되지 않음)
caution
동적 클라이언트 등록(DCR)은 Backstage에서 더 이상 사용되지 않으며 새로운 배포에 사용해서는 안 됩니다. MCP 사양은 2025년 11월 개정에서 DCR을 SHOULD에서 MAY 요구 사항으로 격하하며, 이를 하위 호환성 옵션으로 특성화했습니다. DCR은 결국 MCP 사양과 Backstage 모두에서 제거될 것입니다. Client ID Metadata Documents로 마이그레이션하세요.
기존 DCR 구성은 계속 작동하지만 시작 시 더 이상 사용되지 않음 경고를 기록합니다. DCR을 사용 중이라면 CIMD로 마이그레이션할 계획을 세우세요.
app-config.yaml
auth: experimentalDynamicClientRegistration: enabled: true # Optional: restrict which redirect URIs are allowed. # Defaults to Cursor and loopback addresses (localhost, 127.0.0.1, [::1]). # allowedRedirectUriPatterns: # - 'cursor://*' # - 'http://localhost:*/*' # - 'http://127.0.0.1:*/*' # - 'http://[::1]:*/*'
MCP 클라이언트 구성
MCP 서버는 Streamable HTTP 프로토콜을 사용합니다.
엔드포인트
기본 엔드포인트는 http://localhost:7007/api/mcp-actions/v1입니다.
{ "mcpServers": { "backstage-actions": { "url": "http://localhost:7007/api/mcp-actions/v1", "headers": { "Authorization": "Bearer ${MCP_TOKEN}" } } }}
${MCP_TOKEN} 환경 변수는 외부 접근 정적 토큰이 됩니다.
여러 서버
mcpActions.servers가 구성되면 각 서버 키가 URL의 일부가 됩니다. 예를 들어 catalog와 scaffolder라는 서버의 경우:
-
http://localhost:7007/api/mcp-actions/v1/catalog -
http://localhost:7007/api/mcp-actions/v1/scaffolder
{ "mcpServers": { "backstage-catalog": { "url": "http://localhost:7007/api/mcp-actions/v1/catalog", "headers": { "Authorization": "Bearer ${MCP_TOKEN}" } }, "backstage-scaffolder": { "url": "http://localhost:7007/api/mcp-actions/v1/scaffolder", "headers": { "Authorization": "Bearer ${MCP_TOKEN}" } } }}
메트릭
MCP Actions Backend은 다음 작업에 대한 메트릭을 내보냅니다.
-
mcp.server.operation.duration: 개별 MCP 작업을 처리하는 데 걸린 시간 -
mcp.server.session.duration: 서버 관점에서의 MCP 세션 지속 시간
이 메트릭을 사용 가능하게 만드는 방법은 OpenTelemetry 튜토리얼을 참조하세요.
트레이싱
MCP Actions Backend은 Tracing Service를 통해 각 tools/call 호출에 대한 트레이스 스팬을 내보내며, OpenTelemetry 서버 측 MCP 의미 규칙을 따릅니다. 각 스팬은 tools/call <toolname> 이름과 서버 kind를 사용하며 표준 MCP 속성(mcp.method.name, gen_ai.tool.name, gen_ai.operation.name)을 포함합니다. 알려진 Backstage 오류(예: InputError 또는 NotFoundError)는 잡혀서 isError: true 도구 응답으로 반환됩니다 — 이 경우 스팬은 error.type=tool_error로 표시됩니다. 처리되지 않은 예외는 Tracing Service에 의해 자동으로 기록되며 스팬 상태가 ERROR로 설정됩니다.
이러한 속성 외에도 Tracing Service는 인증된 프린시펄의 유형을 backstage.principal.type(user, service, none 중 하나)으로 자동 첨부합니다. 각 tools/call 스팬은 또한 호출된 액션을 소유한 플러그인인 backstage.plugin.id(예: catalog, scaffolder)로 귀속됩니다 — 기본 mcp-actions 값을 덮어써서 트레이싱 백엔드가 MCP 전송이 아닌 소스 플러그인으로 활동을 필터링할 수 있게 합니다.
배기지 전파
MCP Actions 라우터는 수신 HTTP 요청 헤더에서 OpenTelemetry 컨텍스트를 전파하여 트레이스 부모와 배기지가 MCP 전송 계층을 통해 살아남게 합니다. OpenTelemetry gen_ai.* 속성 레지스트리의 다음 저카디널리티 식별자 항목들은 MCP 클라이언트가 배기지에 설정하면 tools/call 스팬의 속성으로 자동 전달됩니다.
-
gen_ai.agent.id -
gen_ai.agent.name -
gen_ai.conversation.id -
gen_ai.provider.name -
gen_ai.request.model
이를 통해 트레이싱 백엔드는 추가 구성 없이 MCP 도구 호출을 원래 에이전트, 대화 또는 모델로 상관시킬 수 있습니다. 다른 gen_ai.* 배기지 항목은 의도적으로 전달되지 않습니다 — 배기지는 임의의 업스트림 호출자가 설정할 수 있으며, 광범위한 접두사 필터는 클라이언트가 고카디널리티 또는 페이로드 형태의 키(예: gen_ai.tool.call.result, gen_ai.prompt)를 스팬에 밀어 넣어 도구 페이로드 캡처 플래그를 우회하게 할 수 있기 때문입니다.
인증된 최종 사용자 캡처
Tracing Service는 인증된 프린시펄의 신원을 enduser.id(사용자 프린시펄의 경우 사용자 엔티티 ref, 서비스 프린시펄의 경우 서비스 subject)로 추가로 포함할 수 있습니다. 이는 백엔드 전체 구성 플래그 뒤에 있으며 기본적으로 비활성화되어 있습니다.
app-config.yaml
backend: tracing: capture: endUser: true # defaults to false
이 플래그는 MCP Actions뿐만 아니라 Tracing Service를 통해 스팬을 만드는 모든 플러그인에 적용됩니다.
도구 인자와 결과 캡처
mcpActions.tracing.capture.toolPayload가 활성화되면 도구의 입력 인자와 출력 결과가 gen_ai.tool.call.arguments와 gen_ai.tool.call.result로 스팬에 기록됩니다.
app-config.yaml
mcpActions: tracing: capture: toolPayload: true # defaults to false
warning
이 속성들은 민감한 정보 — 엔티티 페이로드, scaffolder 입력, 자유 형식 텍스트 등 — 를 포함할 수 있으므로 OpenTelemetry GenAI 의미 규칙에서 Opt-In으로 표시됩니다. 트레이싱 백엔드의 데이터 처리가 MCP 도구가 받고 만드는 페이로드 종류에 적절한 경우에만 이 플래그를 활성화하세요.
이 스팬들을 사용 가능하게 만드는 방법은 OpenTelemetry 튜토리얼을 참조하세요.
문제 해결
OAuth 인증 중 invalid_client 오류
MCP 클라이언트가 인증 시 invalid_client 오류를 보여준다면 다음을 확인하세요.
- 구성 위치:
auth.clientIdMetadataDocuments(또는auth.experimentalDynamicClientRegistration) 구성은backend.auth:아래가 아니라 최상위auth:키 아래 있어야 합니다.
app-config.yaml
# Correctauth: clientIdMetadataDocuments: enabled: true# Incorrect — this will not workbackend: auth: clientIdMetadataDocuments: enabled: true
-
VS Code의 캐시된 자격 증명: VS Code는 이전 시도의 오래된 OAuth 클라이언트 ID를 캐시할 수 있습니다. VS Code 명령 팔레트를 열고
Authentication: Remove Dynamic Authentication Providers를 실행한 다음 Backstage 항목(예:localhost:7007)을 선택해 지우세요. MCP 서버를 다시 시작하고 다시 시도하세요. -
리다이렉트 URI 패턴: 최근 Backstage 버전을 사용 중이라면
allowedRedirectUriPatterns를 명시적으로 구성해야 할 수 있습니다. VS Code의 경우vscode.dev와 루프백 주소에 대한 패턴을 포함하세요.
app-config.yaml
auth: clientIdMetadataDocuments: enabled: true allowedRedirectUriPatterns: - 'https://vscode.dev/*' - 'https://insiders.vscode.dev/*' - 'http://localhost:*/*' - 'http://127.0.0.1:*/*' - 'http://[::1]:*/*'
- 새 프론트엔드 시스템 요구 사항: OAuth 인증(CIMD와 DCR 모두)은 새 프론트엔드 시스템이 필요합니다. 이전 프론트엔드 시스템을 사용 중이라면 OAuth 인증을 사용하려면 새 프론트엔드 시스템으로 마이그레이션하세요. 마이그레이션이 불가능하다면 폴백으로 정적 토큰을 사용하세요.