MCP 확장 방법
이 페이지에서는 두 가지 확장 가이드를 제공합니다. 하나는 Elftia에 새로운 MCP 전송 방식을 추가하는 방법이고, 다른 하나는 Elftia와 연동되는 커스텀 MCP 서버를 작성하는 방법입니다.
가이드 1: 새로운 전송 방식 추가
Stdio/SSE/HTTP 이외의 전송 방식(예: WebSocket, gRPC 등)을 지원해야 하는 경우, 다음 파일들을 수정해야 합니다.
수정 체크리스트
| 단계 | 파일 | 변경 내용 |
|---|---|---|
| 1 | packages/desktop/app/shared/contracts/mcp-types.ts | McpServerTransport 타입 확장 |
| 2 | packages/desktop/app/main/services/capabilities/tools/mcp-users/McpService.ts | createTransport()에 새 분기 추가 |
| 3 | packages/desktop/app/main/services/routers/McpRouter.ts | mcpAddSchema의 type 열거형 확장 |
| 4 | packages/renderer/src/features/settings/components/tabs/tools-tab/types.ts | 프론트엔드 타입 업데이트 |
| 5 | packages/renderer/src/features/settings/components/tabs/tools-tab/McpServerForm.tsx | 폼 옵션 추가 |
| 6 | i18n 파일 | 새 전송 방식의 표시 이름 추가 |
단계 1: 타입 확장
mcp-types.ts에 새 전송 방식 값을 추가합니다.
export type McpServerTransport = 'stdio' | 'http' | 'sse' | 'websocket';
McpServerConfig에 새 필드가 필요한지도 확인합니다.
export type McpServerConfig = {
command?: string;
args?: string[];
env?: Record<string, string>;
url?: string;
headers?: Record<string, string>;
transport?: string;
// 필요한 경우 새 필드 추가
wsProtocol?: string;
};
단계 2: 전송 계층 구현
McpService.ts의 createTransport() 메서드에 새 case 분기를 추가합니다.
private async createTransport(server: McpServerRecord) {
switch (server.type) {
case 'stdio':
// ...
case 'sse':
// ...
case 'http':
// ...
case 'websocket':
if (!server.config.url) {
throw new Error('WebSocket server requires url');
}
// WebSocket 전송 구현체 사용
return new WebSocketClientTransport(
new URL(server.config.url),
{ headers: server.config.headers || {} }
);
default:
throw new Error(`Unsupported transport type: ${server.type}`);
}
}
요구 사항: 전송 구현체는 MCP SDK의 Transport 인터페이스를 준수하고 Client.connect()와 함께 동작해야 합니다.
단계 3: IPC 유효성 검사 업데이트
McpRouter.ts의 Zod 스키마를 확장합니다.
const mcpAddSchema = z.object({
// ...
type: z.enum(['stdio', 'http', 'sse', 'websocket']),
// ...
});
단계 4-5: 프론트엔드 업데이트
McpServerForm.tsx의 전송 방식 선택기에 옵션을 추가합니다.
options={[
{ value: 'stdio', label: t('...stdio') },
{ value: 'sse', label: t('...sse') },
{ value: 'http', label: t('...http') },
{ value: 'websocket', label: t('...websocket') },
]}
새 전송 방식의 요구 사항에 따라 대응하는 설정 폼 필드(URL, 프로토콜 선택 등)를 추가합니다.
단계 6: 국제화
locales/{en,zh,ja}/settings/tools.json에 새 전송 방식의 표시 이름을 추가합니다.
가이드 2: 커스텀 MCP 서버 작성
Elftia와 연동되는 MCP 서버를 작성하려면 MCP 프로토콜 사양을 준수해야 합니다.
최소 Stdio 서버 (Node.js)
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server(
{ name: 'my-custom-server', version: '1.0.0' },
{
capabilities: {
tools: {}
}
}
);
// 툴 목록 등록
server.setRequestHandler('tools/list', async () => ({
tools: [
{
name: 'hello',
description: '인사말을 반환합니다',
inputSchema: {
type: 'object',
properties: {
name: { type: 'string', description: '인사할 이름' }
},
required: ['name']
}
}
]
}));
// 툴 호출 처리
server.setRequestHandler('tools/call', async (request) => {
if (request.params.name === 'hello') {
const name = request.params.arguments?.name ?? 'World';
return {
content: [
{ type: 'text', text: `Hello, ${name}!` }
]
};
}
return {
content: [{ type: 'text', text: 'Unknown tool' }],
isError: true
};
});
// 시작
const transport = new StdioServerTransport();
await server.connect(transport);
Elftia에서 사용하기
위 서버를 my-server.js로 저장한 후, Elftia에서 Stdio 서버를 추가합니다.
| 필드 | 값 |
|---|---|
| 이름 | my-custom-server |
| 전송 방식 | Stdio |
| 명령어 | node |
| 인수 | /path/to/my-server.js |
툴 정의 사양
Elftia는 MCP 툴에 대해 다음 요건을 요구합니다.
| 요건 | 설명 |
|---|---|
| 이름 | 반드시 제공해야 하며, 툴 ID 생성에 사용됩니다(mcp__server__name) |
| 설명 | 강력히 권장하며, LLM이 언제 호출할지 판단하는 기준이 됩니다 |
| inputSchema | 유효한 JSON Schema이어야 하며, type: 'object' 필요 |
| 반환 형식 | content 배열, 각 항목에 type과 해당 데이터 포함 |
반환 콘텐츠 타입
// 텍스트 반환
{ type: 'text', text: '결과 텍스트' }
// 이미지 반환
{ type: 'image', mimeType: 'image/png', data: '<base64-encoded>' }
// 오디오 반환
{ type: 'audio', mimeType: 'audio/wav', data: '<base64-encoded>' }
참고: Elftia의 McpToolAdapter는 이미지와 오디오를 플레이스홀더 텍스트([Image: mime])로 변환하며, 실제 바이너리 데이터는 ToolCallDisplay 컴포넌트에서 렌더링을 처리합니다.
타임아웃 주의 사항
Elftia는 MCP 툴 호출에 120초 타임아웃을 설정합니다. 툴이 장시간 작업을 수행할 가능성이 있는 경우 다음을 권장합니다.
- 비동기 처리를 구현하여 먼저 작업 ID를 반환하고 폴링 인터페이스를 제공
- 툴 설명에 예상 대기 시간 명시
- 스트리밍 반환 방식 검토(전송 계층이 지원하는 경우)
npm 패키지 배포
MCP 서버를 npm 패키지로 배포하여 npx로 원클릭 실행을 지원하려면:
-
package.json에bin필드를 설정합니다.{"name": "@yourorg/mcp-server-example","bin": {"mcp-server-example": "./dist/index.js"}} -
진입 파일에 shebang이 있는지 확인합니다.
#!/usr/bin/env node -
사용자는 Elftia에서 다음과 같이 설정합니다.
필드 값 명령어 npx인수 -y,@yourorg/mcp-server-example
공식 프리셋에 추가하기
MCP 서버를 Elftia의 공식 프리셋 목록에 포함시키려면 packages/desktop/app/shared/mcp-presets.ts에 설정을 추가합니다.
export const OFFICIAL_MCP_PRESETS: OfficialMcpPreset[] = [
// 기존 프리셋...
{
id: 'your-server-id',
name: 'Your Server Name',
provider: 'your-org',
category: 'general', // search | vision | web-reading | code-repo | general
description: '서버 기능 설명',
tools: ['tool1', 'tool2'],
command: 'npx',
args: ['-y', '@yourorg/mcp-server@latest'],
requiresApiKey: true,
apiKeyEnvVar: 'YOUR_API_KEY',
linkedProviderIds: ['provider-id'],
documentationUrl: 'https://docs.example.com',
icon: 'icon-name',
},
];
프리셋 필드 설명:
| 필드 | 필수 여부 | 설명 |
|---|---|---|
id | 필수 | 고유 식별자 |
name | 필수 | 표시 이름 |
provider | 필수 | 프로바이더 식별자 |
category | 필수 | 카테고리: search / vision / web-reading / code-repo / general |
description | 필수 | 기능 설명 |
tools | 필수 | 제공하는 툴 이름 목록 |
transportType | 선택 | stdio(기본값) / http |
command | Stdio 필요 | 실행 명령어 |
args | Stdio 필요 | 명령어 인수 |
url | HTTP 필요 | 원격 URL |
requiresApiKey | 필수 | API Key 필요 여부 |
apiKeyEnvVar | 선택 | API Key 환경 변수 이름 |
linkedProviderIds | 선택 | 연관된 LLM 프로바이더 ID (Key 자동 가져오기) |
extraEnv | 선택 | 추가 고정 환경 변수 |
documentationUrl | 선택 | 문서 링크 |
DependencyCheckService 확장
MCP 서버가 비표준 CLI 툴에 의존하는 경우, DependencyCheckService의 installCommand() 메서드를 확장할 수 있습니다.
파일 경로: packages/desktop/app/main/services/capabilities/tools/mcp-users/DependencyCheckService.ts
async installCommand(command: string): Promise<DependencyInstallResult> {
// ...
if (command === 'your-tool') {
return await this.installYourTool(command);
}
// ...
}
현재 지원되는 자동 설치 목록:
| 명령어 | 설치 방법 |
|---|---|
npx / npm / node | Windows: winget; macOS: Homebrew; 기타: 다운로드 페이지 |
uv / uvx | 공식 설치 스크립트 (Windows: PowerShell; Unix: curl + sh) |