Skip to content

템플릿 ​

air create 명령어는 템플릿에서 프로젝트를 생성합니다. 각 템플릿은 바로 실행 가능한 MCP 서버입니다.

사용 가능한 템플릿 ​

템플릿설명
basic도구 하나의 최소 서버. 학습용.
api외부 API 래핑. 인증과 재시도 플러그인 포함.
crud파일 기반 스토리지 CRUD 도구 (create, read, update, delete).
agentthink-execute-remember 패턴의 에이전트 서버. L6/L7 계층 힌트.

사용법 ​

bash
air create my-server                       # basic (기본)
air create my-server --template api        # 특정 템플릿
air create my-server --template basic --lang ko  # 한국어 주석

프로젝트 구조 ​

모든 템플릿은 동일한 레이아웃을 생성합니다:

my-server/
├── src/
│   └── index.ts          # 서버 정의
├── package.json          # @airmcp-dev/core 의존성
└── tsconfig.json         # TypeScript 설정

basic ​

도구 하나, 플러그인 없음. 가장 간단한 출발점.

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

const server = defineServer({
  name: 'my-mcp-server',
  version: '0.1.0',
  tools: [
    defineTool('hello', {
      description: 'Say hello',
      params: { name: { type: 'string', description: 'Your name' } },
      handler: async ({ name }) => `Hello, ${name}!`,
    }),
  ],
});

server.start();

api ​

외부 API를 래핑하는 도구 서버. fetch 헬퍼로 외부 API를 호출하고 결과를 MCP 도구로 노출합니다.

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

const BASE_URL = process.env.API_BASE_URL || 'https://jsonplaceholder.typicode.com';
const API_KEY = process.env.API_KEY || '';

async function apiFetch(path: string, options?: RequestInit): Promise<any> {
  const headers: Record<string, string> = { 'Content-Type': 'application/json' };
  if (API_KEY) headers['Authorization'] = `Bearer ${API_KEY}`;
  const res = await fetch(`${BASE_URL}${path}`, { ...options, headers });
  if (!res.ok) throw new Error(`API error: ${res.status} ${res.statusText}`);
  return res.json();
}

const server = defineServer({
  name: 'my-api-server',
  version: '0.1.0',
  tools: [
    defineTool('fetch', {
      description: 'Fetch data from the API',
      params: { path: { type: 'string', description: 'API endpoint (e.g. /users)' } },
      handler: async ({ path }) => apiFetch(path),
    }),
    defineTool('post', {
      description: 'Create data via API',
      params: {
        path: { type: 'string', description: 'API endpoint' },
        body: { type: 'string', description: 'JSON string of request body' },
      },
      handler: async ({ path, body }) => apiFetch(path, { method: 'POST', body }),
    }),
    defineTool('search', {
      description: 'Search with query parameters',
      params: {
        path: { type: 'string', description: 'API endpoint' },
        query: { type: 'string', description: 'Query string (e.g. "q=hello&limit=10")' },
      },
      handler: async ({ path, query }) => {
        const sep = path.includes('?') ? '&' : '?';
        return apiFetch(`${path}${sep}${query}`);
      },
    }),
  ],
});

server.start();

환경변수 설정:

  • API_BASE_URL — 외부 API의 기본 URL
  • API_KEY — Bearer 토큰 (선택)

crud ​

4개 CRUD 도구와 인메모리 스토리지. 실제로는 DB로 교체하여 사용합니다.

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

const store = createStorage({ adapter: 'memory' });

const server = defineServer({
  name: 'my-crud-server',
  version: '0.1.0',
  tools: [
    defineTool('create', {
      description: 'Create a new record',
      params: {
        collection: { type: 'string', description: 'Collection name' },
        data: { type: 'string', description: 'JSON string of record data' },
      },
      handler: async ({ collection, data }) => {
        const record = JSON.parse(data);
        const id = `${collection}_${Date.now()}`;
        await store.set(id, { ...record, _id: id, _collection: collection });
        return { id, message: `Created in ${collection}` };
      },
    }),
    defineTool('read', { /* ... */ }),
    defineTool('update', { /* ... */ }),
    defineTool('delete', { /* ... */ }),
  ],
});

server.start();

agent ​

think-execute-remember 패턴의 AI 에이전트 서버. LLM 연동 없이 구조만 제공 — 사용자가 LLM 호출을 추가합니다.

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

const memory = createStorage({ adapter: 'memory' });

const server = defineServer({
  name: 'my-agent-server',
  version: '0.1.0',
  tools: [
    defineTool('think', {
      description: 'Analyze a problem and produce a plan',
      params: {
        problem: { type: 'string', description: 'Problem statement' },
        context: { type: 'string', description: 'Additional context', optional: true },
      },
      handler: async ({ problem, context }) => {
        // TODO: LLM 호출 연결
        const plan = {
          problem,
          steps: ['Understand', 'Gather data', 'Execute', 'Verify'],
          reasoning: 'Replace with LLM-generated reasoning',
        };
        await memory.set(`thought_${Date.now()}`, { ...plan, timestamp: new Date().toISOString() });
        return plan;
      },
    }),
    defineTool('execute', {
      description: 'Execute a step from the plan',
      params: {
        step: { type: 'string', description: 'Step to execute' },
        input: { type: 'string', description: 'Input data', optional: true },
      },
      handler: async ({ step, input }) => {
        // TODO: 실제 실행 로직 (파일, API, DB 등)
        const result = { step, status: 'completed', output: `Executed: ${step}` };
        await memory.set(`exec_${Date.now()}`, result);
        return result;
      },
    }),
    defineTool('remember', {
      description: 'Store or recall from agent memory',
      params: {
        action: { type: 'string', description: '"store" or "recall"' },
        key: { type: 'string', description: 'Memory key' },
        value: { type: 'string', description: 'Value to store', optional: true },
      },
      handler: async ({ action, key, value }) => {
        if (action === 'store' && value) {
          await memory.set(key, { value, timestamp: new Date().toISOString() });
          return { action: 'stored', key };
        }
        if (action === 'recall') {
          const data = await memory.get(key);
          return data ? { action: 'recall', key, found: true, data } : { action: 'recall', key, found: false };
        }
        return { error: 'Invalid action. Use "store" or "recall".' };
      },
    }),
  ],
});

server.start();

언어 변형 ​

모든 템플릿에 한국어 변형이 있습니다 (예: basic-ko). --lang ko로 선택하면 주석과 설명이 한국어로 제공됩니다.

Released under the Apache-2.0 License.