우리가 Bifrost에 MCP 지원을 구축한 방법 (그리고 Agent Security에 대해 배운 점)
Source: Dev.to
Bifrost용 MCP 지원을 시작했을 때…
I thought it would be straightforward: connect to MCP servers, proxy tool calls, done.
Turns out, making this production‑ready meant solving problems that the MCP spec doesn’t even address.
Bifrost
절대 중단되지 않는 AI 애플리케이션을 가장 빠르게 구축하는 방법
Bifrost는 고성능 AI 게이트웨이로, 단일 OpenAI‑호환 API를 통해 15+ providers(OpenAI, Anthropic, AWS Bedrock, Google Vertex 등)와의 접근을 통합합니다. 몇 초 만에 배포하고 설정이 필요 없으며 자동 장애 조치, 로드 밸런싱, 의미 기반 캐싱, 엔터프라이즈‑급 기능을 제공합니다.
빠른 시작
1분 이내에 제로부터 프로덕션 준비가 된 AI 게이트웨이까지 구축합니다.
단계 1 – Bifrost 게이트웨이 시작
로컬에 설치하고 실행하기
npx -y @maximhq/bifrost
또는 Docker 사용
docker run -p 8080:8080 maximhq/bifrost
단계 2 – 웹 UI로 구성하기
# 내장 웹 인터페이스 열기
open http://localhost:8080
단계 3 – 첫 번째 API 호출하기
curl -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o-mini",
"messages": [{"role": "user", "content": "Hello, Bifrost!"}]
}'
이게 전부입니다! AI 게이트웨이가 시각적 구성, 실시간 모니터링 등을 위한 웹 인터페이스와 함께 실행 중입니다.
AI 에이전트의 문제
AI 에이전트는 실제 인프라에 연결하려고 할 때 심각한 한계에 부딪힙니다.
에이전트가 데이터베이스를 조회하거나, 파일을 읽거나, API를 호출하도록 하고 싶나요? 각 사용 사례마다 맞춤형 통합 코드를 작성하게 됩니다.
Model Context Protocol (MCP) 은 이를 바꿉니다. MCP는 AI 모델이 런타임에 외부 도구를 발견하고 사용할 수 있는 표준 방식을 제공합니다. 통합을 하드코딩하는 대신, 도구를 노출하는 MCP 서버를 띄우면 AI 모델이 무엇이 사용 가능한지 스스로 파악하고 활용합니다.
실제 배포에서 관찰된 세 가지 큰 문제
- 보안 재난이 일어날 위험 – 대부분의 구현은 AI 모델이 원하는 어떤 도구든 실행하도록 허용합니다. 감독도, 로깅도 없습니다. 하나의 잘못된 프롬프트가 운영 데이터베이스를 업데이트하거나 파일을 삭제할 수 있습니다.
- 관측성 부재 – 문제가 발생했을 때 어떤 도구가 호출됐는지, 어떤 파라미터가 사용됐는지, 무엇이 실패했는지 전혀 알 수 없습니다. 디버깅이 고고학이 됩니다.
- 운영 복잡성 – 수십 개의 MCP 서버와 연결을 관리하고, 장애를 처리하며, 접근을 제어하는 일 – 이러한 문제들은 프로토콜 자체만으로는 해결되지 않습니다.
왜 Bifrost는 MCP 지원을 포함하는가
Bifrost에 MCP 지원을 직접 구현했습니다. 단순한 클라이언트가 아니라 프로덕션 수준 에이전트 인프라를 위한 완전한 제어 플레인입니다.
우리는 MCP 서버에 연결하는 네 가지 방법을 지원하며, 각각 다른 문제를 해결합니다:
| 연결 유형 | 설명 | 일반적인 지연 시간 | 이상적인 사용 사례 |
|---|---|---|---|
| 인‑프로세스 | 도구를 Bifrost 메모리 내에서 직접 실행합니다. Go에서 타입이 지정된 핸들러를 등록합니다. | ~0.1 ms (네트워크 없음) | 별도의 프로세스가 필요 없는 내부 비즈니스 로직. |
| 로컬 프로세스 | 외부 프로세스를 실행하고 stdin/stdout으로 통신합니다. Python/Node.js MCP 서버에 적합합니다. | 1‑10 ms | 파일 시스템 작업, 스크립트, 혹은 로컬 도구 전반. |
| 원격 HTTP | HTTP를 통해 원격 MCP 서버와 통신합니다. | 10‑500 ms (네트워크 의존) | 확장 가능한 마이크로서비스, 데이터베이스 도구, 인증된 API. |
| 서버 전송 이벤트 (SSE) | 실시간 업데이트를 스트리밍하는 지속 연결. | 소스에 따라 다름 | 모니터링 도구, 실시간 대시보드, 이벤트 기반 데이터. |
예시: 인‑프로세스 도구 등록 (Go)
type CalculatorArgs struct {
Operation string `json:"operation"`
A float64 `json:"a"`
B float64 `json:"b"`
}
func calculatorHandler(args CalculatorArgs) (string, error) {
switch args.Operation {
case "add":
return fmt.Sprintf("%.2f", args.A+args.B), nil
case "multiply":
return fmt.Sprintf("%.2f", args.A*args.B), nil
default:
return "", fmt.Errorf("unsupported operation")
}
}
// Register the tool with Bifrost
client.RegisterMCPTool(
"calculator",
"Perform arithmetic",
calculatorHandler,
schema,
)
컴파일 시 타입 검사가 런타임 이전에 버그를 잡아냅니다.
예시: 원격 HTTP 도구 (데이터베이스)
# Bifrost configuration snippet
ToolManagerConfig: &schemas.MCPToolManagerConfig{
ToolsToAutoExecute: []string{
"filesystem/read_file",
"database/query_readonly",
},
ToolExecutionTimeout: 30 * time.Second,
}
명시적으로 승인한 도구만 자동으로 실행됩니다. 그 외의 모든 도구는 수동 승인이 필요하므로 재해를 방지하면서도 에이전트를 빠르게 유지하여 안전한 작업을 수행할 수 있습니다.
Source: …
세밀한 도구 노출
요청당 사용할 수 있는 도구를 필터링할 수 있습니다:
curl -X POST http://localhost:8080/v1/chat/completions \
-H "x-bf-mcp-include-clients: secure-database,audit-logger" \
-H "x-bf-mcp-include-tools: secure-database/*,audit-logger/log_access" \
-d '{"model": "gpt-4o-mini", "messages": [...]}'
- 에이전트는 지정한 도구만 볼 수 있습니다.
- 고객용 챗봇은 관리자 도구에 접근할 수 없습니다.
- 금융 애플리케이션은 에이전트를 읽기 전용 작업으로 제한할 수 있습니다.
- 와일드카드(
database/*)를 지원하여 해당 데이터베이스 도구 전체를 포함합니다.
이 방법은 요청당, 도구당 제어를 제공함으로써 권한 상승 문제를 해결합니다.
보안 모델
기본적으로 Bifrost는 도구 호출을 제안으로 간주하며, 명령으로 취급하지 않습니다. AI 모델이 도구를 사용하려고 하면 요청을 애플리케이션에 반환하고, 실행 여부를 사용자가 결정합니다. 이를 통해 위험한 작업에 대해 인간이 감독할 수 있습니다.
완전 자동 실행이 필요하다면 에이전트 모드를 활성화하고 안전한 도구를 화이트리스트에 추가하십시오(위의 구성 예시와 같이).
요약
- 관찰 가능성 – 모든 도구 호출이 기록되며 추적할 수 있습니다.
- 보안 – 기본적으로 인간이 루프에 포함됩니다; 안전한 자동화를 위한 선택적 화이트리스트.
- 운영 단순성 – 하나의 게이트웨이, 네 가지 연결 모드, 통합 구성.
Bifrost + MCP = 빠르고, 관찰 가능하며, 안전한 프로덕션 준비 AI 에이전트.
실행 패턴
우리는 두 가지 실행 패턴을 만들었습니다. 서로 다른 사용 사례마다 다른 접근 방식이 필요하기 때문입니다:
1. 에이전트 모드
- AI는 한 번에 하나의 도구를 호출합니다.
- 결과를 보고 생각한 뒤, 다음 도구를 호출합니다.
- 각 단계에서 가시성을 원하는 대화형 에이전트에 이상적입니다.
2. 코드 모드
- AI는 여러 도구를 하나의 스크립트에서 조정하는 TypeScript를 작성합니다.
const files = await listFiles("/project");
const results = await Promise.all(
files.map(file => analyzeFile(file))
);
return summarize(results);
- 코드는 원자적으로 실행되어 배치 작업이 훨씬 빠릅니다.
- 여러 LLM 라운드‑트립을 피하므로 지연 시간이 낮아집니다.
- 트레이드‑오프: 도구별 승인을 잃게 되며, 코드는 실행되거나 실행되지 않습니다.
일반적인 사용 사례
- 코드 모드 – 수십 개의 파일을 읽고, 쿼리를 실행하며, 보고서를 생성해야 하는 데이터‑분석 워크플로.
- 에이전트 모드 – 데이터베이스 쿼리를 실행하기 전에 검토하고 싶은 고객‑지원 시나리오.
도구 탐색 및 통신
- Tool discovery는 예상보다 빠릅니다 – MCP 서버에서 50개 이상의 도구 목록을 가져오는 데 100 ms 미만이 걸립니다.
- STDIO latency는 놀라울 정도로 낮습니다: 오버헤드가 1–2 ms에 불과해 거의 눈에 띄지 않습니다.
- HTTP는 네트워크 왕복으로 인해 훨씬 더 많은 지연을 초래합니다.
타입 안전성 및 요청 필터링
- Type safety는 많은 버그를 방지합니다. Go 구조체를 사용하는 인‑프로세스 도구는 컴파일 타임에 문제를 포착하여, JSON 검증으로 인해 런타임 오류가 발생하는 것을 방지합니다.
- Request‑level filtering은 전역 설정보다 더 강력합니다. 요청별로 사용 가능한 도구를 변경할 수 있어 정적 구성보다 훨씬 더 많은 제어가 가능합니다.
실제 성능 수치
| Component | Avg. Latency | Notes |
|---|---|---|
| STDIO 파일시스템 도구 | 1.2 ms | |
| HTTP 데이터베이스 도구 | 15 ms | 로컬 네트워크 |
| 인‑프로세스 계산 도구 | 0.08 ms | |
| STDIO 연결당 메모리 | ~2 MB | |
| 도구 탐색 (50개 도구) | 85 ms | Go 런타임; Python/Node.js MCP 서버는 더 느리지만, 아키텍처는 잘 확장됩니다. |
MCP 지원
- MCP 지원은 Bifrost에서 라이브됩니다.
- 설정은 간단합니다: MCP 서버를 구성하고, 자동 실행 가능한 도구를 지정한 뒤, 요청을 시작하세요.
문서화
- 우리는 MCP 문서에 네 가지 연결 유형 모두, 에이전트 vs. 코드 모드, 그리고 요청‑레벨 필터링을 문서화했습니다.
- 일반적인 패턴에 대한 예제가 제공됩니다:
- 파일 시스템
- 데이터베이스
- 웹 API
Closing Thoughts
실제 인프라와 상호작용해야 하는 에이전트를 구축하고 있다면, 이 접근 방식은 맞춤형 통합 코드보다 더 깔끔하며, 프로덕션에 필요한 가시성 및 보안 제어를 제공합니다.
코드는 오픈 소스이며 – 내부 구현이 궁금하다면 구현을 확인해 보세요. 우리는 실제 사용 사례를 기반으로 업데이트를 제공하므로 피드백을 언제든 환영합니다.