MCP 및 커서: IDE를 데이터베이스 및 API에 연결
IDE에 PostgreSQL 데이터베이스, 쿼리 문제에 직접 액세스하도록 요청할 수 있다고 상상해 보세요. GitHub에서 열고, Confluence의 문서를 읽고, 외부 REST API를 호출하는 작업을 모두 나가지 않고도 수행할 수 있습니다. 데이터와 패턴을 수동으로 복사하여 붙여넣지 않고도 편집기에서 사용할 수 있습니다. 그것은 공상과학 소설이 아닙니다. 그것이 바로 그 것입니다. 허용합니다 모델 컨텍스트 프로토콜(MCP) 커서에 통합되었습니다.
MCP는 Anthropic에서 개발하고 2024년 11월에 출시된 개방형 표준으로, 언어는 구조화되고 안전하며 구성 가능한 방식으로 외부 시스템과 통신할 수 있습니다. 몇 달 안에 그리고 AI와 개발 도구 간의 통합을 위한 사실상의 표준이 되었습니다. Cursor가 이를 채택했습니다. 기본적으로 오늘날 생태계에는 데이터베이스, API, 파일 시스템, 발권 시스템 등.
이 기사에서는 실용적이고 고급 관점인 아키텍처, 구성에서 MCP를 살펴봅니다. 커서, 가장 일반적인 사용 사례를 위해 사전 구축된 서버, TypeScript에서 사용자 정의 서버 생성, 관리 보안 및 문제 해결. 작업이 완료되면 Cursor를 유능한 에이전트로 전환하는 데 필요한 모든 것을 갖게 됩니다. 프로젝트의 전체 인프라와 상호 작용합니다.
이 기사에서 배울 내용
- MCP 아키텍처: 호스트, 클라이언트, 서버, 도구, 리소스 및 프롬프트
- 파일을 사용하여 커서에서 MCP를 구성합니다.
.cursor/mcp.json(프로젝트 및 글로벌 범위) - MCP 서버를 통해 커서를 PostgreSQL, MySQL 및 SQLite에 연결
- REST API, GraphQL, GitHub 및 Jira를 사전 구축된 MCP 서버와 통합
- 공식 SDK를 사용하여 TypeScript에서 사용자 정의 MCP 서버 만들기
- 보안, 권한 및 자격 증명 순환 관리
- 가장 일반적인 MCP 연결 문제 진단 및 수정
- MCP와 기존 통합 접근 방식의 비교
전제 조건
- IDE 커서 설치(안정적인 MCP를 위해서는 버전 0.43 이상 권장)
- Node.js 18+ 및 npm 설치됨
- TypeScript 및 JSON에 대한 기본 지식
- 선택 사항: 실제 사례를 위한 액세스 가능한 PostgreSQL 또는 MySQL 데이터베이스
1. 모델 컨텍스트 프로토콜이란 무엇입니까?
Il 모델 컨텍스트 프로토콜(MCP) 정의하는 JSON-RPC 2.0 기반의 개방형 표준 AI 애플리케이션( 고객)는 외부 시스템에 연결할 수 있습니다(i 섬기는 사람) 구조화된 방식으로 컨텍스트를 얻고, 작업을 수행하고, 리소스에 액세스합니다. 그리고 그 '공통언어'는 Cursor가 GitHub, Jira와 대화하는 것과 같은 방식으로 데이터베이스와 대화할 수 있습니다. 또는 다른 API.
MCP 이전에는 각 AI IDE가 서로 다른 도구, 서로 다른 API, 다른 형식. MCP를 사용하면 한 번 작성된 서버가 Cursor, Claude Desktop, VS Code Copilot과 작동합니다. 그리고 기타 호환 가능한 클라이언트. HTTP를 웹 표준으로 만든 것과 동일한 원칙입니다.
2. MCP 아키텍처: 호스트, 클라이언트 및 서버
MCP 아키텍처는 구성하기 전에 반드시 이해해야 하는 세 가지 수준으로 나뉩니다. 통합:
세 가지 MCP 수준
- 호스트: 사용자가 직접 상호작용하는 애플리케이션. 이 경우에는 커서 IDE입니다. 호스트는 MCP 클라이언트의 수명주기를 관리하고 AI 모델과의 상호 작용을 조정합니다.
- MCP 클라이언트: 단일 호스트와 1:1 연결을 유지하는 호스트의 내부 구성 요소 MCP 서버. Cursor는 각 서버의 클라이언트 생성 및 유지 관리를 자동으로 관리합니다. 구성되었습니다.
- MCP 서버: 도구, 리소스, 프롬프트 등의 기능을 노출하는 외부(또는 원격) 프로세스입니다. 로컬 프로세스(stdio) 또는 원격 서비스(HTTP/SSE)일 수 있습니다.
각 MCP 서버는 클라이언트가 사용할 수 있는 세 가지 유형의 기본 요소를 노출합니다.
// Primitive MCP: overview concettuale
// 1. TOOLS - azioni che il modello può invocare
// (lettura/scrittura, chiamate API, esecuzione query)
{
"name": "execute_query",
"description": "Esegue una query SQL sul database",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string" }
},
"required": ["query"]
}
}
// 2. RESOURCES - dati che il modello può leggere
// (simili a endpoint GET di una REST API)
{
"uri": "postgres://mydb/tables",
"name": "Database Tables",
"description": "Lista di tutte le tabelle del database",
"mimeType": "application/json"
}
// 3. PROMPTS - template riutilizzabili
// (istruzioni pre-costruite per task comuni)
{
"name": "analyze_schema",
"description": "Analizza lo schema del database e suggerisce ottimizzazioni",
"arguments": [
{ "name": "table_name", "required": true }
]
}
클라이언트와 서버 간의 통신은 지원되는 전송 중 하나를 통해 JSON-RPC 2.0을 통해 발생합니다.
- stdio(표준 I/O): 클라이언트는 서버를 자식 프로세스로 시작하고 다음을 통해 통신합니다. 표준 입력/표준 출력. 그리고 로컬 서버를 위한 가장 간단하고 적합한 전송입니다. 커서가 자동으로 관리합니다. 프로세스 수명주기.
- 스트리밍 가능한 HTTP: 서버는 독립적인 HTTP 서비스로 실행됩니다. 원격 서버에 이상적 여러 개발자 간에 공유되거나 클라우드 통합을 위해 공유됩니다. 2025년 3월부터 운송 수단으로 SSE를 대체했습니다. HTTP를 권장합니다.
SSE 전송이 더 이상 사용되지 않음
SSE(서버 전송 이벤트) 전송은 2025년 3월 26일 MCP 사양에 따라 더 이상 사용되지 않습니다. 만약 당신이
기존 SSE 구성을 사용하여 형식으로 마이그레이션 streamableHttp. 커서 버전
0.43+는 새로운 사양을 지원합니다.
3. 커서에서 MCP 구성
Cursor는 구성된 서버를 사용할 수 있는 위치를 결정하는 두 가지 MCP 구성 범위를 지원합니다.
# Configurazione GLOBALE (disponibile in tutti i progetti)
~/.cursor/mcp.json
# Configurazione PROGETTO (solo nel workspace corrente)
.cursor/mcp.json <-- nella root del progetto
# La configurazione progetto ha PRIORITA su quella globale
# in caso di conflitti di nomi
구성 파일의 기본 구조는 간단하고 두 범위 간에 일관됩니다.
// .cursor/mcp.json - Struttura base
{
"mcpServers": {
"nome-server": {
"command": "comando-da-eseguire",
"args": ["argomento1", "argomento2"],
"env": {
"VARIABILE": "valore"
}
}
}
}
HTTP를 통한 원격 서버의 경우 구조가 약간 다릅니다.
// .cursor/mcp.json - Server remoto HTTP
{
"mcpServers": {
"nome-server-remoto": {
"url": "https://mio-server-mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer {{env.MCP_API_TOKEN}}"
}
}
}
}
구성 파일을 저장한 후 커서를 다시 시작하거나 다음을 누르십시오. Cmd/Ctrl + Shift + P 그리고 검색
변경 사항을 적용하려면 "MCP: 서버 다시 로드"를 수행하세요. 서버의 상태를 확인할 수 있습니다.
설정 > MCP 녹색(연결됨) 또는 빨간색(오류) 표시기가 있는 각 서버를 볼 수 있습니다.
4. 데이터베이스용 MCP 서버
MCP 데이터베이스 서버는 개발자에게 가장 유용한 서버 중 하나입니다. 이를 통해 Cursor AI 모델은 다음을 수행할 수 있습니다. 스키마 검사, 쿼리 실행, 성능 분석 및 구조 기반 최적화 제안 일반적인 가정이 아닌 데이터베이스의 현실.
4.1 포스트그레SQL
Anthropic의 PostgreSQL용 공식 MCP 서버는 데이터베이스 스키마를 MCP 리소스로 노출하고 다음을 허용합니다. 읽기 전용 쿼리를 실행하려면(보안을 위해 읽기 전용):
// .cursor/mcp.json - PostgreSQL server ufficiale
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://utente:password@localhost:5432/mio_database"
]
}
}
}
구성 파일에 자격 증명을 넣지 마십시오.
파일의 연결 문자열 URL에 사용자 이름과 비밀번호를 직접 입력하지 마세요.
mcp.json, 특히 파일 버전이 git으로 지정된 경우에는 더욱 그렇습니다. 환경 변수를 사용하십시오.
// .cursor/mcp.json - PostgreSQL con variabili d'ambiente
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres"
],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://{{env.DB_USER}}:{{env.DB_PASSWORD}}@localhost:5432/mio_database"
}
}
}
}
# Nel tuo .env (NON versionato):
DB_USER=myuser
DB_PASSWORD=supersecretpassword
일단 구성되면 커서 채팅에서 직접 데이터베이스와 상호 작용할 수 있습니다.
PostgreSQL MCP를 사용한 프롬프트 예
- "사용자 테이블의 스키마를 보여주고 중요한 인덱스가 누락되었는지 알려주세요."
- "지난달에 생성된 주문 테이블에는 몇 개의 행이 있나요?"
- "이 느린 쿼리를 분석하고 실제 스키마를 기반으로 최적화를 제안합니다."
- "사용자 테이블에 email_verified 열을 추가하기 위해 TypeORM 마이그레이션을 생성합니다."
4.2 MySQL과 마리아DB
MySQL 및 MariaDB의 경우 유사한 기능을 제공하는 커뮤니티 MCP 서버가 있습니다.
// .cursor/mcp.json - MySQL tramite server community
{
"mcpServers": {
"mysql": {
"command": "npx",
"args": ["-y", "@benborla29/mcp-server-mysql"],
"env": {
"MYSQL_HOST": "localhost",
"MYSQL_PORT": "3306",
"MYSQL_USER": "root",
"MYSQL_PASS": "password",
"MYSQL_DB": "mio_database",
"ALLOW_INSERT_OPERATION": "false",
"ALLOW_UPDATE_OPERATION": "false",
"ALLOW_DELETE_OPERATION": "false"
}
}
}
}
4.3 로컬 개발을 위한 SQLite
// .cursor/mcp.json - SQLite (ottimo per sviluppo locale e test)
{
"mcpServers": {
"sqlite": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sqlite",
"--db-path",
"./database/dev.db"
]
}
}
}
5. API 및 외부 서비스를 위한 MCP 서버
데이터베이스 외에도 MCP 생태계는 가장 일반적인 도구를 워크플로에 통합하기 위해 사전 구축된 서버를 제공합니다. 매일 발전의.
5.1 GitHub MCP
공식 GitHub MCP 서버(GitHub에서 직접 유지 관리)를 사용하면 리포지토리를 관리할 수 있습니다. 문제, 끌어오기 요청, CI/CD 워크플로 등을 커서 채팅에서 직접 확인할 수 있습니다.
// .cursor/mcp.json - GitHub MCP ufficiale (via Docker)
// NOTA: Il package npm e stato deprecato ad aprile 2025
// Usa l'immagine Docker ufficiale:
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxx"
}
}
}
}
// Alternativa: via npx (versione community)
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxx"
}
}
}
}
GitHub 서버가 구성되면 Cursor는 다음을 수행할 수 있습니다.
- 이슈 및 풀 요청 읽기 및 생성
- 버그의 맥락을 이해하기 위해 커밋 기록을 분석합니다.
- 공개 및 비공개 저장소의 코드 검색
- GitHub Actions 워크플로 트리거
- PR에 대한 의견을 읽고 쓰기
5.2 MCP 파일 시스템
Anthropic의 파일 시스템 서버를 사용하면 모델이 특정 경로에 파일을 읽고 쓸 수 있습니다. 세분화된 액세스 제어를 통해:
// .cursor/mcp.json - Filesystem con accesso limitato
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/federicocalo/progetti",
"/tmp/cursor-workspace"
]
}
}
}
// ATTENZIONE: specifica SOLO le directory necessarie
// Non dare accesso a / (root) o home directory completa
5.3 다중 서버 구성
Cursor에서 MCP의 강력한 측면과 여러 서버를 동시에 구성할 수 있는 기능, 데이터베이스, 외부 API 및 내부 도구를 단일 파일에 결합:
// .cursor/mcp.json - Configurazione completa multi-server
{
"mcpServers": {
// Database principale
"postgres-prod": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://user:pass@prod-db:5432/app"
}
},
// Database di sviluppo
"postgres-dev": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://user:pass@localhost:5432/app_dev"
}
},
// Repository GitHub
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxx"
}
},
// Filesystem progetti
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/federicocalo/progetti/mio-app"
]
},
// Server custom interno
"api-interna": {
"command": "node",
"args": ["/Users/federicocalo/mcp-servers/api-server/dist/index.js"],
"env": {
"API_BASE_URL": "https://api.mia-azienda.com",
"API_KEY": "key_xxxx"
}
}
}
}
6. TypeScript에서 사용자 정의 MCP 서버 생성
사전 구축된 서버는 많은 일반적인 사용 사례를 다루지만 Cursor를 시스템에 연결해야 하는 경우가 많습니다. 내부, 독점 API 또는 프로젝트와 관련된 논리. 공식 TypeScript SDK는 놀랍도록 간단한 사용자 정의 서버 생성.
6.1 프로젝트 설정
# Inizializza il progetto
mkdir mio-mcp-server
cd mio-mcp-server
npm init -y
# Installa le dipendenze
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node ts-node
# Configura TypeScript
npx tsc --init --target ES2022 --module commonjs --outDir dist
// package.json - scripts necessari
{
"name": "mio-mcp-server",
"version": "1.0.0",
"main": "dist/index.js",
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "ts-node src/index.ts"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0",
"zod": "^3.22.0"
},
"devDependencies": {
"typescript": "^5.3.0",
"@types/node": "^20.0.0",
"ts-node": "^10.9.0"
}
}
6.2 도구와 리소스가 포함된 기본 MCP 서버
내부 REST API를 쿼리하는 도구를 노출하는 완전한 MCP 서버를 구축하는 방법을 살펴보겠습니다. 정적 데이터를 노출하는 리소스:
// src/index.ts - Server MCP completo
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListResourcesRequestSchema,
ListToolsRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
const API_BASE_URL = process.env.API_BASE_URL || "https://api.esempio.com";
const API_KEY = process.env.API_KEY || "";
// Inizializza il server MCP
const server = new Server(
{
name: "mio-server-mcp",
version: "1.0.0",
},
{
capabilities: {
resources: {},
tools: {},
},
}
);
// === TOOLS ===
// I tools sono azioni che il modello può invocare
// Lista i tools disponibili
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "get_utenti",
description: "Recupera la lista degli utenti attivi dall'API",
inputSchema: {
type: "object",
properties: {
limite: {
type: "number",
description: "Numero massimo di utenti da restituire (default: 10)",
},
ruolo: {
type: "string",
enum: ["admin", "user", "guest"],
description: "Filtra per ruolo utente",
},
},
required: [],
},
},
{
name: "crea_report",
description: "Genera un report aggregato per un periodo specificato",
inputSchema: {
type: "object",
properties: {
data_inizio: {
type: "string",
format: "date",
description: "Data inizio periodo (YYYY-MM-DD)",
},
data_fine: {
type: "string",
format: "date",
description: "Data fine periodo (YYYY-MM-DD)",
},
tipo: {
type: "string",
enum: ["vendite", "utenti", "performance"],
description: "Tipo di report da generare",
},
},
required: ["data_inizio", "data_fine", "tipo"],
},
},
],
};
});
// Gestisce l'esecuzione dei tools
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case "get_utenti": {
const limite = (args?.limite as number) || 10;
const ruolo = args?.ruolo as string | undefined;
const url = new URL(`${API_BASE_URL}/utenti`);
url.searchParams.set("limite", String(limite));
if (ruolo) url.searchParams.set("ruolo", ruolo);
const response = await fetch(url.toString(), {
headers: { "X-API-Key": API_KEY },
});
if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
return {
content: [
{
type: "text",
text: JSON.stringify(data, null, 2),
},
],
};
}
case "crea_report": {
const { data_inizio, data_fine, tipo } = args as {
data_inizio: string;
data_fine: string;
tipo: string;
};
const response = await fetch(`${API_BASE_URL}/report`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": API_KEY,
},
body: JSON.stringify({ data_inizio, data_fine, tipo }),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Errore report: ${response.status} - ${errorText}`);
}
const report = await response.json();
return {
content: [
{
type: "text",
text: `Report generato con successo:\n${JSON.stringify(report, null, 2)}`,
},
],
};
}
default:
throw new Error(`Tool sconosciuto: ${name}`);
}
});
// === RESOURCES ===
// Le resources espongono dati statici o semi-statici
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{
uri: "config://ambiente",
name: "Configurazione Ambiente",
description: "Configurazione corrente dell'ambiente applicativo",
mimeType: "application/json",
},
{
uri: "docs://api-endpoints",
name: "Documentazione API",
description: "Lista di tutti gli endpoint API disponibili",
mimeType: "text/markdown",
},
],
};
});
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const { uri } = request.params;
switch (uri) {
case "config://ambiente":
return {
contents: [
{
uri,
mimeType: "application/json",
text: JSON.stringify(
{
ambiente: process.env.NODE_ENV || "development",
api_base_url: API_BASE_URL,
versione_api: "v2",
funzionalità: {
report: true,
export_csv: process.env.ENABLE_CSV === "true",
},
},
null,
2
),
},
],
};
case "docs://api-endpoints":
return {
contents: [
{
uri,
mimeType: "text/markdown",
text: `# Endpoint API Disponibili
## Utenti
- GET /utenti - Lista utenti
- GET /utenti/:id - Dettaglio utente
- POST /utenti - Crea utente
## Report
- POST /report - Genera report
- GET /report/:id - Scarica report
## Autenticazione
Tutti gli endpoint richiedono l'header X-API-Key.`,
},
],
};
default:
throw new Error(`Risorsa non trovata: ${uri}`);
}
});
// Avvia il server con trasporto stdio
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
// Log su stderr (non stdout) per non corrompere il protocollo
console.error("Server MCP avviato e in ascolto");
}
main().catch((error) => {
console.error("Errore fatale:", error);
process.exit(1);
});
6.3 커서에 사용자 정의 서버 연결
// Prima compila il server
// npm run build
// .cursor/mcp.json - Registra il server custom
{
"mcpServers": {
"api-interna": {
"command": "node",
"args": ["/percorso/assoluto/mio-mcp-server/dist/index.js"],
"env": {
"API_BASE_URL": "https://api.mia-azienda.com",
"API_KEY": "chiave_segreta_qui",
"NODE_ENV": "production"
}
}
}
}
팁: 절대 경로 사용
현장에서 args 파일의 mcp.json, 항상 파일에 대한 절대 경로를 사용하십시오
서버의. 커서는 작업 디렉토리가 아닌 컨텍스트에서 MCP 프로세스를 실행합니다.
당신이 기대하는 것.
7. MCP 자격 증명의 보안 및 관리
보안은 아마도 전문적인 맥락에서 MCP를 구현하는 데 가장 중요한 측면일 것입니다. MCP 서버는 민감한 리소스(데이터베이스, API, 파일 시스템) 및 잘못된 구성에 액세스할 수 있습니다. 중요한 데이터가 노출될 수 있습니다.
7.1 최소 권한 원칙
기본 원칙은 필요한 최소한의 권한으로 각 MCP 서버를 구성하는 것입니다.
// SBAGLIATO: credenziali admin sul database
{
"postgres": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://postgres:adminpassword@localhost/db"
]
}
}
// CORRETTO: utente dedicato in sola lettura
// Prima crea l'utente sul database:
// CREATE USER cursor_readonly WITH PASSWORD 'password';
// GRANT CONNECT ON DATABASE db TO cursor_readonly;
// GRANT USAGE ON SCHEMA public TO cursor_readonly;
// GRANT SELECT ON ALL TABLES IN SCHEMA public TO cursor_readonly;
{
"postgres": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://cursor_readonly:password@localhost/db"
]
}
}
7.2 환경변수의 안전한 관리
// APPROCCIO 1: Variabili d'ambiente di sistema
// Imposta le variabili nell'ambiente shell prima di avviare Cursor
# ~/.zshrc o ~/.bashrc
export POSTGRES_URL="postgresql://user:pass@localhost/db"
export GITHUB_TOKEN="ghp_xxxxxxxxxxxx"
export OPENAI_API_KEY="sk-xxxxxxxxxxxx"
// Nel mcp.json usa i riferimenti alle variabili:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_URL": "${POSTGRES_URL}"
}
}
}
}
// APPROCCIO 2: File .env locale (NON committato)
// .cursor/mcp.json legge automaticamente le variabili
// dall'ambiente del processo Cursor, che a sua volta
// può essere configurato da un .env nel progetto
// APPROCCIO 3: Secret manager (produzione/team)
// Usa 1Password CLI, Vault o AWS Secrets Manager:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_URL": "op://vault/database/connection-string"
}
}
}
}
7.3 CVE-2025-54136: MCPoison 및 mcp.json 보안
2025년에는 Cursor에 영향을 미치는 "MCPoison"(CVE-2025-54136)이라는 취약점이 문서화되었습니다.
MCP 서버가 사용자에 의해 승인되면 Cursor는 신뢰를 이름
서버의 명령. 파일 mcp.json 공격자에 의해 수정됨
공유 저장소는 동일한 신뢰할 수 있는 이름을 유지하면서 실행된 명령을 대체할 수 있습니다.
MCPoison 완화 조치
- 커밋하지 마세요
.cursor/mcp.json공유 저장소에 자격 증명이 있는 경우 - 추가하다
.cursor/mcp.jsonal.gitignore자격 증명이 포함된 경우 - 전역 구성 사용(
~/.cursor/mcp.json) 개인 자격 증명용 - Cursor를 정기적으로 업데이트하세요. 최신 버전에서는 신뢰 관리가 향상됩니다.
- 항상 내용을 확인하세요.
mcp.json공유 저장소에서 가져온 후
# .gitignore - Aggiungi questa riga
.cursor/mcp.json
# Oppure usa un file template senza credenziali:
# .cursor/mcp.json.example (versionato, senza segreti)
# .cursor/mcp.json (ignorato da git, con segreti reali)
8. MCP 연결 문제 해결
MCP는 상대적으로 젊은 기술이므로 특히 연결 문제가 자주 발생합니다. 초기 구성. 다음은 가장 자주 발생하는 문제를 진단하고 해결하기 위한 체계적인 가이드입니다.
8.1 서버 상태 확인
첫 번째 단계는 항상 커서 UI에서 서버 상태를 확인하는 것입니다.
- 열려 있는 설정 (Cmd/Ctrl + ,)
- 섹션으로 이동 MCP 측면 패널에
- 각 서버에는 녹색(연결됨), 노란색(연결 중), 빨간색(오류) 표시기가 표시됩니다.
- 오류 메시지를 보려면 실패한 서버 옆에 있는 로그 아이콘을 클릭하세요.
8.2 일반적인 문제와 해결책
// PROBLEMA 1: "Server non trovato" o "command not found"
// CAUSA: Il comando npx/node non e nel PATH di Cursor
// SOLUZIONE: Usa il percorso assoluto del comando
// SBAGLIATO:
{ "command": "npx", "args": ["-y", "@mcp/server-postgres"] }
// CORRETTO (trova il percorso con 'which npx'):
{ "command": "/usr/local/bin/npx", "args": ["-y", "@mcp/server-postgres"] }
// ---
// PROBLEMA 2: "Connection refused" o "ECONNREFUSED"
// CAUSA: Il server SSE non e in esecuzione o porta sbagliata
// SOLUZIONE: Verifica che il server sia avviato e usa il trasporto corretto
// Per server stdio, non serve nessun server avviato separatamente
// Cursor lo avvia automaticamente come processo figlio
// ---
// PROBLEMA 3: JSON malformato nel mcp.json
// CAUSA: Virgola finale, commenti JS, ecc.
// MCP.json e JSON standard: NO commenti, NO trailing commas
// SOLUZIONE: Valida il JSON con jq:
// cat .cursor/mcp.json | jq .
// ---
// PROBLEMA 4: Variabili d'ambiente non disponibili
// CAUSA: Cursor non eredita le variabili dell'ambiente shell
// SOLUZIONE: Specifica esplicitamente le variabili nel campo "env"
{
"env": {
"MY_VAR": "valore-diretto"
}
}
// ---
// PROBLEMA 5: Output su stdout corrompe il protocollo
// CAUSA: Il server MCP usa console.log() invece di console.error()
// SOLUZIONE: Usa SEMPRE console.error() per i log nei server stdio
// Il protocollo MCP usa stdout per i messaggi JSON-RPC
// Qualsiasi output non-JSON su stdout rompe la comunicazione
8.3 MCP 디버깅 활성화
# Modalità debug per MCP in Cursor
# Avvia Cursor da terminale con debug abilitato:
cursor --enable-mcp-logging --log-level=DEBUG
# Variabili d'ambiente per debug del server MCP:
export MCP_DEBUG=1
export MCP_LOG_LEVEL=debug
export DEBUG="mcp:*"
# Testa il server MCP manualmente (fuori da Cursor):
echo '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}' | node dist/index.js
9. MCP와 기존 접근 방식
MCP의 실제 가치를 이해하려면 MCP를 기존 통합 접근 방식과 비교하는 것이 유용합니다. AI와 외부 도구 사이:
| 나는 기다린다 | 전통적인 접근 방식 | MCP |
|---|---|---|
| 완성 | 채팅에 스키마/데이터를 수동으로 복사하여 붙여넣기 | 실시간으로 직접적이고 구조화된 액세스 |
| 표준화 | 모든 IDE에는 호환되지 않는 독점 플러그인이 있습니다 | 하나의 서버가 모든 MCP 클라이언트와 작동합니다. |
| 안전 | 프롬프트 또는 채팅 컨텍스트의 자격 증명 | 모델에 노출되지 않는 서버 프로세스의 자격 증명 |
| 구성성 | 분리된 통합, 결합하기 어려움 | 여러 서버를 단일 작업 흐름으로 결합할 수 있습니다. |
| 유지 | 유지 관리할 맞춤형 통합 | 커뮤니티 서버 생태계 유지 |
| 데이터 업데이트 | (정적) 컨텍스트의 정적 데이터 | 업데이트된 데이터에 대한 실시간 액세스 |
10. 실제 작업 흐름: Angular 프로젝트를 사용한 MCP
MCP가 PostgreSQL 백엔드를 사용하여 Angular 프로젝트의 개발 워크플로를 어떻게 변환하는지 살펴보겠습니다. 여러 서버를 단일 운영 구성으로 결합:
// .cursor/mcp.json - Configurazione per progetto Angular + PostgreSQL
{
"mcpServers": {
"database": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://cursor_ro:pass@localhost:5432/angular_app"
]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxx"
}
}
}
}
이 구성이 활성화되면 커서에서 사용할 수 있는 프롬프트가 훨씬 더 강력해집니다.
MCP 다중 서버를 사용한 고급 프롬프트
- "GitHub에서 이슈 #142를 보고 요청한 기능을 구현하세요. 데이터베이스 스키마는 다음과 같습니다. postgres/my_db, 관련된 테이블을 구독이라고 합니다."
- "UserList 구성 요소에 대한 E2E 테스트를 작성합니다. 실제 데이터베이스 스키마를 사용하여 생성합니다. 현실적인 테스트 데이터."
- "커밋 abc1234에 회귀가 발생했습니다. 현재 스키마를 해당 스키마와 비교하세요. 이전에 문제를 일으켰을 수 있는 변경 사항을 식별합니다."
- "TypeORM 마이그레이션 파일을 생성하여 사용자 테이블에 필요한 열을 추가하고, 현재 데이터베이스 구조를 기반으로 합니다."
11. 프로덕션 MCP 모범 사례
개발팀을 위한 MCP 체크리스트
- 방 분리: 개발, 스테이징 및 프로덕션에 서로 다른 MCP 서버를 사용합니다. 동일한 MCP 서버가 여러 환경을 가리키지 않습니다.
- 기본적으로 읽기 전용: 모든 데이터베이스 서버를 읽기 전용으로 구성합니다. 전용 서버에서만 쓰기가 가능하며 이중 확인이 가능합니다.
- 키 순환: MCP 서버에서 사용하는 API 토큰에 만료를 설정합니다. 60~90일은 좋은 습관입니다
-
mcp.json용 Gitignore: 자격 증명이 있는 파일의 버전을 관리하지 않았습니다. 미국
mcp.json.example공유 템플릿으로 - 모니터링: 추적을 위해 사용자 정의 서버에 구조화된 로깅 구현 어떤 도구가 호출되고 어떤 커서 세션에서
- 시간 초과: 이를 방지하기 위해 서버의 API 호출에 시간 초과를 추가하십시오. 커서가 무기한 대기함
- 입력 유효성 검사: 수신된 매개변수를 검증하려면 Zod 또는 이와 유사한 것을 사용하십시오. 작업을 수행하기 전에 도구에서
// Esempio: Tool con validazione Zod e timeout
import { z } from "zod";
const QuerySchema = z.object({
tabella: z.string().min(1).max(100).regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/),
limite: z.number().int().positive().max(1000).default(50),
filtro: z.string().optional(),
});
// Nel handler del tool:
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const parsed = QuerySchema.safeParse(request.params.arguments);
if (!parsed.success) {
throw new Error(`Parametri non validi: ${parsed.error.message}`);
}
// AbortController per timeout
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10s timeout
try {
const result = await fetch(apiUrl, {
signal: controller.signal,
headers: { "X-API-Key": API_KEY },
});
return { content: [{ type: "text", text: await result.text() }] };
} finally {
clearTimeout(timeoutId);
}
});
결론
모델 컨텍스트 프로토콜은 AI IDE가 상호 작용하는 방식의 질적 도약을 나타냅니다. 개발 인프라. 정적이고 일반적인 정보와 별도로 작업하는 대신, MCP가 구성된 커서는 실제 컨텍스트(스키마)를 추론할 수 있는 에이전트가 됩니다. 데이터베이스의 현재 상태, GitHub의 미해결 문제, 프로젝트의 특정 구성.
우리는 전역적으로나 프로젝트 수준에서 MCP를 구성하는 방법, 사전 구축된 서버를 사용하는 방법을 살펴보았습니다. 가장 일반적인 사용 사례(PostgreSQL, GitHub, 파일 시스템), TypeScript에서 사용자 정의 서버를 구축하는 방법 독점 시스템을 통합하고 전문적인 방식으로 보안 및 문제 해결을 관리하는 방법을 설명합니다.
자연스러운 다음 단계는 MCP를 Cursor의 다른 고급 기능과 결합하는 것입니다. MCP 사용 에이전트 모드 내에서 에이전트가 액세스 권한이 필요한 다단계 작업을 수행하도록 합니다. 데이터베이스 및 저장소; 패턴과 관련된 복잡한 기능을 계획하려면 계획 모드를 사용하십시오. 마이그레이션 및 애플리케이션 코드를 함께 사용합니다. 가능성은 엄청나게 늘어납니다.
MCP 생태계는 빠르게 성장하고 있습니다. 매주 새로운 서버가 npm에 게시되고 공식 Anthropic 저장소에 있습니다. 정기적으로 카탈로그를 탐색하여 알아낼 가치가 있습니다. 작업 흐름 속도를 높일 수 있는 새로운 통합.
이 시리즈의 관련 기사
관련 시리즈
- MCP 시리즈(ID 64-77): 모델 컨텍스트 프로토콜에 대한 심층적인 연구를 완료하고, 모든 MCP 클라이언트를 위한 고급 아키텍처 및 구현
- 최신 Angular(ID 224-233): 전문적인 Angular 워크플로를 사용할 수 있습니다. 이 기사에 표시된 MCP 통합으로 향상
- 바이브 코딩(ID 281-288): AI 우선 개발 접근 방식, 완벽하게 MCP와 함께 커서의 고급 사용을 보완합니다.







