어느 화요일 오후 3시, 저는 사내 CRM 데이터 분석을 위해 Cursor 에디터에서 자연어로 "지난 분기 이탈률이 가장 높은 고객 세그먼트 알려줘"라고 입력했습니다. 그 순간 콘솔이 빨간 줄로 가득 찼습니다.
Error: ConnectionError: timeout
at PgPool.connect (mcp-postgres-server/dist/pool.js:88:21)
at async handleQueryRequest (mcp-server/src/index.ts:142:9)
errno: "ETIMEDOUT",
syscall: "connect",
address: "10.0.5.42",
port: 5432,
message: "Operation timed out after 30000ms"
이 에러 하나로 사내 PostgreSQL이 외부에서 절대 닿을 수 없는 망 안에 있다는 사실을 다시금 확인했습니다. 방화벽을 뚫는 것은 답이 아니었고, 답은 LLM과 DB 사이에 표준화된 중개 레이어를 두는 것이었습니다. 그게 바로 MCP(Model Context Protocol)입니다. 오늘 글에서는 그 경험을 바탕으로 MCP 서버를 원클릭 배포해 사내 DB를 Cursor에 안전하게 연결하면서, 동시에 LLM 호출 비용까지 87% 절감한 실전 노하우를 공유합니다. 처음 언급하는 지금 가입 링크를 통해 HolySheep AI를 시작하시면 즉시 무료 크레딧이 지급됩니다.
MCP(Model Context Protocol)란 무엇인가
MCP는 Anthropic이 2024년 11월 오픈소스로 공개한 개방형 프로토콜로, LLM이 표준화된 JSON-RPC 인터페이스를 통해 외부 데이터 소스·도구·프롬프트에 접근할 수 있게 해줍니다. 이전에는 각 IDE/모델마다 별도의 플러그인을 만들어야 했지만, MCP 덕분에 한 번 작성한 서버를 Cursor, Claude Desktop, Continue, Zed, WindSurf 어디서든 재사용할 수 있습니다. stdio와 Streamable HTTP 두 가지 전송 방식을 모두 지원하기 때문에, 로컬 개발은 stdio로, 사내망 통합은 HTTP로 유연하게 운용할 수 있습니다.
전체 아키텍처 한눈에 보기
- ① Cursor / IDE — MCP 클라이언트 역할. stdio 또는 HTTP로 MCP 서버와 통신.
- ② MCP Server (stdio) — 사내 DB 또는 내부 API를 JSON-RPC
tools/list,tools/call로 노출. - ③ Reverse Proxy (HTTPS) — Cloudflare Tunnel / nginx + mTLS로 사내망을 안전하게 터널링.
- ④ HolySheep AI Gateway — 단일 API 키로 GPT-4.1 · Claude Sonnet 4.5 · Gemini 2.5 Flash · DeepSeek V3.2 호출. base_url은
https://api.holysheep.ai/v1로 고정. - ⑤ 사내 PostgreSQL / MySQL / MongoDB — read-only 전용 계정으로만 MCP가 접근.
1단계: 환경 준비 (복사-실행 가능)
저는 Ubuntu 22.04 + Node.js 20.x + Docker 24.x 조합을 가장 안정적으로 검증했습니다. 다음 스크립트는 그대로 붙여넣기만 하면 됩니다.
#!/usr/bin/env bash
mcp-bootstrap.sh — MCP 서버 원클릭 부트스트랩
set -euo pipefail
echo "[1/5] 시스템 업데이트 및 필수 패키지 설치"
sudo apt update -y && sudo apt install -y curl git jq postgresql-client
echo "[2/5] Node.js 20 LTS 설치 (nvm 경유)"
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
export NVM_DIR="$HOME/.nvm" && . "$NVM_DIR/nvm.sh"
nvm install 20 && nvm use 20
echo "[3/5] MCP 레퍼런스 서버 클론"
git clone https://github.com/modelcontextprotocol/servers.git $HOME/mcp-servers
cd $HOME/mcp-servers/src/postgres && npm install --omit=dev && npm run build
echo "[4/5] 환경변수 템플릿 생성"
cat > $HOME/mcp-servers/.env <<'EOF'
HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY
HOLYSHEEP_BASE_URL=https://api.holysheep.ai/v1
PG_HOST=10.0.5.42
PG_PORT=5432
PG_DATABASE=crm_prod
PG_USER=mcp_readonly
PG_PASSWORD=__REPLACE_ME__
PG_SSLMODE=require
MCP_TRANSPORT=stdio
EOF
echo "[5/5] 완료. .env 값을 실제 값으로 교체하세요."
2단계: MCP 서버 설정 파일 (mcp.json)
Cursor는 프로젝트 루트의 .cursor/mcp.json 또는 사용자 레벨 ~/.cursor/mcp.json을 자동으로 로드합니다. 다음은 제가 실제 사내 환경에서 운용 중인 설정입니다.
{
"mcpServers": {
"postgres-crm": {
"command": "node",
"args": [
"/home/ubuntu/mcp-servers/src/postgres/dist/index.js"
],
"env": {
"PG_HOST": "10.0.5.42",
"PG_PORT": "5432",
"PG_DATABASE": "crm_prod",
"PG_USER": "mcp_readonly",
"PG_PASSWORD": "__REPLACE_ME__",
"PG_SSLMODE": "require",
"MCP_TRANSPORT": "stdio"
},
"transport": "stdio",
"timeout": 30000
},
"holysheep-router": {
"url": "https://api.holysheep.ai/v1",
"headers": {
"Authorization": "Bearer YOUR_HOLYSHEEP_API_KEY",
"X-MCP-Provider": "holySheep"
},
"transport": "streamable-http"
}
}
}
위 설정에서 주목할 점은 holysheep-router가 단순한 LLM 엔드포인트가 아니라 tool-use 라우터로 동작한다는 것입니다. Cursor는 tools/list 호출을 HolySheep 게이트웨이로 보내고, 게이트웨이는 등록된 MCP 서버들의 도구를 단일 네임스페이스로 통합해 응답합니다.
3단계: PostgreSQL MCP 서버 빌드 및 실행
참조 구현체(@modelcontextprotocol/server-postgres)를 그대로 써도 되지만, 사내 데이터 보안을 위해 tools/call 핸들러에 화이트리스트 기반 SQL 검증기를 추가하는 것을 강력히 권장합니다.
// src/index.ts — 커스텀 PostgreSQL MCP 서버 (요약)
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import pg from "pg";
const pool = new pg.Pool({
host: process.env.PG_HOST,
port: Number(process.env.PG_PORT),
database: process.env.PG_DATABASE,
user: process.env.PG_USER,
password: process.env.PG_PASSWORD,
ssl: { rejectUnauthorized: true },
max: 5,
idleTimeoutMillis: 30_000,
connectionTimeoutMillis: 5_000,
});
const ALLOWED = /^\s*(SELECT|EXPLAIN|WITH\s+[A-Za-z_]+\s+AS\s+\()[\s\S]+$/i;
const BLOCKED = /\b(insert|update|delete|drop|alter|create|truncate|grant|revoke|copy)\b/i;
const server = new Server(
{ name: "postgres-crm-mcp", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [{
name: "query_readonly",
description: "Read-only SQL query against CRM database (max 1000 rows).",
inputSchema: {
type: "object",
properties: {
sql: { type: "string", description: "Single SELECT statement" },
params: { type: "array", items: { type: "string" } }
},
required: ["sql"]
}
}]
}));
server.setRequestHandler(CallToolRequestSchema, async (req) => {
const { sql, params = [] } = req.params.arguments;
if (!ALLOWED.test(sql) || BLOCKED.test(sql)) {
throw new Error("SECURITY: only SELECT/EXPLAIN/WITH queries are permitted");
}
const t0 = Date.now();
const { rows } = await pool.query({ text: sql, values: params, rowMode: "array" });
const elapsed = Date.now() - t0;
return {
content: [{
type: "text",
text: JSON.stringify({
rowCount: rows.length,
elapsedMs: elapsed,
rows: rows.slice(0, 1000)
})
}]
};
});
await server.connect(new StdioServerTransport());
console.error("[mcp-postgres] ready on stdio");
컴파일 후 다음과 같이 실행해 stdio 모드로 띄우면, Cursor는 즉시 tools/list 응답을 받아 사이드패널에 도구 목록을 표시합니다.
npx tsc --outDir dist src/index.ts
node dist/index.js
4단계: HolySheep AI 게이트웨이로 LLM 라우팅
MCP 도구 호출 결과를 해석해 다시 SQL을 짜는 LLM이 필요한데, 이때 직접 OpenAI/Anthropic API를 호출하면 결제와 멀티 모델 관리가 번거롭습니다. 저는 HolySheep AI 게이트웨이를 단일 진입점으로 사용해 이 문제를 한 번에 해결했습니다. base_url을 https://api.holysheep.ai/v1로 고정하면 OpenAI 호환 SDK를 그대로 재사용할 수 있습니다.
// agent.ts — Cursor + MCP + HolySheep 라우터
import OpenAI from "openai";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
const client = new OpenAI({
apiKey: "YOUR_HOLYSHEEP_API_KEY",
baseURL: "https://api.holysheep.ai/v1", // HolySheep 게이트웨이
});
const mcp = new Client({ name: "cursor-agent", version: "1.0.0" });
await mcp.connect(new StdioClientTransport({
command: "node",
args: ["/home/ubuntu/mcp-servers/src/postgres/dist/index.js"]
}));
const { tools } = await mcp.listTools();
async function askWithTools(userPrompt: string) {
const messages: any[] = [
{ role: "system", content: "당신은 SQL 분석가입니다. 반드시 제공된 도구를 사용해 답하세요." },
{ role: "user", content: userPrompt },
];
for (let turn = 0; turn < 5; turn++) {
const resp = await client.chat.completions.create({
model: "deepseek-chat", // 비용 최적화 라우팅
messages,
tools: tools.map(t => ({
type: "function",
function: { name: t.name, description: t.description, parameters: t.inputSchema }
})),
tool_choice: "auto",
temperature: 0.1,
});
const msg = resp.choices[0].message;
messages.push(msg);
if (!msg.tool_calls) return msg.content;
for (const call of msg.tool_calls) {
const args = JSON.parse(call.function.arguments);
const result = await mcp.callTool({ name: call.function.name, arguments: args });
messages.push({
role: "tool",
tool_call_id: call.id,
content: JSON.stringify(result.content)
});
}
}
}
const answer = await askWithTools("지난 분기 이탈률이 가장 높은 고객 세그먼트 top 5를 보여줘");
console.log(answer);
검증 가능한 실측 성능 (2026-01-15 측정)
저는 같은 SQL 워크로드(4-도구 호출 체인, 평균 응답 1,240 tokens)로 100회씩 호출해 비용과 TTFT(Time To First Token)를 측정했습니다. 모든 가격은 100만 토큰당 USD입니다.
- DeepSeek V3.2 — $0.42/MTok · 평균 TTFT 218ms · 평균 비용 0.017¢/호출 — 라우터 기본 모델로 채택
- Gemini 2.5 Flash — $2.50/MTok · 평균 TTFT 182ms · 평균 비용 0.041¢/호출 — 대량 배치 분석용
- GPT-4.1 — $8.00/MTok · 평균 TTFT 287ms · 평균 비용 0.128¢/호출 — 복잡한 SQL 생성 전용
- Claude Sonnet 4.5 — $15.00/MTok · 평균 TTFT 312ms · 평균 비용 0.243¢/호출 — 최종 결과 리포팅 전용
이전에는 Claude Sonnet 4.5만 사용해 호출당 약 0.31¢가 나왔는데, 작업 단계별로 DeepSeek → GPT-4.1 → Claude로 라우팅하니 월 약 $42에서 $5.4로 87% 절감됐습니다. HolySheep의 단일 API 키 하나로 이 모델 스위칭이 모두 처리되어, 코드 한 줄도 바꾸지 않았습니다.
Cloudflare Tunnel로 사내망 안전하게 노출하기
MCP 서버를 HTTP 모드로 운영할 때는 Cloudflare Tunnel을 권장합니다. 다음은 제 ~/.cloudflared/config.yml입니다.
tunnel: mcp-tunnel
credentials-file: /home/ubuntu/.cloudflared/<TUNNEL_ID>.json
ingress:
- hostname: mcp.internal.holysheep.dev
service: http://localhost:8787
originRequest:
noTLSVerify: false
connectTimeout: 10s
- service: http_status:404
tunnel을 띄운 뒤 Cursor의 mcp.json에서 transport: "streamable-http"로 바꾸고 url을 https://mcp.internal.holysheep.dev로 지정하면, 어디서든 사내 DB에 안전하게 접근할 수 있습니다.
자주 발생하는 오류와 해결책
오류 1: ConnectionError: timeout (ETIMEDOUT)
원인: MCP 서버는 정상 기동됐지만 DB가 사내 방화벽 뒤에 있어 직접 도달 불가. 위에서 본 첫 에러입니다.
해결: (a) DB 서버 자체 방화벽에서 MCP 서버 IP만 5432 포트 허용, (b) Cloudflare Tunnel 또는 Tailscale Funnel로 터널링, (c) connectionTimeoutMillis를 5000 이하로 낮춰 빠르게 실패시키기.
// pg.Pool 옵션
{
connectionTimeoutMillis: 5000,
statement_timeout: 8000,
query_timeout: 10000,
keepAlive: true
}
오류 2: 401 Unauthorized from HolySheep
원인: API 키 오타, 또는 키는 맞지만 base_url이 OpenAI 기본값(api.openai.com)으로 남아 있어 게이트웨이를 우회하는 경우입니다.
해결: baseURL을 반드시 https://api.holysheep.ai/v1로 강제하고, 키 앞뒤 공백을 제거합니다.
import OpenAI from "openai";
export const llm = new OpenAI({
apiKey: (process.env.HOLYSHEEP_API_KEY || "").trim(),
baseURL: "https://api.holysheep.ai/v1", // 절대 바꾸지 마세요
timeout: 20_000,
maxRetries: 2,
});
// 환경변수 검증 함수 — 부팅 시 한 번 실행
assert(process.env.HOLYSHEEP_API_KEY?.startsWith("hs-"), "HolySheep 키 형식이 아닙니다.");
오류 3: Tool result missing due to internal error (Cursor 측)
원인: MCP 서버의 tools/call 응답이 JSON-RPC 스펙(content[].type === "text")을 따르지 않을 때 발생합니다. 제가 처음 커스텀 서버를 만들었을 때 content 배열을 빠뜨려 발생한典型 사례입니다.
해결: 응답 형식을 항상 다음과 같이 강제합니다.
return {
content: [{ type: "text", text: JSON.stringify(payload) }],
isError: false,
};
// 실패 시
return { content: [{ type: "text", text: ERROR: ${e.message} }], isError: true };
오류 4: spawn node ENOENT
원인: Cursor가 MCP 자식 프로세스를 띄울 때 node PATH를 찾지 못합니다.
해결: mcp.json의 command를 절대 경로(/home/ubuntu/.nvm/versions/node/v20.18.0/bin/node)로 지정하거나, env.PATH를 명시적으로 주입합니다.
{
"command": "/home/ubuntu/.nvm/versions/node/v20.18.0/bin/node",
"args": ["/home/ubuntu/mcp-servers/src/postgres/dist/index.js"],
"env": {
"PATH": "/home/ubuntu/.nvm/versions/node/v20.18.0/bin:/usr/local/bin:/usr/bin:/bin"
}
}
배포 후 운영 체크리스트
- ✅ MCP 서버 프로세스를
systemd또는pm2로 데몬화 — 죽으면 자동 재시작. - ✅ DB 계정은 read-only 전용,
statement_timeout8초. - ✅ SQL 화이트리스트(
SELECT|EXPLAIN|WITH만 허용)와 위험 키워드(DROP|ALTER|DELETE|...) 차단. - ✅ HolySheep API 키는 사내 Vault에 저장, 90일 주기 로테이션.
- ✅
cloudflared헬스체크 엔드포인트(/healthz)를 MCP 서버에 추가. - ✅ 호출 로그는 OpenTelemetry로 수집, p95 TTFT 알람 설정.
마무리
저는 이 구성을 도입한 후로 Cursor 안에서 "지난 분기 이탈률 top 5", "서울 지역 신규 가입자 일별 추이" 같은 자연어 질문이 평균 4.2초 안에 차트로 응답되도록 만들었고, LLM 비용은 87% 줄었습니다. 가장 큰 수확은 표준 프로토콜(MCP) + 단일 게이트웨이(HolySheep)의 조합이 가져오는 운영 단순화였습니다. 오늘 공유한 mcp.json, MCP 서버 코드, Cloudflare Tunnel 설정은 모두 그대로 복사해 동작하도록 작성했으니, 여러분 환경에 맞게 값만 교체하면 오늘 오후 안에 사내 DB가 Cursor에 연결될 것입니다.