Just describe what you need. Bkend builds it for you 🚀 
Get Started!
Sign In
📚

MCP 연동 메뉴얼

AI 에디터(Claude Code, Cursor, Google Antigravity)에 Bkend MCP를 연동하여 백엔드 인프라를 자연어로 관리하는 방법을 안내합니다.

🤔 MCP란?

MCP (Model Context Protocol)는 AI가 외부 도구를 사용할 수 있게 해주는 프로토콜입니다.

Bkend MCP를 연동하면?

AI 에디터에서 자연어로 Bkend 백엔드를 관리할 수 있어요:
💬
사용자: "Todo 테이블 만들어줘. 제목, 완료여부, 우선순위 필드 필요해"
AI가 자동으로 :
✅ MongoDB 스키마 설계
✅ REST API 4종 생성 (GET/POST/PATCH/DELETE)
✅ 필드 타입 검증 규칙 추가
✅ 인덱스 최적화
✅ 권한 설정
...
결과:
/data/todos API 즉시 사용 가능! ⚡

시작하기

1️⃣ 처음이신가요?

배울 내용:
Organization ID, API Key 발급 받기
AI 에디터 설정하기 (3개 중 선택)
첫 테이블 만들어보기
프론트엔드 연동하기
이런 분들에게 추천:
✅ Bkend MCP를 처음 사용하는 분
✅ 빠르게 실습하며 배우고 싶은 분

2️⃣ AI에게 어떻게 말해야 할지 모르겠어요

배울 내용:
애매한 요청 vs 명확한 요청
실전 예시 모음 (테이블 생성, 검색 최적화, 권한 설정)
피해야 할 패턴
이런 분들에게 추천:
✅ AI가 내 요청을 잘 이해하지 못하는 것 같아요
✅ 더 효과적으로 요청하고 싶어요

3️⃣ 더 깊이 활용하고 싶어요

아래 고급 기능 섹션으로 스크롤 ⬇️

고급 기능

기본 사용법을 익혔다면, 아래 기능들을 활용해보세요.

스키마 설계

MongoDB 스키마 타입 가이드

지원하는 필드 타입

타입
설명
예시
String
문자열
이름, 이메일, 설명
Number
숫자
나이, 가격, 수량
Boolean
참/거짓
완료 여부, 활성화 상태
Date
날짜/시간
생성일, 마감일
Array
배열
태그 목록, 파일 목록
Object
객체
주소 (시/구/동), 설정 정보
ObjectId
참조 ID
다른 테이블 참조

필드 옵션

