2025년 SaaS 제품을 위한 MCP 서버 구축 방법
AI 에이전트를 위한 MCP 서버 구축 가이드
2025년 AI 도구 분야를 주목하고 있다면, Model Context Protocol (MCP)이 "Anthropic의 흥미로운 스펙"에서 "모든 진지한 SaaS 제품이 지원해야 하는 것"으로 진화했다는 것을 눈치챘을 것입니다. 그리고 당연한 이유가 있습니다. MCP는 AI 에이전트(Claude, GPT 기반 어시스턴트, 커스텀 에이전트)에게 표준화된 방식으로 API를 발견하고 호출할 수 있게 해줍니다. agentic 시대를 위한 OpenAPI라고 생각하면 되지만, 실시간 양방향 통신이 내장되어 있습니다.
저는 지난 몇 개월간 여러 SaaS 제품을 위해 MCP 서버를 구축했으며, 실제로 작동하는 것, 문서에서 다루지 않는 것, 중요한 아키텍처 결정에 관해 공유하고 싶습니다. 이것은 스펙의 재탕이 아닙니다. 이것은 제가 시작했을 때 가졌으면 좋았을 가이드입니다.
목차
- Model Context Protocol (MCP)이란?
- SaaS 제품이 MCP 서버가 필요한 이유
- MCP 아키텍처: 실제로는 어떻게 작동하는가
- MCP 서버 프로젝트 설정
- 도구, 리소스 및 프롬프트 정의
- SaaS API에 연결
- 인증 및 멀티테넌시
- 에러 처리 및 유효성 검사
- MCP 서버 테스트
- 배포 및 프로덕션 고려사항
- 실제 사례: 프로젝트 관리 SaaS용 MCP 서버 구축
- FAQ
Model Context Protocol (MCP)이란?
MCP는 Anthropic이 원래 만든 오픈 프로토콜로, AI 모델이 외부 도구 및 데이터 소스와 통신하는 방식을 정의합니다. 2024년 말 릴리스되고 2025년 초 v1.0 안정성에 도달했으며, 현재 Claude Desktop, Cursor, Windsurf, OpenAI Agents SDK 및 수십 개의 다른 AI 클라이언트에서 지원합니다.
핵심 아이디어: 모든 AI 통합이 독점 형식의 커스텀 플러그인인 대신, MCP는 호환되는 모든 클라이언트가 서비스가 무엇을 제공하는지 발견하고 상호작용할 수 있도록 하는 단일 프로토콜을 제공합니다.
MCP가 정의하는 것:
- 도구 -- AI가 호출할 수 있는 함수 (
create_ticket,search_users,generate_report등) - 리소스 -- AI가 읽을 수 있는 데이터 (설명서, 데이터베이스 레코드, 설정 파일 등)
- 프롬프트 -- 서버가 노출할 수 있는 재사용 가능한 프롬프트 템플릿
- 샘플링 -- 서버가 클라이언트로부터 LLM 완성을 요청할 수 있는 기능
전송 계층은 stdio(로컬 서버의 경우) 또는 Server-Sent Events(SSE)를 사용한 HTTP(원격 서버의 경우)를 통해 JSON-RPC 2.0을 사용합니다. 2025-03 스펙 개정에서 도입된 최신 Streamable HTTP 전송이 프로덕션 SaaS 배포에 사용하려는 것입니다.
SaaS 제품이 MCP 서버가 필요한 이유
직설적으로 말씀드리겠습니다: SaaS 제품에 API가 있다면 지금 바로 MCP 서버를 구축해야 합니다. 이유는 다음과 같습니다.
AI 에이전트가 주요 API 소비자가 되고 있습니다. 2025년 1분기, Anthropic은 Claude Desktop 사용자가 매일 MCP 도구를 200만 번 이상 호출한다고 보고했습니다. 그 숫자는 빠르게 증가하고 있습니다. 고객들은 이미 AI 에이전트를 사용하여 제품과 상호작용하려고 시도하고 있습니다. 문제는 그것을 쉽게 만드느냐 답답하게 만드느냐입니다.
배포 채널입니다. Claude Desktop을 설치하고 "프로젝트 관리를 도와줘"라고 입력하면, AI가 사용자가 설정한 MCP 서버를 발견하고 사용할 수 있습니다. 제품이 자연어를 통해 접근 가능해집니다. 이것은 요술이 아닙니다. 제품의 새로운 표면 영역입니다.
경쟁사들이 이미 구축했습니다. Stripe, Linear, Notion, GitHub, Sentry, Supabase 모두 2025년 상반기에 MCP 서버를 출시했습니다. B2B SaaS에 있는데 MCP 서버가 없다면, 뒤처지고 있는 것입니다.
| 요소 | REST API만 | REST API + MCP 서버 |
|---|---|---|
| AI 에이전트 접근성 | 에이전트당 커스텀 통합 필요 | 모든 MCP 클라이언트가 자동으로 작동 |
| 발견 | 개발자가 문서를 읽음 | AI가 런타임에 기능 발견 |
| 첫 통합까지의 시간 | 시간~일 | 분 |
| 자연어 상호작용 | 래퍼 없이는 불가능 | 내장됨 |
| 유지보수 부담 | 하나의 코드베이스 | 두 개의 코드베이스 (하지만 MCP가 REST를 감싼다) |
MCP 아키텍처: 실제로는 어떻게 작동하는가
코드를 작성하기 전에 아키텍처를 명확히 합시다. MCP 배포는 세 부분으로 이루어집니다:
- MCP 클라이언트 -- AI 애플리케이션 (Claude Desktop, Cursor, 커스텀 에이전트). 서버의 기능을 발견하고 호출합니다.
- MCP 서버 -- 제 코드. 도구, 리소스, 프롬프트를 MCP 프로토콜을 통해 노출합니다. 이것이 우리가 구축할 것입니다.
- SaaS API -- MCP 서버가 작업을 수행하기 위해 호출하는 실제 백엔드.
흐름은 다음과 같습니다:
사용자 → AI 클라이언트 → MCP 클라이언트 → MCP 서버 → SaaS API
↓
응답이 역으로 흘러감
MCP 서버는 기본적으로 프로토콜 어댑터입니다. MCP 프로토콜(AI 클라이언트가 사용하는)과 기존 REST/GraphQL API 사이의 번역입니다. 즉, 기존 API를 전혀 수정할 필요가 없습니다. MCP 서버가 옆에 있습니다.
전송 옵션
SaaS 제품의 경우 두 가지 현실적인 전송 옵션이 있습니다:
- Streamable HTTP (권장): 표준 HTTP 요청 및 스트리밍을 위한 선택적 SSE를 사용합니다. 로드 밸런서, CDN 및 표준 인프라 뒤에서 작동합니다. 원격/호스팅 MCP 서버의 경우 이것이 원하는 것입니다.
- SSE (레거시): 원본 원격 전송. 여전히 작동하지만 스펙은 새로운 구현을 위해 Streamable HTTP를 권장합니다.
Stdio 전송은 로컬 도구에 좋지만 SaaS 제품의 MCP 서버에는 적용할 수 없습니다.
MCP 서버 프로젝트 설정
TypeScript로 구축합시다. 공식 @modelcontextprotocol/sdk 패키지는 잘 유지보수되며 프로덕션 사용에 올바른 선택입니다. Python은 그 스택이라면 mcp (공식 Python SDK)가 있지만, 제가 작업하는 대부분의 SaaS 백엔드가 Node.js를 사용하므로 TypeScript에 초점을 맞추겠습니다.
mkdir my-saas-mcp-server
cd my-saas-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod express
npm install -D typescript @types/node @types/express tsx
tsconfig.json을 설정하세요:
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"]
}
이제 기본 서버 구조를 만들어봅시다:
// src/server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import express from "express";
const app = express();
app.use(express.json());
const server = new McpServer({
name: "my-saas-mcp",
version: "1.0.0",
description: "MCP server for My SaaS Product",
});
// 도구, 리소스, 프롬프트를 여기에 추가합니다
app.post("/mcp", async (req, res) => {
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => crypto.randomUUID(),
});
await server.connect(transport);
await transport.handleRequest(req, res);
});
app.get("/mcp", async (req, res) => {
// 스트리밍 응답을 위한 SSE 엔드포인트
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => crypto.randomUUID(),
});
await server.connect(transport);
await transport.handleRequest(req, res);
});
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log(`MCP server running on port ${PORT}`);
});
이것이 골격입니다. 채워봅시다.
도구, 리소스 및 프롬프트 정의
도구
도구는 가장 중요한 기본 요소입니다. 각 도구는 구조화된 매개변수로 AI가 호출할 수 있는 함수입니다. 정의 방법은 다음과 같습니다:
import { z } from "zod";
server.tool(
"create_project",
"Create a new project in the workspace",
{
name: z.string().describe("The project name"),
description: z.string().optional().describe("Project description"),
team_id: z.string().describe("ID of the team that owns this project"),
},
async ({ name, description, team_id }) => {
// SaaS API를 여기에서 호출합니다
const project = await apiClient.createProject({ name, description, team_id });
return {
content: [
{
type: "text",
text: JSON.stringify(project, null, 2),
},
],
};
}
);
도구 설계에 대해 배운 몇 가지:
설명을 구체적으로 작성하세요. AI는 도구 설명과 매개변수 설명을 사용하여 언제 어떻게 호출할지 결정합니다. 모호한 설명은 잘못된 도구 선택으로 이어집니다. "새 프로젝트 만들기"는 괜찮습니다. "사용자 워크스페이스에 새 프로젝트를 만듭니다. list_teams 도구에서 얻을 수 있는 team_id가 필요합니다"는 훨씬 낫습니다.
도구 개수를 관리 가능하게 유지하세요. 50개 이상의 도구를 노출하고 AI가 혼동하는 이유를 궁금해하는 사람들을 봤습니다. 10-15개의 핵심 작업으로 시작하세요. 항상 더 추가할 수 있습니다.
구조화된 데이터를 반환하세요. 항상 텍스트 콘텐츠로 JSON을 반환하세요. AI는 산문보다 더 잘 파싱합니다.
리소스
리소스는 읽을 수 있는 데이터를 노출합니다. AI 소비를 위한 GET 엔드포인트로 생각하면 됩니다:
server.resource(
"project-list",
"projects://list",
"List of all projects in the workspace",
async () => {
const projects = await apiClient.listProjects();
return {
contents: [
{
uri: "projects://list",
mimeType: "application/json",
text: JSON.stringify(projects, null, 2),
},
],
};
}
);
프롬프트
프롬프트는 재사용 가능한 템플릿입니다. 저활용되지만 강력합니다:
server.prompt(
"weekly-report",
"Generate a weekly status report for a project",
{
project_id: z.string().describe("The project ID to report on"),
},
async ({ project_id }) => {
const stats = await apiClient.getProjectStats(project_id);
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `Generate a weekly status report based on this data: ${JSON.stringify(stats)}. Include completed tasks, blockers, and upcoming deadlines.`,
},
},
],
};
}
);
SaaS API에 연결
MCP 서버는 기존 API와 통신해야 합니다. 타입이 지정된 API 클라이언트 클래스를 만드는 것을 권장합니다:
// src/api-client.ts
class SaaSApiClient {
private baseUrl: string;
private apiKey: string;
constructor(baseUrl: string, apiKey: string) {
this.baseUrl = baseUrl;
this.apiKey = apiKey;
}
private async request<T>(path: string, options?: RequestInit): Promise<T> {
const response = await fetch(`${this.baseUrl}${path}`, {
...options,
headers: {
"Authorization": `Bearer ${this.apiKey}`,
"Content-Type": "application/json",
...options?.headers,
},
});
if (!response.ok) {
const error = await response.text();
throw new Error(`API error ${response.status}: ${error}`);
}
return response.json() as T;
}
async createProject(data: CreateProjectInput): Promise<Project> {
return this.request<Project>("/api/v1/projects", {
method: "POST",
body: JSON.stringify(data),
});
}
async listProjects(): Promise<Project[]> {
return this.request<Project[]>("/api/v1/projects");
}
// ... 더 많은 메서드
}
이 클라이언트를 얇게 유지하세요. 통과 기능이지, 비즈니스 로직 계층이 아닙니다.
인증 및 멀티테넌시
이것이 흥미로워지는 부분입니다. 대부분의 튜토리얼이 어려운 부분을 무시합니다.
MCP 서버는 두 가지 방식으로 요청을 인증해야 합니다:
- MCP 클라이언트가 MCP 서버에 인증 ("이것이 유효한 사용자인가?")
- MCP 서버가 SaaS API에 인증 ("이 사용자를 대신하여 작동")
OAuth 2.0 (프로덕션에 권장)
MCP 스펙에는 OAuth 2.1을 기반으로 하는 인증 프레임워크가 포함됩니다. SaaS 제품의 경우 이것이 올바른 접근입니다:
// OAuth 토큰을 추출하고 유효성을 검사하는 미들웨어
app.use("/mcp", async (req, res, next) => {
const authHeader = req.headers.authorization;
if (!authHeader?.startsWith("Bearer ")) {
return res.status(401).json({ error: "Missing authorization" });
}
const token = authHeader.slice(7);
try {
const user = await validateOAuthToken(token);
req.user = user;
next();
} catch {
return res.status(401).json({ error: "Invalid token" });
}
});
그런 다음 도구 핸들러에 사용자 컨텍스트를 전달합니다. 멀티테넌시의 경우 이것이 중요합니다. 모든 API 호출은 인증된 사용자의 워크스페이스로 범위가 지정되어야 합니다.
API 키 접근법 (더 간단하고, 내부/초기 단계용)
초기 단계이거나 내부 전용이라면 API 키가 잘 작동합니다:
const apiKey = req.headers["x-api-key"] as string;
const client = new SaaSApiClient(process.env.API_BASE_URL!, apiKey);
사용자가 MCP 클라이언트에서 MCP 서버를 구성할 때 API 키를 제공하고, API에 전달됩니다.
에러 처리 및 유효성 검사
AI 에이전트는 명확한 에러 메시지가 필요합니다. 도구가 실패하면, AI는 왜 실패했는지 알아야 입력을 수정하거나 문제를 사용자에게 설명할 수 있습니다.
server.tool(
"get_project",
"Get project details by ID",
{ project_id: z.string().uuid().describe("The project's UUID") },
async ({ project_id }) => {
try {
const project = await apiClient.getProject(project_id);
return {
content: [{ type: "text", text: JSON.stringify(project, null, 2) }],
};
} catch (error) {
const message = error instanceof Error ? error.message : "Unknown error";
return {
isError: true,
content: [
{
type: "text",
text: `Failed to get project: ${message}. Make sure the project_id is a valid UUID and the project exists in your workspace.`,
},
],
};
}
}
);
isError: true 플래그에 주목하세요. 이것은 AI 클라이언트에게 도구 호출이 실패했음을 알려주므로 적절히 처리할 수 있습니다. 항상 에러 메시지에 실행 가능한 지도를 포함하세요.
MCP 서버 테스트
MCP 서버를 테스트하는 것이 2025년에 훨씬 쉬워졌습니다. 옵션은 다음과 같습니다:
MCP Inspector
공식 MCP Inspector는 개발 중에 최고의 친구입니다:
npx @modelcontextprotocol/inspector
이것은 서버에 연결하고, 도구/리소스를 탐색하고, 대화식으로 호출할 수 있는 웹 UI를 제공합니다. 지속적으로 사용하세요.
자동화된 테스트
CI/CD의 경우 도구를 일반 async 함수로 테스트하세요:
import { describe, it, expect } from "vitest";
describe("create_project tool", () => {
it("should create a project with valid input", async () => {
const result = await createProjectHandler({
name: "Test Project",
team_id: "team-123",
});
expect(result.isError).toBeUndefined();
const data = JSON.parse(result.content[0].text);
expect(data.name).toBe("Test Project");
});
it("should return error for missing team_id", async () => {
// Zod 유효성 검사가 핸들러를 실행하기 전에 이를 포착해야 합니다
// 유효성 검사 계층을 테스트합니다
});
});
Claude Desktop과의 통합 테스트
서버가 실행 중이면 Claude Desktop의 설정에 추가하세요:
{
"mcpServers": {
"my-saas": {
"url": "http://localhost:3001/mcp",
"headers": {
"Authorization": "Bearer your-test-token"
}
}
}
}
그런 다음 Claude와 대화하고 도구를 자연스럽게 사용해 보세요. 자동화된 테스트가 놓치는 엣지 케이스를 빠르게 발견하게 됩니다.
배포 및 프로덕션 고려사항
배포할 위치
MCP 서버는 그냥 Express 앱입니다. Node.js 서비스를 배포하는 곳 어디든 배포하세요. 좋은 옵션 몇 가지:
| 플랫폼 | 콜드 스타트 | 비용 (추정) | 최적 사용처 |
|---|---|---|---|
| Railway | 없음 | ~$5-20/월 | 소-중형 SaaS |
| Fly.io | <500ms | ~$5-15/월 | 전역 배포 |
| AWS ECS/Fargate | 없음 | ~$15-50/월 | 엔터프라이즈, 기존 AWS |
| Vercel (Edge) | <100ms | $0-20/월 | Vercel에 이미 있는 경우 |
| Cloudflare Workers | <5ms | $0-5/월 | 성능이 중요한 경우 |
속도 제한
AI 에이전트는 수다스러울 수 있습니다. 단일 사용자 대화가 20-30개의 도구 호출을 트리거할 수 있습니다. 정상적인 AI 사용에는 충분히 관대하지만 남용을 방지하는 속도 제한을 구현하세요:
import rateLimit from "express-rate-limit";
const limiter = rateLimit({
windowMs: 60 * 1000, // 1분
max: 60, // 사용자당 분당 60개 요청
keyGenerator: (req) => req.user?.id || req.ip,
});
app.use("/mcp", limiter);
모니터링
모든 도구 호출을 사용자 ID, 도구 이름, 지연 시간과 함께 로깅하세요. 어떤 도구가 가장 많이 사용되고, 어떤 도구가 가장 많이 실패하고, 지연 시간의 병목이 어디 있는지 확인하고 싶습니다. Datadog, Axiom 또는 CloudWatch에 대한 구조화된 JSON 로그도 잘 작동합니다.
버전 관리
MCP 서버는 진화할 것입니다. 서버 메타데이터에서 version 필드를 사용하고 전환 중에 경로 접두사 (/mcp/v1, /mcp/v2) 뒤에서 여러 버전을 실행하는 것을 고려하세요.
실제 사례: 프로젝트 관리 SaaS용 MCP 서버 구축
실제 사례를 살펴봅시다. 프로젝트 관리 도구용 MCP 서버를 구축하고 있다고 가정합시다 (단순화된 Linear 또는 Asana처럼).
노출할 도구 세트는 다음과 같습니다:
// 핵심 CRUD 도구
server.tool("list_projects", ...);
server.tool("get_project", ...);
server.tool("create_project", ...);
server.tool("update_project", ...);
// 작업 관리
server.tool("list_tasks", ...); // 상태, 담당자, 프로젝트별 필터
server.tool("create_task", ...);
server.tool("update_task", ...); // 상태, 담당자, 우선순위 업데이트
server.tool("add_comment", ...);
// 검색 및 보고
server.tool("search", ...); // 프로젝트와 작업에 걸쳐 전체 텍스트 검색
server.tool("get_project_stats", ...); // 프로젝트의 요약 통계
// 리소스
server.resource("workspace-info", ...); // 워크스페이스 설정, 팀 멤버
// 프롬프트
server.prompt("standup-report", ...); // 최근 활동으로부터 standup 생성
server.prompt("sprint-planning", ...); // sprint 계획 지원
12개의 도구, 1개의 리소스, 2개의 프롬프트입니다. AI의 도구 선택을 압도하지 않으면서 진정으로 유용할 만큼 충분합니다.
사용자 경험은 다음과 같습니다: 누군가 Claude Desktop을 열고 "Backend Rewrite 프로젝트의 어떤 작업이 기한을 넘었나?"라고 말합니다. Claude는 상태 필터와 프로젝트 이름으로 list_tasks를 호출하고, 결과를 받고, 자연어로 제시합니다. 사용자가 "인증 마이그레이션 작업을 Sarah에게 할당하고 우선순위를 높음으로 올려"라고 말합니다. Claude는 update_task를 호출합니다. 마법처럼 느껴지지만, 실제로는 프로토콜 배관일 뿐입니다.
이런 것을 구축하고 있는데 Next.js 프론트엔드나 보통 이런 프로젝트를 수반하는 headless CMS 계층의 도움이 필요하다면, Social Animal에서 많이 하는 것입니다. 하지만 MCP 서버 자체는? 이 가이드를 통해 사내에서 절대적으로 구축할 수 있습니다.
FAQ
MCP와 function calling의 차이점은?
Function calling (OpenAI의 function calling 또는 Claude의 tool use 같은)은 AI 모델이 단일 API 호출 내에서 함수를 호출하기로 결정하는 방식입니다. MCP는 AI 클라이언트가 외부 서버에서 어떤 함수를 사용할 수 있는지 발견할 수 있는 프로토콜입니다. 함께 작동합니다. AI 클라이언트는 MCP 도구를 언제 호출할지 결정하기 위해 function calling을 내부적으로 사용합니다. MCP를 시스템 간의 배관으로, function calling을 모델의 의사결정 프로세스로 생각하세요.
MCP 서버를 구축하고 실행하는 데 비용이 얼마나 드나요?
서버 자체는 가볍습니다. 10-20개의 도구가 있는 일반적인 SaaS 제품의 경우, 수백 줄의 TypeScript 정도입니다. 호스팅 비용은 트래픽과 플랫폼에 따라 $5-50/월입니다. 실제 비용은 개발자 시간입니다. 인증, 에러 처리, 모니터링, 테스트가 있는 프로덕션 품질 MCP 서버에 2-4주를 예산으로 계획하세요. 이것이 많은 것처럼 느껴진다면, 우리는 팀이 더 빨리 배포하도록 도왔습니다. 세부사항은 가격 페이지를 확인하세요.
Python 대신 TypeScript를 사용할 수 있나요?
절대적으로 가능합니다. 공식 Python SDK (pip install mcp)는 훌륭하며 아마도 도구 정의에 대해 더 나은 인체공학을 가지고 있습니다. 팀이 아는 것을 무엇이든 사용하세요. 프로토콜은 언어 무관입니다. SaaS 백엔드가 Python (Django, FastAPI)이면, MCP 서버를 Python으로 구축하는 것이 더 의미가 있으므로 모델과 유효성 검사 로직을 공유할 수 있습니다.
기존 API를 수정해야 하나요?
아닙니다. MCP 서버는 기존 API를 호출하는 별도의 서비스입니다. 어댑터 계층입니다. 즉, AI 소비를 위해 특별히 설계된 몇 가지 API 엔드포인트를 추가하고 싶을 수도 있습니다. 예를 들어 UI가 필요로 하는 것보다 더 많은 컨텍스트를 반환하는 검색 엔드포인트입니다. 괜찮습니다. 하지만 추가적입니다, 수정이 아닙니다.
장기간 실행되는 작업을 어떻게 처리하나요?
일부 도구가 시간이 오래 걸리는 작업을 트리거할 수 있습니다 (보고서 생성 또는 대규모 가져오기 처리 같은). MCP의 진행률 알림 기능을 사용하여 클라이언트에 알리세요. 도구 핸들러는 작업 완료를 기다리는 동안 진행률 업데이트를 내보낼 수 있습니다. 매우 장기 작업 (>30초)의 경우 즉시 작업 ID를 반환하고 별도의 check_job_status 도구를 제공하는 것을 고려하세요.
MCP는 프로덕션에 충분히 안정적인가요?
예, 2025년 중반 기준. 스펙이 2025년 3월에 v1.0에 도달했으며, 2025-03-26 개정판 (Streamable HTTP 추가)은 주요 클라이언트가 채택했습니다. Anthropic, Microsoft, Google, OpenAI 모두 프로토콜에 투자하고 있습니다. 사라지지 않을 것입니다. 즉, 스펙 업데이트를 계속 지켜보세요. 더 나은 인증 흐름과 서버 간 통신에 대한 활발한 제안이 있습니다.
MCP 도구에서 페이지 매김을 처리하는 가장 좋은 방법은?
합리적인 결과 페이지 (20-50개 항목)를 기본값으로 반환하고 cursor 또는 page 매개변수를 허용합니다. 응답에 페이지 매김 메타데이터를 포함하여 AI가 더 많은 결과가 있음을 알 수 있도록 합니다. 뭔가 이런 식: { results: [...], next_cursor: "abc123", total_count: 342 }. AI가 사용자가 더 많은 데이터가 필요하면 자연스럽게 다음 페이지를 요청합니다.
하나의 MCP 서버가 동시에 여러 AI 클라이언트를 지원할 수 있나요?
예, 그래야 합니다. MCP 서버는 그냥 HTTP 서버 동시 요청을 처리합니다. 각 요청은 사용자의 인증 토큰을 포함하므로 올바른 테넌트로 모든 것을 범위 지정합니다. Streamable HTTP 전송을 올바르게 사용하면 클라이언트 특정 상태에 대해 걱정할 필요가 없습니다. 다른 상태가 없는 API 서버처럼 취급하세요.