이 문서에서는 Node.js 및 TypeScript를 사용하여 MCP(모델 컨텍스트 프로토콜) 서버를 빌드하는 방법을 설명합니다. 서버는 서버리스 환경에서 도구와 서비스를 실행합니다. 이 구조를 시작점으로 사용하여 사용자 지정 MCP 서버를 만듭니다.
코드로 바로 이동하기
TypeScript MCP(원격 모델 컨텍스트 프로토콜) 서버 샘플을 살펴봅니다. Node.js 및 TypeScript를 사용하여 원격 MCP 서버를 빌드하고 Azure Container Apps에 배포하는 방법을 보여 줍니다.
코드 연습 섹션으로 이동하여 이 샘플의 작동 방식을 이해합니다.
아키텍처 개요
다음 다이어그램은 샘플 앱의 간단한 아키텍처를 보여줍니다.
MCP 서버는 ACA(Azure Container Apps)에서 컨테이너화된 앱으로 실행됩니다. Node.js/TypeScript 백 엔드를 사용하여 모델 컨텍스트 프로토콜을 통해 MCP 클라이언트에 도구를 제공합니다. 모든 도구는 백 엔드 SQLite 데이터베이스에서 작동합니다.
비용
비용을 낮게 유지하기 위해 이 샘플은 대부분의 리소스에 대해 기본 또는 소비 가격 책정 계층을 사용합니다. 필요에 따라 계층을 조정하고 요금이 부과되지 않도록 완료되면 리소스를 삭제합니다.
필수 조건
- Visual Studio Code - MCP 서버 개발을 지원하는 최신 버전입니다.
- GitHub Copilot Visual Studio Code 확장
- GitHub 코필로트 채팅 Visual Studio Code 확장
- Azure 개발자 CLI(azd)
개발 컨테이너에는 이 문서에 필요한 모든 종속성이 포함됩니다. GitHub Codespaces(브라우저에서) 또는 Visual Studio Code를 사용하여 로컬로 실행할 수 있습니다.
이 문서를 따르려면 다음 필수 구성 요소를 충족하는지 확인합니다.
- GitHub Codespaces (권장)
- Visual Studio Code
- Azure 구독 – 무료로 구독 만들기
- Azure 계정 권한 – Azure 계정에
Microsoft.Authorization/roleAssignments/write, 사용자 액세스 관리자 또는 소유자와 같은 권한이 있어야 합니다. 구독 수준 권한이 없는 경우 기존 리소스 그룹에 대한 RBAC 를 부여하고 해당 그룹에 배포해야 합니다.- Azure 계정에는 구독 수준의 권한도 필요합니다
Microsoft.Resources/deployments/write.
- Azure 계정에는 구독 수준의 권한도 필요합니다
- GitHub 계정
개방형 개발 환경
필요한 모든 종속성을 사용하여 미리 구성된 개발 환경을 설정하려면 다음 단계를 수행합니다.
- GitHub Codespaces (권장)
- Visual Studio Code
GitHub Codespaces는웹용 Visual Studio Code 를 인터페이스로 사용하여 GitHub에서 관리하는 개발 컨테이너를 실행합니다. 이 문서에 미리 설치된 필수 도구 및 종속성과 함께 제공되는 가장 간단한 설정에는 GitHub Codespaces를 사용합니다.
중요합니다
모든 GitHub 계정은 두 개의 핵심 인스턴스를 사용하여 매월 최대 60시간 동안 Codespaces를 무료로 사용할 수 있습니다. 자세한 내용은 GitHub Codespaces 월별 포함된 스토리지 및 코어 시간을 참조하세요.
다음 단계를 사용하여 GitHub 리포지토리의 분기에 새 GitHub Codespace main 를 Azure-Samples/mcp-container-ts 만듭니다.
다음 단추를 마우스 오른쪽 단추로 클릭하고 새 창에서 링크 열기를 선택합니다. 이 작업을 통해 개발 환경과 설명서를 나란히 열 수 있습니다.
코드스페이스 만들기 페이지에서 새 코드스페이스 만들기를 검토한 다음 선택합니다.
코드스페이스가 시작될 때까지 기다립니다. 이 작업은 몇 분 정도 걸릴 수 있습니다.
화면 맨 아래에 있는 터미널에서 Azure 개발자 CLI를 사용하여 Azure에 로그인합니다.
azd auth login터미널에서 코드를 복사한 다음 브라우저에 붙여넣습니다. 지침에 따라 Azure 계정으로 인증합니다.
이 개발 컨테이너에서 나머지 작업을 수행합니다.
비고
MCP 서버를 로컬로 실행하려면 다음을 수행합니다.
- 샘플 리포지토리의 로컬 환경 설정 섹션에 설명된 대로 환경을 설정합니다.
- 샘플 리포지토리의 Visual Studio Code에서 MCP 서버 구성 섹션의 지침에 따라 로컬 환경을 사용하도록 MCP 서버를 구성합니다.
- 계속하려면 에이전트 모드 섹션에서 TODO MCP 서버 도구 사용 으로 건너뜁니다.
배포 및 실행
샘플 리포지토리에는 MCP 서버 Azure 배포에 대한 모든 코드 및 구성 파일이 포함되어 있습니다. 다음 단계에서는 샘플 MCP 서버 Azure 배포 프로세스를 안내합니다.
Azure에 배포
중요합니다
이 섹션의 Azure 리소스는 명령이 완료되기 전에 중지하더라도 즉시 비용이 들기 시작합니다.
Azure 리소스 프로비저닝 및 소스 코드 배포에 대해 다음 Azure Developer CLI 명령을 실행합니다.
azd up다음 표를 사용하여 프롬프트에 응답합니다.
프롬프트 답변 환경 이름 짧게 하고 소문자로 유지하세요. 이름 또는 별칭을 추가합니다. 예: my-mcp-server. 리소스 그룹 이름의 일부로 사용됩니다.구독 구독을 선택하여 리소스를 생성합니다. 위치(호스팅용) 목록에서 가까운 위치를 선택합니다. Azure OpenAI 모델의 위치 목록에서 가까운 위치를 선택합니다. 첫 번째 위치와 동일한 위치를 사용할 수 있는 경우 해당 위치를 선택합니다. 앱이 배포될 때까지 기다립니다. 배포를 완료하는 데 일반적으로 5~10분이 걸립니다.
배포가 완료되면 출력에 제공된 URL을 사용하여 MCP 서버에 액세스할 수 있습니다. URL은 다음과 같습니다.
https://<env-name>.<container-id>.<region>.azurecontainerapps.io
- URL을 클립보드에 복사합니다. 다음 섹션에서 필요합니다.
Visual Studio Code에서 MCP 서버 구성
mcp.json 파일에 .vscode URL을 추가하여 로컬 VS Code 환경에서 MCP 서버를 구성합니다.
mcp.json폴더에서.vscode파일을 엽니다.파일에서
mcp-server-sse-remote섹션을 찾습니다. 다음과 같이 표시되어야 합니다."mcp-server-sse-remote": { "type": "sse", "url": "https://<container-id>.<location>.azurecontainerapps.io/sse" }기존
url값을 이전 단계에서 복사한 URL로 바꿉다.mcp.json파일을 폴더에 저장합니다.vscode.
에이전트 모드에서 TODO MCP 서버 도구 사용
MCP 서버를 수정한 후에는 도구를 사용할 수 있으며 에이전트 모드에서 제공합니다. 에이전트 모드에서 MCP 도구를 사용하려면 다음을 수행합니다.
채팅 보기(
Ctrl+Alt+I)를 열고 드롭다운에서 에이전트 모드를 선택합니다.도구 단추를 선택하여 사용 가능한 도구 목록을 봅니다. 필요에 따라 사용하려는 도구를 선택하거나 선택 취소합니다. 검색 상자에 입력하여 도구를 검색할 수 있습니다.
채팅 입력 상자에 "수요일에 관리자에게 전자 메일을 보내야 합니다."와 같은 프롬프트를 입력하고 다음 스크린샷과 같이 필요에 따라 도구가 자동으로 호출되는 방법을 확인합니다.
비고
기본적으로 도구가 호출되면 도구를 실행하기 전에 작업을 확인해야 합니다. 그렇지 않으면 도구가 컴퓨터에서 로컬로 실행될 수 있으며 파일 또는 데이터를 수정하는 작업을 수행할 수 있습니다.
계속 단추 드롭다운 옵션을 사용하여 현재 세션, 작업 영역 또는 모든 향후 호출에 대한 특정 도구를 자동으로 확인합니다.
샘플 코드 탐색
이 섹션에서는 MCP 서버 샘플의 키 파일 및 코드 구조에 대한 개요를 제공합니다. 코드는 다음과 같은 몇 가지 주요 구성 요소로 구성됩니다.
-
index.ts: Express.js HTTP 서버 및 라우팅을 설정하는 MCP 서버의 기본 진입점입니다. -
server.ts: Server-Sent 이벤트(SSE) 연결 및 MCP 프로토콜 처리를 관리하는 전송 계층입니다. -
tools.ts: MCP 서버에 대한 비즈니스 논리 및 유틸리티 함수를 포함합니다. -
types.ts: MCP 서버 전체에서 사용되는 TypeScript 형식 및 인터페이스를 정의합니다.
index.ts - 서버가 HTTP 연결을 시작하고 수락하는 방법
이 파일은 index.ts MCP 서버의 주요 진입점입니다. 서버를 초기화하고, Express.js HTTP 서버를 설정하고, SSE(Server-Sent 이벤트) 엔드포인트에 대한 라우팅을 정의합니다.
MCP 서버 인스턴스 만들기
다음 코드 조각은 MCP 서버를 초기화하는데, 이는 코어 MCP StreamableHTTPServer 클래스에 대한 래퍼인 Server 클래스를 사용합니다. 이 클래스는 SSE(Server-Sent 이벤트)에 대한 전송 계층을 처리하고 클라이언트 연결을 관리합니다.
const server = new StreamableHTTPServer(
new Server(
{
name: 'todo-http-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
)
);
개념:
-
컴퍼지션 패턴:
SSEPServer하위 수준Server클래스 래핑 - 기능 선언: 서버가 도구를 지원하지만 리소스/프롬프트는 지원하지 않음을 알려 줍니다.
- 명명 규칙: 서버 이름이 MCP 식별의 일부가 됩니다.
Express 경로 설정
다음 코드 조각은 SSE 연결 및 메시지 처리에 대한 들어오는 HTTP 요청을 처리하도록 Express.js 서버를 설정합니다.
router.post('/messages', async (req: Request, res: Response) => {
await server.handlePostRequest(req, res);
});
router.get('/sse', async (req: Request, res: Response) => {
await server.handleGetRequest(req, res);
});
개념:
- 2 엔드포인트 패턴: SSE 연결을 설정하기 위한 GET, 메시지를 보내기 위한 POST
-
위임 패턴: Express 경로가 즉시
SSEPServer에게 위임합니다.
프로세스 수명 주기 관리
다음 코드 조각은 서버 시작 및 종료 신호 시 정상적으로 종료를 포함하여 서버의 수명 주기를 처리합니다.
process.on('SIGINT', async () => {
log.error('Shutting down server...');
await server.close();
process.exit(0);
});
개념:
- 우아한 종료: Ctrl+C를 통한 적절한 정리
- 비동기 정리: 서버 닫기 작업이 비동기입니다.
- 리소스 관리: SSE 연결에 중요
전송 계층: server.ts
이 파일은 server.ts MCP 서버에 대한 전송 계층을 구현하며, 특히 SSE(Server-Sent 이벤트) 연결을 처리하고 MCP 프로토콜 메시지를 라우팅합니다.
SSE 클라이언트 연결 설정 및 전송 만들기
클래스는 SSEPServer MCP 서버에서 Server-Sent 이벤트(SSE)를 처리하기 위한 기본 전송 계층입니다. 클래스를 SSEServerTransport 사용하여 개별 클라이언트 연결을 관리합니다. 여러 전송 프로토콜 및 그 수명 주기를 관리합니다.
export class SSEPServer {
server: Server;
transport: SSEServerTransport | null = null;
transports: Record<string, SSEServerTransport> = {};
constructor(server: Server) {
this.server = server;
this.setupServerRequestHandlers();
}
}
개념:
- 상태 관리: 현재 전송 및 모든 전송을 모두 추적합니다.
-
세션 매핑:
transports개체가 세션 ID를 전송 인스턴스에 매핑합니다. - 생성자 위임: 즉시 요청 처리기 설정
SSE 연결 설정(handleGetRequest)
이 handleGetRequest 메서드는 클라이언트가 엔드포인트에 GET 요청을 할 때 새 SSE 연결을 설정해야 합니다 /sse .
async handleGetRequest(req: Request, res: Response) {
log.info(`GET ${req.originalUrl} (${req.ip})`);
try {
log.info("Connecting transport to server...");
this.transport = new SSEServerTransport("/messages", res);
TransportsCache.set(this.transport.sessionId, this.transport);
res.on("close", () => {
if (this.transport) {
TransportsCache.delete(this.transport.sessionId);
}
});
await this.server.connect(this.transport);
log.success("Transport connected. Handling request...");
} catch (error) {
// Error handling...
}
}
개념:
-
전송 생성: 각 GET 요청마다 새로운
SSEServerTransport - 세션 관리: 캐시에 저장된 자동 생성된 세션 ID
- 이벤트 처리기: 연결 닫기 시 정리
-
MCP 연결:
server.connect()프로토콜 연결 설정 - 비동기 흐름: 연결 설정이 오류 경계와 비동기적입니다.
메시지 처리(handlePostRequest)
이 메서드는 handlePostRequest 들어오는 POST 요청을 처리하여 클라이언트에서 보낸 MCP 메시지를 처리합니다. 쿼리 매개 변수의 세션 ID를 사용하여 올바른 전송 인스턴스를 찾습니다.
async handlePostRequest(req: Request, res: Response) {
log.info(`POST ${req.originalUrl} (${req.ip}) - payload:`, req.body);
const sessionId = req.query.sessionId as string;
const transport = TransportsCache.get(sessionId);
if (transport) {
await transport.handlePostMessage(req, res, req.body);
} else {
log.error("Transport not initialized. Cannot handle POST request.");
res.status(400).json(/* error response */);
}
}
개념:
-
세션 조회: 쿼리 매개 변수를 사용하여
sessionId전송 찾기 - 세션 유효성 검사: 먼저 SSE 연결의 유효성을 검사합니다.
- 메시지 위임: 전송이 실제 메시지 처리를 처리합니다.
- 오류 응답: 누락된 세션에 대한 적절한 HTTP 오류 코드
MCP 프로토콜 처리기 설정(setupServerRequestHandlers)
이 메서드는 setupServerRequestHandlers MCP 프로토콜 요청에 대해 다음 처리기를 등록합니다.
-
ListToolsRequestSchema에 대한 핸들러로, 사용 가능한 TODO 도구의 목록을 반환합니다. -
CallToolRequestSchema핸들러는 제공된 인수를 사용하여 요청된 도구를 찾아서 실행합니다.
이 메서드는 Zod 스키마를 사용하여 예상된 요청 및 응답 형식을 정의합니다.
private setupServerRequestHandlers() {
this.server.setRequestHandler(ListToolsRequestSchema, async (_request) => {
return {
tools: TodoTools,
};
});
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
const tool = TodoTools.find((tool) => tool.name === name);
if (!tool) {
return this.createJSONErrorResponse(`Tool "${name}" not found.`);
}
const response = await tool.execute(args as any);
return { content: [{ type: "text", text: response }] };
});
}
개념:
- Schema-Based 라우팅: 형식 안전 요청 처리에 Zod 스키마 사용
-
도구 검색:
ListToolsRequestSchema정적 TodoTools 배열을 반환합니다. -
도구 실행:
CallToolRequestSchema도구 찾기 및 실행 - 오류 처리: 알 수 없는 도구의 정상적인 처리
- 응답 형식: MCP 규격 응답 구조
- 형식 안전성: TypeScript 형식은 올바른 인수 전달을 보장합니다.
비즈니스 논리: tools.ts
이 파일은 tools.ts MCP 클라이언트에서 사용할 수 있는 실제 기능을 정의합니다.
- 도구 메타데이터(이름, 설명, 스키마)
- 입력 유효성 검사 스키마
- 도구 실행 논리
- 데이터베이스 계층과의 통합
이 MCP 서버는 4개의 TODO 관리 도구를 정의합니다.
-
add_todo: 새 TODO 항목을 만듭니다. -
complete_todo: TODO 항목을 완료됨으로 표시 -
delete_todo: TODO 항목을 삭제합니다. -
list_todos: 모든 TODO 항목을 나열합니다. -
update_todo_text: 기존 TODO 항목의 텍스트를 업데이트합니다.
도구 정의 패턴
도구는 각각 특정 TODO 작업을 나타내는 개체의 배열로 정의됩니다. 다음 코드 조각 addTodo 에서 도구가 정의됩니다.
{
name: "addTodo",
description: "Add a new TODO item to the list...",
inputSchema: {
type: "object",
properties: {
text: { type: "string" },
},
required: ["text"],
},
outputSchema: { type: "string" },
async execute({ text }: { text: string }) {
const info = await addTodo(text);
return `Added TODO: ${text} (id: ${info.lastInsertRowid})`;
},
}
각 도구 정의에는 다음이 있습니다.
-
name: 도구의 고유 식별자 -
description: 도구의 용도에 대한 간략한 설명 -
inputSchema: 예상 입력 형식을 정의하는 Zod 스키마 -
outputSchema: 예상 출력 형식을 정의하는 Zod 스키마 -
execute: 도구의 논리를 구현하는 함수
이러한 도구 정의는 server.ts에 가져와서 ListToolsRequestSchema 핸들러를 통해 노출됩니다.
개념:
- 모듈식 도구 디자인: 각 도구는 자체 포함 개체입니다.
-
JSON 스키마 유효성 검사:
inputSchema예상 매개 변수 정의 - 형식 안전성: TypeScript 형식이 스키마 정의와 일치합니다.
- 비동기 실행: 모든 도구 실행은 비동기입니다.
- 데이터베이스 통합: 가져온 데이터베이스 함수 호출
- Human-Readable 응답: 원시 데이터가 아닌 형식이 지정된 문자열을 반환합니다.
도구 배열 내보내기
도구는 정적 배열로 내보내므로 서버에서 쉽게 가져오고 사용할 수 있습니다. 각 도구는 메타데이터 및 실행 논리가 있는 개체입니다. 이 구조를 사용하면 MCP 서버가 클라이언트 요청에 따라 도구를 동적으로 검색하고 실행할 수 있습니다.
export const TodoTools = [
{ /* addTodo */ },
{ /* listTodos */ },
{ /* completeTodo */ },
{ /* deleteTodo */ },
{ /* updateTodoText */ },
];
개념:
- 정적 등록: 모듈 로드 시 정의된 도구
- 배열 구조: 간단한 배열을 사용하면 도구를 쉽게 반복할 수 있습니다.
- 가져오기/내보내기: 서버 논리로부터 명확히 분리하기
도구 실행 오류 처리
각 도구의 execute 함수는 오류를 원활하게 처리하고 예외를 throw하는 대신 명확한 메시지를 반환합니다. 이 방법을 사용하면 MCP 서버가 원활한 사용자 환경을 제공할 수 있습니다.
도구는 다음과 같은 다양한 오류 시나리오를 처리합니다.
async execute({ id }: { id: number }) {
const info = await completeTodo(id);
if (info.changes === 0) {
return `TODO with id ${id} not found.`;
}
return `Marked TODO ${id} as completed.`;
}
개념:
-
데이터베이스 응답 검사: 오류를 감지하는 데 사용
info.changes - 우아한 성능 저하: 설명 오류 메시지를 반환하는 대신 throw를 사용합니다.
- User-Friendly 오류: AI 해석에 적합한 메시지
데이터 계층: db.ts
이 파일은 db.ts SQLite 데이터베이스 연결을 관리하고 TODO 앱에 대한 CRUD 작업을 처리합니다. 동기 데이터베이스 액세스에 better-sqlite3 라이브러리를 사용합니다.
데이터베이스 초기화
데이터베이스는 SQLite에 연결하고 테이블이 없는 경우 테이블을 만들어 초기화합니다. 다음 코드 조각은 초기화 프로세스를 보여줍니다.
const db = new Database(":memory:", {
verbose: log.info,
});
try {
db.pragma("journal_mode = WAL");
db.prepare(
`CREATE TABLE IF NOT EXISTS ${DB_NAME} (
id INTEGER PRIMARY KEY AUTOINCREMENT,
text TEXT NOT NULL,
completed INTEGER NOT NULL DEFAULT 0
)`
).run();
log.success(`Database "${DB_NAME}" initialized.`);
} catch (error) {
log.error(`Error initializing database "${DB_NAME}":`, { error });
}
개념:
-
In-Memory 데이터베이스:
:memory:다시 시작할 때 데이터가 손실됨을 의미합니다(데모/테스트에만 해당). - WAL 모드: 성능 향상을 위한 Write-Ahead 로깅
- 스키마 정의: 자동 증가 ID가 있는 간단한 TODO 테이블
- 오류 처리: 초기화 오류의 정상적인 처리
- 로깅 통합: 디버깅을 위해 데이터베이스 작업이 기록됩니다.
CRUD 작업 패턴
이 파일은 db.ts TODO 항목을 관리하기 위한 네 가지 주요 CRUD 작업을 제공합니다.
작업 만들기:
export async function addTodo(text: string) {
log.info(`Adding TODO: ${text}`);
const stmt = db.prepare(`INSERT INTO todos (text, completed) VALUES (?, 0)`);
return stmt.run(text);
}
읽기 작업:
export async function listTodos() {
log.info("Listing all TODOs...");
const todos = db.prepare(`SELECT id, text, completed FROM todos`).all() as Array<{
id: number;
text: string;
completed: number;
}>;
return todos.map(todo => ({
...todo,
completed: Boolean(todo.completed),
}));
}
업데이트 작업:
export async function completeTodo(id: number) {
log.info(`Completing TODO with ID: ${id}`);
const stmt = db.prepare(`UPDATE todos SET completed = 1 WHERE id = ?`);
return stmt.run(id);
}
삭제 작업:
export async function deleteTodo(id: number) {
log.info(`Deleting TODO with ID: ${id}`);
const row = db.prepare(`SELECT text FROM todos WHERE id = ?`).get(id) as
| { text: string }
| undefined;
if (!row) {
log.error(`TODO with ID ${id} not found`);
return null;
}
db.prepare(`DELETE FROM todos WHERE id = ?`).run(id);
log.success(`TODO with ID ${id} deleted`);
return row;
}
개념:
- 준비된 문장: SQL 삽입으로부터 보호
- 형식 캐스팅: 쿼리 결과에 대한 명시적 TypeScript 형식
- 데이터 변환: SQLite 정수를 부울로 변환하기
- 원자성 작업: 각 함수는 단일 데이터베이스 트랜잭션입니다.
- 반환 값 일관성: 함수가 작업 메타데이터를 반환합니다.
- 방어 프로그래밍: 삭제 전 검사 패턴
스키마 디자인
데이터베이스 스키마는 간단한 SQL 문을 사용하여 파일에 정의 db.ts 됩니다. 테이블에는 todos 세 개의 필드가 있습니다.
CREATE TABLE todos (
id INTEGER PRIMARY KEY AUTOINCREMENT, -- Unique identifier
text TEXT NOT NULL, -- TODO description
completed INTEGER NOT NULL DEFAULT 0 -- Boolean as integer
);
도우미 유틸리티: helpers/ 디렉터리
helpers/ 디렉터리에서는 서버에 대한 유틸리티 함수 및 클래스를 제공합니다.
디버깅 및 모니터링을 위한 구조적 로깅: helpers/logs.ts
이 파일은 helpers/logs.ts MCP 서버에 대한 구조적 로깅 유틸리티를 제공합니다. 로깅에는 debug 라이브러리를 사용하고, 콘솔에서 색으로 구분된 출력에는 chalk 라이브러리를 사용합니다.
export const logger = (namespace: string) => {
const dbg = debug('mcp:' + namespace);
const log = (colorize: ChalkInstance, ...args: any[]) => {
const timestamp = new Date().toISOString();
const formattedArgs = [timestamp, ...args].map((arg) => {
if (typeof arg === 'object') {
return JSON.stringify(arg, null, 2);
}
return arg;
});
dbg(colorize(formattedArgs.join(' ')));
};
return {
info(...args: any[]) { log(chalk.cyan, ...args); },
success(...args: any[]) { log(chalk.green, ...args); },
warn(...args: any[]) { log(chalk.yellow, ...args); },
error(...args: any[]) { log(chalk.red, ...args); },
};
};
SSE 전송에 대한 세션 관리: helpers/cache.ts
파일 helpers/cache.ts은 Map를 사용하여 세션 ID별로 SSE 전송을 저장합니다. 이 방법을 사용하면 서버가 활성 연결을 빠르게 찾고 관리할 수 있습니다.
import type { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse";
export const TransportsCache = new Map<string, SSEServerTransport>();
비고
간단한 TransportsCache 메모리 내 캐시입니다. 프로덕션 환경에서는 세션 관리를 위해 Redis 또는 데이터베이스와 같은 보다 강력한 솔루션을 사용하는 것이 좋습니다.
실행 흐름 요약
다음 다이어그램에서는 도구 실행 및 데이터베이스 작업을 포함하여 클라이언트에서 MCP 서버로의 전체 요청 과정을 보여 줍니다.
GitHub Codespaces 정리
GitHub Codespaces 환경을 삭제하여 코어당 무료 시간을 최대화합니다.
중요합니다
GitHub 계정의 무료 스토리지 및 코어 시간에 대한 자세한 내용은 GitHub Codespaces 월별 포함된 스토리지 및 코어 시간을 참조하세요.
GitHub Codespaces 대시보드로그인합니다.
Azure-Samples//mcp-container-tsGitHub 리포지토리에서 생성된 활성 Codespaces를 찾으세요.코드스페이스에 대한 상황에 맞는 메뉴를 열고 삭제선택합니다.
도움받기
리포지토리의 문제에 문제를 기록합니다.