{ "fieldName": "email", "type": "String", "required": true, // 필수 필드 "unique": true, // 고유 값 (중복 불가) "default": "user@example.com", // 기본값 "minLength": 5, // 최소 길이 "maxLength": 100, // 최대 길이 "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$" // 정규식 }

AI에게 요청하는 방법

좋은 예:
"사용자 테이블에 이메일 필드 추가해줘. 필수 항목이고, 중복되면 안 돼. 이메일 형식이 맞는지 검증도 필요해."
→ AI가 자동으로 required: true, unique: true, 이메일 패턴 검증을 추가합니다.
관계형 데이터 설계하기

1:N 관계 (일대다)

시나리오: 한 음식점은 여러 메뉴를 가질 수 있음
AI에게 요청:
"배달 앱 만들려고 해. 음식점 정보(이름, 주소, 전화번호)랑 메뉴(이름, 가격, 카테고리)를 저장해야 해. 한 음식점은 여러 메뉴를 가질 수 있어."
AI가 생성하는 구조:
// restaurants 테이블 { "_id": ObjectId, "name": String, "address": String, "phone": String } // menus 테이블 { "_id": ObjectId, "restaurantId": ObjectId, // restaurants 테이블 참조 "name": String, "price": Number, "category": String }

N:M 관계 (다대다)

시나리오: 한 학생은 여러 수업을 들을 수 있고, 한 수업은 여러 학생이 들을 수 있음
AI에게 요청:
"학생 관리 앱 만들려고 해. 학생 정보(이름, 학번)와 수업 정보(수업명, 교수명)를 저장하고, 한 학생은 여러 수업을 들을 수 있고, 한 수업은 여러 학생이 들을 수 있어."
AI가 생성하는 구조:
// students 테이블 { "_id": ObjectId, "name": String, "studentId": String } // courses 테이블 { "_id": ObjectId, "courseName": String, "professor": String } // enrollments 테이블 (중간 테이블) { "_id": ObjectId, "studentId": ObjectId, // students 테이블 참조 "courseId": ObjectId, // courses 테이블 참조 "enrolledAt": Date }
특정 값만 허용하고 싶을 때 사용합니다.
AI에게 요청:
"상품 테이블 만들어줘. 상태는 '판매중', '품절', '단종' 중 하나만 가능해야 해."
AI가 생성하는 구조:
{ "status": { "type": "String", "enum": ["판매중", "품절", "단종"], "default": "판매중" } }

권한 관리

역할 기반 권한 설정

기본 역할

Bkend는 기본적으로 2개의 역할을 제공합니다:
역할
설명
기본 권한
admin
관리자
CRUD 모두 가능
user
일반 사용자
CRUD 모두 가능
self
Beta 제약: 현재는 admin, self, user 3개 역할만 제공되며, 커스텀 역할 추가는 정식 버전에서 지원 예정입니다.

CRUD 권한 조합

각 역할은 다음 4가지 권한을 개별적으로 설정할 수 있습니다:
Create (C): 데이터 생성
Read (R): 데이터 조회
Update (U): 데이터 수정
Delete (D): 데이터 삭제

실전 예시

시나리오 1: 읽기 전용 사용자
AI에게 요청:
"공지사항 테이블 만들어줘. 관리자는 작성/수정/삭제 가능하고, 일반 사용자는 보기만 가능하게 해줘."
결과:
admin: ✅ Create, ✅ Read, ✅ Update, ✅ Delete
user: ❌ Create, ✅ Read, ❌ Update, ❌ Delete
시나리오 2: 본인 데이터만 수정/삭제 가능
AI에게 요청:
"게시글 테이블 만들어줘. 누구나 글을 쓰고 볼 수 있지만, 수정과 삭제는 본인이 쓴 글만 가능하게 해줘."
결과:
admin: ✅ CRUD 모두
user: ✅ Create, ✅ Read, ✅ Update (본인 글만), ✅ Delete (본인 글만)
💡 본인 데이터 필터링은 프론트엔드에서 처리해야 합니다.
API 호출 시 createdBy 필드로 필터링:
// 현재 사용자 ID로 필터링 const filters = JSON.stringify({ createdBy: currentUser.id }); await apiClient.get(`/data/posts?andFilters=${encodeURIComponent(filters)}`);

성능 최적화

인덱스 전략

인덱스란?

데이터베이스에서 검색 속도를 빠르게 하기 위한 색인입니다.
비유:
인덱스 없음 = 책에서 특정 단어를 찾기 위해 처음부터 끝까지 읽기
인덱스 있음 = 책 뒤쪽 색인을 보고 바로 페이지 찾기

언제 인덱스를 추가해야 하나요?

추가해야 하는 경우:
자주 검색하는 필드 (이메일, 이름 등)
정렬 기준으로 사용하는 필드 (생성일, 수정일 등)
중복을 방지해야 하는 필드 (unique 제약조건)
추가하지 말아야 하는 경우:
거의 검색하지 않는 필드
데이터 입력이 빈번한 테이블 (인덱스가 많으면 입력 속도 저하)

AI에게 요청하는 방법

예시 1: 단일 필드 인덱스
"사용자를 이메일로 검색할 때 느린데 빠르게 해줘."
→ AI가 email 필드에 인덱스를 추가합니다.
예시 2: 중복 방지 (Unique 인덱스)
"회원가입할 때 같은 이메일로 여러 번 가입되는 문제가 있어. 막아줘."
→ AI가 email 필드에 unique 인덱스를 추가합니다.
예시 3: 복합 인덱스
**쿼리 최적화 팁** ### 1. 필요한 필드만 조회하기 ❌ **나쁜 예:** ``` // 모든 필드 조회 (불필요한 데이터 전송) const users = await apiClient.get('/data/users'); ``` ✅ **좋은 예:** ``` // 필요한 필드만 지정 (API에서 지원 예정) // 현재는 프론트엔드에서 필터링 const users = await apiClient.get('/data/users'); const userNames = users.data.data.items.map(u => ({ id: u._id, name: u.name })); ``` ### 2. 페이지네이션 활용 ❌ **나쁜 예:** ``` // 모든 데이터 한 번에 조회 const todos = await apiClient.get('/data/todos'); ``` ✅ **좋은 예:** ``` // 페이지 단위로 조회 const todos = await apiClient.get('/data/todos?page=1&limit=20'); ``` ### 3. 서버 사이드 필터링 사용 ❌ **나쁜 예:** ``` // 클라이언트에서 필터링 (모든 데이터 전송) const allTodos = await apiClient.get('/data/todos'); const completed = allTodos.data.data.items.filter(t => t.completed); ``` ✅ **좋은 예:** ``` // 서버에서 필터링 (필요한 데이터만 전송) const filters = JSON.stringify({ completed: true }); const completed = await apiClient.get(`/data/todos?andFilters=${encodeURIComponent(filters)}`); ``` ### 4. 인덱스가 있는 필드로 정렬 ✅ **좋은 예:** ``` // createdAt에는 시스템 인덱스가 있음 const latest = await apiClient.get('/data/todos?sortBy=createdAt&sortDirection=desc'); ```"사용자를 이름과 나이로 함께 검색할 때 빠르게 해줘."
→ AI가 (name, age) 복합 인덱스를 추가합니다.

시스템 자동 생성 인덱스

모든 테이블에는 다음 4개의 인덱스가 자동으로 생성됩니다:
인덱스명
필드
용도
_id_
_id
Primary Key, 레코드 조회
idx_createdAt_desc
createdAt
생성일 기준 정렬
idx_updatedAt_desc
updatedAt
수정일 기준 정렬
idx_createdBy
createdBy
생성자별 조회
📌 시스템 인덱스는 삭제할 수 없습니다.
쿼리 최적화 팁

1. 필요한 필드만 조회하기

나쁜 예:
// 모든 필드 조회 (불필요한 데이터 전송) const users = await apiClient.get('/data/users');
좋은 예:
// 필요한 필드만 지정 (API에서 지원 예정) // 현재는 프론트엔드에서 필터링 const users = await apiClient.get('/data/users'); const userNames = users.data.data.items.map(u => ({ id: u._id, name: u.name }));

2. 페이지네이션 활용

나쁜 예:
// 모든 데이터 한 번에 조회 const todos = await apiClient.get('/data/todos');
좋은 예:
// 페이지 단위로 조회 const todos = await apiClient.get('/data/todos?page=1&limit=20');

3. 서버 사이드 필터링 사용

나쁜 예:
// 클라이언트에서 필터링 (모든 데이터 전송) const allTodos = await apiClient.get('/data/todos'); const completed = allTodos.data.data.items.filter(t => t.completed);
좋은 예:
// 서버에서 필터링 (필요한 데이터만 전송) const filters = JSON.stringify({ completed: true }); const completed = await apiClient.get(`/data/todos?andFilters=${encodeURIComponent(filters)}`);

4. 인덱스가 있는 필드로 정렬

좋은 예:
// createdAt에는 시스템 인덱스가 있음 const latest = await apiClient.get('/data/todos?sortBy=createdAt&sortDirection=desc');

데이터 관리

대량 데이터 작업

배치 생성 (정식 버전 예정)

현재는 API를 반복 호출하여 처리해야 합니다:
const items = [ { title: "할 일 1", completed: false }, { title: "할 일 2", completed: false }, { title: "할 일 3", completed: false } ]; // 순차 처리 for (const item of items) { await todosApi.create(item); } // 또는 병렬 처리 await Promise.all(items.map(item => todosApi.create(item)));
정식 버전 업데이트 예정: 배치 생성 API가 추가될 예정입니다.
데이터 마이그레이션

시나리오: 기존 필드 이름 변경

Question: 필드 이름을 변경하면 기존 데이터는 어떻게 되나요?
Answer:
✅ 새 필드가 추가됩니다
⚠️ 기존 필드는 그대로 남아있습니다 (자동으로 삭제되지 않음)
📝 프론트엔드에서 두 필드를 모두 고려해야 합니다
해결 방법:
1.
새 필드 추가
"todos 테이블에 dueDate 필드 추가해줘."
2.
프론트엔드에서 마이그레이션 처리
// 기존 데이터는 deadline, 새 데이터는 dueDate 사용 const todos = await todosApi.list(userId); const normalized = todos.map(t => ({ ...t, dueDate: t.dueDate || t.deadline // fallback 처리 }));
3.
기존 필드 삭제 (옵션)
"todos 테이블에서 deadline 필드 삭제해줘."

프론트엔드 연동

백엔드가 완성되었나요? 이제 프론트엔드에서 API를 호출해보세요.
포함된 내용:
인증 API (회원가입, 로그인, 사용자 정보 조회)
데이터 CRUD API (생성, 조회, 수정, 삭제)
필터링, 검색, 정렬
React/Vue 예시 코드
에러 처리

자주 묻는 질문

MCP 서버가 연결되지 않아요
< 진단 체크 리스트 >
✔️ Organization ID가 정확한가요?
콘솔 우측 상단 프로필 > 조직 설정에서 확인
복사할 때 앞뒤 공백이 들어가지 않았는지 확인
✔️ API Key가 유효한가요?
콘솔 > 설정 > API 키에서 상태 확인
만료되었다면 새 키 생성
✔️ 설정 파일 경로가 맞나요?
Claude Code: ~/.claude/settings.local.json 또는 .mcp.json
Cursor: ~/.cursor/mcp.json
Google Antigravity: ~/.gemini/antigravity/mcp_config.json
✔️ AI 에디터를 재시작했나요?
설정 파일 변경 후 반드시 재시작 필요

해결 방법

1단계: 로그 확인
# Claude Code cat ~/.claude/logs/mcp.log # Cursor cat ~/.cursor/logs/mcp.log
2단계: 설정 파일 재확인
# Claude Code cat ~/.claude/settings.local.json # 올바른 형식인지 확인 { "mcpServers": { "mcp-bkend": { "type": "http", "url": "https://api.bkend.ai/mcp", "headers": { "X-Organization-Id": "your_org_id", "X-Api-Key": "your_api_key" } } } }
3단계: 권한 확인
# 설정 파일 권한 확인 ls -la ~/.claude/settings.local.json # 읽기 권한이 없다면 chmod 644 ~/.claude/settings.local.json
프론트엔드에서 API 호출 실패해요
< 진단 체크리스트 >
✔️ 필수 헤더가 모두 포함되었나요?
{ "Authorization": "Bearer {access_token}", "X-Project-Id": "{project_id}", "X-Environment": "dev", "Content-Type": "application/json" }
✔️ CORS 에러인가요?
개발 환경: Vite/Webpack 프록시 설정 필요
프로덕션: CORS는 자동으로 처리됨
✔️ 인증 토큰이 유효한가요?
localStorage.getItem('access_token')으로 확인
만료되었다면 재로그인 필요

해결 방법

Vite 프록시 설정:
// vite.config.ts export default defineConfig({ server: { proxy: { '/api': { target: 'https://api-enduser.bkend.ai', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ''), }, }, }, });
테이블 생성에 실패했어요
< 일반적인 원인 >
1.
환경 배포가 완료되지 않음
콘솔에서 환경 상태 확인: dev 환경이 active인지 확인
배포 실패 시 프로젝트를 다시 생성해야 함 (Beta 제약)
2.
스키마 유효성 검증 실패
필드 타입이 올바른지 확인
필수 필드가 누락되지 않았는지 확인
3.
권한 문제
Organization ID가 올바른지 확인
API Key가 만료되지 않았는지 확인

해결 방법

1단계: 콘솔에서 환경 상태 확인
프로젝트 선택 → 환경 탭 → dev 상태 확인
2단계: 간단한 테이블로 테스트
"test라는 이름으로 간단한 테이블 만들어줘. title 필드 하나만."
3단계: 에러 메시지 공유
🐛 버그 리포트 또는 지원팀에 에러 메시지 공유
문서 버전: 1.0.0 | 최종 수정: 2025-12-04