Skip to content

트랜스포트

air는 네 가지 MCP 트랜스포트를 지원합니다. transport 설정으로 선택합니다.

stdio

표준 입출력. Claude Desktop이 서버를 자식 프로세스로 실행하고 stdin/stdout으로 통신합니다.

typescript
defineServer({
  transport: { type: 'stdio' },
});

포트 불필요. 로그는 stderr로 출력됩니다 (stdout은 MCP 프로토콜 전용).

SSE (Server-Sent Events)

HTTP 기반 원격 연결. 세션별 독립 MCP 서버 인스턴스가 생성됩니다.

typescript
defineServer({
  transport: { type: 'sse', port: 3510 },
});

SSE 엔드포인트

메서드경로설명
GET/sseSSE 스트림 연결 (새 세션 생성)
POST/message?sessionId=xxx메시지 전송
GET/서버 상태 JSON 반환
OPTIONS*CORS preflight (자동 처리)

클라이언트 연결 흐름:

  1. GET /sse → SSE 연결 수립, 세션 ID 발급
  2. POST /message?sessionId=xxx → MCP 메시지 전송
  3. 연결 종료 시 세션 자동 정리

터미널 출력:

[air] SSE server listening on port 3510
[air] SSE client connected (session: a1b2c3d4-...)
[air] SSE client disconnected (session: a1b2c3d4-...)

CORS

SSE 트랜스포트는 CORS 헤더를 자동으로 설정합니다:

  • Access-Control-Allow-Origin: *
  • Access-Control-Allow-Methods: GET, POST, OPTIONS
  • Access-Control-Allow-Headers: Content-Type

커스터마이즈하려면 corsPlugin을 사용하세요.

Streamable HTTP

최신 MCP 트랜스포트 스펙. 단일 엔드포인트로 모든 통신을 처리합니다.

typescript
defineServer({
  transport: { type: 'http', port: 3510 },
});
메서드설명
POSTMCP 메시지 처리
GET서버 상태 JSON 반환
DELETE세션 종료

각 세션에 고유 ID(crypto.randomUUID())가 자동 할당됩니다.

Cloudflare Workers

엣지 배포용 트랜스포트. Node.js http 서버 대신 Workers 런타임에 맞는 fetch() 핸들러를 노출합니다. MCP 프로토콜은 JSON-RPC 2.0으로 직접 처리합니다 (런타임에 MCP SDK 의존성 없음).

typescript
import { defineServer, defineTool } from '@airmcp-dev/core';

const server = defineServer({
  name: 'my-edge-server',
  transport: { type: 'workers' },
  tools: [
    defineTool('hello', {
      params: { name: 'string' },
      handler: async ({ name }) => `Hello, ${name}!`,
    }),
  ],
});

export default {
  async fetch(request: Request, env: any): Promise<Response> {
    const url = new URL(request.url);

    // MCP 엔드포인트
    if (request.method === 'POST' && url.pathname === '/') {
      return server.fetch!(request);
    }

    // 상태 확인
    if (request.method === 'GET' && url.pathname === '/') {
      return Response.json(server.status());
    }

    return new Response('Not Found', { status: 404 });
  },
};

server.fetch가 처리하는 JSON-RPC 메서드:

  • initialize → 서버 정보 + capabilities
  • tools/list → 도구 스키마 (annotations 포함)
  • tools/call → 미들웨어 체인을 거쳐 도구 실행
  • resources/list, prompts/list → 등록된 경우
  • notifications/initialized → 204 No Content

TIP

Workers 트랜스포트에서는 server.start()를 호출하지 않습니다. 서버는 즉시 사용 가능 — server.fetch(request)만 호출하면 됩니다.

WARNING

Workers 환경에서는 stdiosse 트랜스포트를 사용할 수 없습니다. workers 트랜스포트만 지원됩니다.

auto (기본)

type을 생략하거나 'auto'로 설정하면 환경을 감지하여 자동 선택합니다:

typescript
defineServer({
  transport: { type: 'auto', port: 3510 },
});

감지 순서:

  1. MCP_TRANSPORT 환경변수가 있으면 해당 값 사용 (stdio, http, sse, workers)
  2. Workers 환경 감지 (globalThis.caches 존재, process.stdin 없음) → workers
  3. stdin이 TTY가 아니면 → stdio (MCP 클라이언트가 spawn한 경우)
  4. stdin이 TTY이면 → http (개발자가 직접 실행한 경우)
bash
# 환경변수로 강제 지정
MCP_TRANSPORT=sse node dist/index.js

# 파이프 → stdio 자동 감지
echo '{}' | node dist/index.js

# 터미널 직접 실행 → http 자동 감지
node dist/index.js

TransportConfig

typescript
interface TransportConfig {
  type?: 'stdio' | 'sse' | 'http' | 'workers' | 'auto';  // 기본: 'auto'
  port?: number;                               // HTTP/SSE 포트
  host?: string;                               // 기본: 'localhost'
  basePath?: string;                           // 기본: '/'
}

포트 결정 순서

포트는 다음 순서로 결정됩니다:

  1. transport.port (명시적 지정)
  2. dev.port (개발 모드 설정)
  3. 3100 (하드코딩 기본값)
typescript
// transport.port 우선
defineServer({ transport: { type: 'sse', port: 3510 } });  // → 3510

// transport.port 없으면 dev.port
defineServer({ transport: { type: 'sse' }, dev: { port: 4000 } });  // → 4000

// 둘 다 없으면 3100
defineServer({ transport: { type: 'sse' } });  // → 3100

선택 가이드

트랜스포트용도클라이언트
stdio로컬 도구, Claude Desktop 직접 연결Claude Desktop, mcp-cli
sse원격 서버, 기존 MCP 인프라, mcp-proxy 호환Cursor, VS Code, mcp-proxy
http새 배포, Streamable HTTP 스펙, 리버스 프록시 뒤최신 MCP 클라이언트
workersCloudflare Workers 엣지 배포, 서버리스PlayMCP, 원격 URL 기반 MCP 클라이언트

TIP

리버스 프록시(Nginx, Cloudflare) 뒤에 배포할 때는 http 트랜스포트를 사용하세요. SSE는 장기 연결(proxy_read_timeout 86400)을 위한 별도 프록시 설정이 필요합니다.

INFO

stdio 트랜스포트에서는 모든 console.log 출력이 MCP 프로토콜 스트림에 섞일 수 있습니다. air의 내장 로거는 이를 자동으로 stderr로 리다이렉트합니다.

Released under the Apache-2.0 License.