@airmcp-dev/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/LICENSE +17 -0
  2. package/dist/commands/add.d.ts +3 -0
  3. package/dist/commands/add.d.ts.map +1 -0
  4. package/dist/commands/add.js +192 -0
  5. package/dist/commands/add.js.map +1 -0
  6. package/dist/commands/check.d.ts +3 -0
  7. package/dist/commands/check.d.ts.map +1 -0
  8. package/dist/commands/check.js +218 -0
  9. package/dist/commands/check.js.map +1 -0
  10. package/dist/commands/connect.d.ts +3 -0
  11. package/dist/commands/connect.d.ts.map +1 -0
  12. package/dist/commands/connect.js +135 -0
  13. package/dist/commands/connect.js.map +1 -0
  14. package/dist/commands/create.d.ts +3 -0
  15. package/dist/commands/create.d.ts.map +1 -0
  16. package/dist/commands/create.js +150 -0
  17. package/dist/commands/create.js.map +1 -0
  18. package/dist/commands/dev.d.ts +3 -0
  19. package/dist/commands/dev.d.ts.map +1 -0
  20. package/dist/commands/dev.js +184 -0
  21. package/dist/commands/dev.js.map +1 -0
  22. package/dist/commands/disconnect.d.ts +3 -0
  23. package/dist/commands/disconnect.d.ts.map +1 -0
  24. package/dist/commands/disconnect.js +69 -0
  25. package/dist/commands/disconnect.js.map +1 -0
  26. package/dist/commands/index.d.ts +13 -0
  27. package/dist/commands/index.d.ts.map +1 -0
  28. package/dist/commands/index.js +16 -0
  29. package/dist/commands/index.js.map +1 -0
  30. package/dist/commands/inspect.d.ts +3 -0
  31. package/dist/commands/inspect.d.ts.map +1 -0
  32. package/dist/commands/inspect.js +159 -0
  33. package/dist/commands/inspect.js.map +1 -0
  34. package/dist/commands/license.d.ts +3 -0
  35. package/dist/commands/license.d.ts.map +1 -0
  36. package/dist/commands/license.js +113 -0
  37. package/dist/commands/license.js.map +1 -0
  38. package/dist/commands/list.d.ts +3 -0
  39. package/dist/commands/list.d.ts.map +1 -0
  40. package/dist/commands/list.js +101 -0
  41. package/dist/commands/list.js.map +1 -0
  42. package/dist/commands/start.d.ts +3 -0
  43. package/dist/commands/start.d.ts.map +1 -0
  44. package/dist/commands/start.js +130 -0
  45. package/dist/commands/start.js.map +1 -0
  46. package/dist/commands/status.d.ts +3 -0
  47. package/dist/commands/status.d.ts.map +1 -0
  48. package/dist/commands/status.js +83 -0
  49. package/dist/commands/status.js.map +1 -0
  50. package/dist/commands/stop.d.ts +3 -0
  51. package/dist/commands/stop.d.ts.map +1 -0
  52. package/dist/commands/stop.js +56 -0
  53. package/dist/commands/stop.js.map +1 -0
  54. package/dist/index.d.ts +3 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +46 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/templates/agent/.ai/context.md +36 -0
  59. package/dist/templates/agent/.vscode/air.code-snippets +178 -0
  60. package/dist/templates/agent/package.json +17 -0
  61. package/dist/templates/agent/src/index.ts +98 -0
  62. package/dist/templates/agent/tsconfig.json +14 -0
  63. package/dist/templates/agent-ko/.ai/context.md +36 -0
  64. package/dist/templates/agent-ko/.vscode/air.code-snippets +178 -0
  65. package/dist/templates/agent-ko/package.json +17 -0
  66. package/dist/templates/agent-ko/src/index.ts +92 -0
  67. package/dist/templates/agent-ko/tsconfig.json +14 -0
  68. package/dist/templates/api/.ai/context.md +36 -0
  69. package/dist/templates/api/.vscode/air.code-snippets +178 -0
  70. package/dist/templates/api/package.json +17 -0
  71. package/dist/templates/api/src/index.ts +76 -0
  72. package/dist/templates/api/tsconfig.json +14 -0
  73. package/dist/templates/api-ko/.ai/context.md +36 -0
  74. package/dist/templates/api-ko/.vscode/air.code-snippets +178 -0
  75. package/dist/templates/api-ko/package.json +17 -0
  76. package/dist/templates/api-ko/src/index.ts +70 -0
  77. package/dist/templates/api-ko/tsconfig.json +14 -0
  78. package/dist/templates/basic/.ai/context.md +36 -0
  79. package/dist/templates/basic/.vscode/air.code-snippets +178 -0
  80. package/dist/templates/basic/package.json +17 -0
  81. package/dist/templates/basic/src/index.ts +39 -0
  82. package/dist/templates/basic/tsconfig.json +15 -0
  83. package/dist/templates/basic-ko/.ai/context.md +36 -0
  84. package/dist/templates/basic-ko/.vscode/air.code-snippets +178 -0
  85. package/dist/templates/basic-ko/package.json +17 -0
  86. package/dist/templates/basic-ko/src/index.ts +39 -0
  87. package/dist/templates/basic-ko/tsconfig.json +14 -0
  88. package/dist/templates/crud/.ai/context.md +36 -0
  89. package/dist/templates/crud/.vscode/air.code-snippets +178 -0
  90. package/dist/templates/crud/package.json +17 -0
  91. package/dist/templates/crud/src/index.ts +82 -0
  92. package/dist/templates/crud/tsconfig.json +14 -0
  93. package/dist/templates/crud-ko/.ai/context.md +36 -0
  94. package/dist/templates/crud-ko/.vscode/air.code-snippets +178 -0
  95. package/dist/templates/crud-ko/package.json +17 -0
  96. package/dist/templates/crud-ko/src/index.ts +81 -0
  97. package/dist/templates/crud-ko/tsconfig.json +14 -0
  98. package/dist/utils/index.d.ts +7 -0
  99. package/dist/utils/index.d.ts.map +1 -0
  100. package/dist/utils/index.js +8 -0
  101. package/dist/utils/index.js.map +1 -0
  102. package/dist/utils/json-editor.d.ts +45 -0
  103. package/dist/utils/json-editor.d.ts.map +1 -0
  104. package/dist/utils/json-editor.js +122 -0
  105. package/dist/utils/json-editor.js.map +1 -0
  106. package/dist/utils/path-resolver.d.ts +30 -0
  107. package/dist/utils/path-resolver.d.ts.map +1 -0
  108. package/dist/utils/path-resolver.js +121 -0
  109. package/dist/utils/path-resolver.js.map +1 -0
  110. package/dist/utils/printer.d.ts +26 -0
  111. package/dist/utils/printer.d.ts.map +1 -0
  112. package/dist/utils/printer.js +65 -0
  113. package/dist/utils/printer.js.map +1 -0
  114. package/dist/utils/process-manager.d.ts +36 -0
  115. package/dist/utils/process-manager.d.ts.map +1 -0
  116. package/dist/utils/process-manager.js +143 -0
  117. package/dist/utils/process-manager.js.map +1 -0
  118. package/dist/utils/test-console.d.ts +8 -0
  119. package/dist/utils/test-console.d.ts.map +1 -0
  120. package/dist/utils/test-console.js +198 -0
  121. package/dist/utils/test-console.js.map +1 -0
  122. package/package.json +52 -0
@@ -0,0 +1,36 @@
1
+ # air MCP Server -- AI Context
2
+
3
+ This project is an MCP server built with the air framework.
4
+
5
+ ## Stack
6
+ - TypeScript + Node.js
7
+ - @airmcp-dev/core for server definition
8
+ - MCP protocol (JSON-RPC 2.0)
9
+
10
+ ## Key APIs
11
+ - defineServer({ name, tools, resources, prompts, use, shield, meter })
12
+ - defineTool(name, { params, handler })
13
+ - defineResource({ uri, name, handler })
14
+ - definePrompt(name, { args, handler })
15
+
16
+ ## Adding Features
17
+ - Add tool: `air add tool <name> --params "key:type"`
18
+ - Add resource: `air add resource <name>`
19
+ - Add prompt: `air add prompt <name>`
20
+
21
+ ## Plugins (import from @airmcp-dev/core)
22
+ timeoutPlugin, retryPlugin, circuitBreakerPlugin, fallbackPlugin,
23
+ cachePlugin, dedupPlugin, queuePlugin,
24
+ authPlugin, sanitizerPlugin, validatorPlugin,
25
+ corsPlugin, webhookPlugin, transformPlugin, i18nPlugin,
26
+ jsonLoggerPlugin, perUserRateLimitPlugin, dryrunPlugin
27
+
28
+ ## Transport
29
+ - stdio (default): for Claude Desktop direct execution
30
+ - sse: for remote connections (set transport.type and transport.port)
31
+ - http: for Streamable HTTP
32
+
33
+ ## Commands
34
+ - `air dev --console` -- dev mode with test console
35
+ - `air connect claude-desktop` -- register with client
36
+ - `air check` -- project diagnostics
@@ -0,0 +1,178 @@
1
+ {
2
+ // ═══════════════════════════════════════════
3
+ // air — MCP Server Development Snippets
4
+ // ═══════════════════════════════════════════
5
+
6
+ "air: defineServer": {
7
+ "prefix": "airserver",
8
+ "description": "Create a new MCP server with air",
9
+ "body": [
10
+ "import { defineServer, defineTool } from '@air/core';",
11
+ "",
12
+ "export default defineServer({",
13
+ " name: '${1:my-server}',",
14
+ " version: '${2:0.1.0}',",
15
+ " description: '${3:MCP server description}',",
16
+ "",
17
+ " shield: {",
18
+ " enabled: ${4|true,false|},",
19
+ " threatDetection: true,",
20
+ " },",
21
+ "",
22
+ " meter: {",
23
+ " enabled: true,",
24
+ " classify: true,",
25
+ " trackCalls: true,",
26
+ " },",
27
+ "",
28
+ " tools: [",
29
+ " $0",
30
+ " ],",
31
+ "});"
32
+ ]
33
+ },
34
+
35
+ "air: defineTool": {
36
+ "prefix": "airtool",
37
+ "description": "Define a new MCP tool",
38
+ "body": [
39
+ "defineTool('${1:tool_name}', {",
40
+ " description: '${2:Tool description}',",
41
+ " params: {",
42
+ " ${3:param}: { type: '${4|string,number,boolean,object|}', description: '${5:param description}' },",
43
+ " },",
44
+ " handler: async ({ ${3:param} }) => {",
45
+ " $0",
46
+ " return '${6:result}';",
47
+ " },",
48
+ "}),"
49
+ ]
50
+ },
51
+
52
+ "air: defineTool (no params)": {
53
+ "prefix": "airtool0",
54
+ "description": "Define a tool with no parameters",
55
+ "body": [
56
+ "defineTool('${1:tool_name}', {",
57
+ " description: '${2:Tool description}',",
58
+ " params: {},",
59
+ " handler: async () => {",
60
+ " $0",
61
+ " return '${3:result}';",
62
+ " },",
63
+ "}),"
64
+ ]
65
+ },
66
+
67
+ "air: defineTool (multi params)": {
68
+ "prefix": "airtoolm",
69
+ "description": "Define a tool with multiple parameters",
70
+ "body": [
71
+ "defineTool('${1:tool_name}', {",
72
+ " description: '${2:Tool description}',",
73
+ " params: {",
74
+ " ${3:param1}: { type: 'string', description: '${4:first param}' },",
75
+ " ${5:param2}: { type: 'string', description: '${6:second param}' },",
76
+ " },",
77
+ " handler: async ({ ${3:param1}, ${5:param2} }) => {",
78
+ " $0",
79
+ " return '${7:result}';",
80
+ " },",
81
+ "}),"
82
+ ]
83
+ },
84
+
85
+ "air: defineResource": {
86
+ "prefix": "airresource",
87
+ "description": "Define an MCP resource",
88
+ "body": [
89
+ "defineResource({",
90
+ " name: '${1:resource_name}',",
91
+ " uri: '${2:resource://path}',",
92
+ " description: '${3:Resource description}',",
93
+ " handler: async (uri, ctx) => {",
94
+ " $0",
95
+ " return '${4:content}';",
96
+ " },",
97
+ "}),"
98
+ ]
99
+ },
100
+
101
+ "air: definePrompt": {
102
+ "prefix": "airprompt",
103
+ "description": "Define an MCP prompt template",
104
+ "body": [
105
+ "definePrompt({",
106
+ " name: '${1:prompt_name}',",
107
+ " description: '${2:Prompt description}',",
108
+ " args: [",
109
+ " { name: '${3:arg}', description: '${4:arg description}' },",
110
+ " ],",
111
+ " handler: async ({ ${3:arg} }) => [",
112
+ " { role: 'user', content: `${5:prompt text \\${${3:arg}\\}}` },",
113
+ " ],",
114
+ "}),"
115
+ ]
116
+ },
117
+
118
+ "air: shield config": {
119
+ "prefix": "airshield",
120
+ "description": "Add shield (security) configuration",
121
+ "body": [
122
+ "shield: {",
123
+ " enabled: true,",
124
+ " policies: [",
125
+ " { name: '${1:policy_name}', target: '${2:*}', action: '${3|allow,deny|}', priority: ${4:10} },",
126
+ " ],",
127
+ " threatDetection: true,",
128
+ " rateLimit: {",
129
+ " maxCalls: ${5:100},",
130
+ " windowMs: ${6:60000},",
131
+ " },",
132
+ " audit: true,",
133
+ "},"
134
+ ]
135
+ },
136
+
137
+ "air: meter config": {
138
+ "prefix": "airmeter",
139
+ "description": "Add meter (metrics) configuration",
140
+ "body": [
141
+ "meter: {",
142
+ " enabled: true,",
143
+ " classify: true,",
144
+ " trackCalls: true,",
145
+ "},"
146
+ ]
147
+ },
148
+
149
+ "air: import core": {
150
+ "prefix": "airimport",
151
+ "description": "Import air/core essentials",
152
+ "body": [
153
+ "import { defineServer, defineTool${1:, getAuditLog, getMetricsSnapshot} } from '@air/core';"
154
+ ]
155
+ },
156
+
157
+ "air: import all": {
158
+ "prefix": "airimportall",
159
+ "description": "Import from all air packages",
160
+ "body": [
161
+ "import { defineServer, defineTool, getAuditLog, getMetricsSnapshot } from '@air/core';",
162
+ "import { AirLogger, PrettyFormatter, ConsoleTransport } from '@air/logger';",
163
+ "import { PolicyEngine, ThreatDetector, RateLimiter } from '@air/shield';",
164
+ "import { LayerClassifier, CallTracker } from '@air/meter';"
165
+ ]
166
+ },
167
+
168
+ "air: handler async": {
169
+ "prefix": "airhandler",
170
+ "description": "Async handler function for a tool",
171
+ "body": [
172
+ "handler: async ({ ${1:params} }) => {",
173
+ " $0",
174
+ " return '${2:result}';",
175
+ "},"
176
+ ]
177
+ }
178
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "my-api-server",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "air dev",
8
+ "start": "air start",
9
+ "build": "tsc"
10
+ },
11
+ "dependencies": {
12
+ "@airmcp-dev/core": "^0.1.0"
13
+ },
14
+ "devDependencies": {
15
+ "typescript": "^5.5.0"
16
+ }
17
+ }
@@ -0,0 +1,76 @@
1
+ // Copyright 2026 CodePedia Labs. Licensed under Apache-2.0.
2
+ // my-api-server — src/index.ts
3
+ //
4
+ // 외부 API 래핑 도구 서버 템플릿.
5
+ // fetch로 외부 API를 호출하고 결과를 MCP 도구로 노출한다.
6
+ // BASE_URL과 API_KEY를 환경변수로 설정.
7
+
8
+ import { defineServer, defineTool } from '@airmcp-dev/core';
9
+
10
+ const BASE_URL = process.env.API_BASE_URL || 'https://jsonplaceholder.typicode.com';
11
+ const API_KEY = process.env.API_KEY || '';
12
+
13
+ /** 공통 fetch 헬퍼 */
14
+ async function apiFetch(path: string, options?: RequestInit): Promise<any> {
15
+ const headers: Record<string, string> = {
16
+ 'Content-Type': 'application/json',
17
+ };
18
+ if (API_KEY) headers['Authorization'] = `Bearer ${API_KEY}`;
19
+
20
+ const res = await fetch(`${BASE_URL}${path}`, { ...options, headers });
21
+ if (!res.ok) {
22
+ throw new Error(`API error: ${res.status} ${res.statusText}`);
23
+ }
24
+ return res.json();
25
+ }
26
+
27
+ const server = defineServer({
28
+ name: 'my-api-server',
29
+ version: '0.1.0',
30
+
31
+ // transport: { type: 'sse', port: 3510 },
32
+ description: 'External API wrapper as MCP tools',
33
+
34
+ tools: [
35
+ defineTool('fetch', {
36
+ description: 'Fetch data from the API',
37
+ params: {
38
+ path: { type: 'string', description: 'API endpoint path (e.g. /users, /posts/1)' },
39
+ },
40
+ handler: async ({ path }) => {
41
+ const data = await apiFetch(path);
42
+ return data;
43
+ },
44
+ }),
45
+
46
+ defineTool('post', {
47
+ description: 'Create data via API',
48
+ params: {
49
+ path: { type: 'string', description: 'API endpoint path' },
50
+ body: { type: 'string', description: 'JSON string of request body' },
51
+ },
52
+ handler: async ({ path, body }) => {
53
+ const data = await apiFetch(path, {
54
+ method: 'POST',
55
+ body,
56
+ });
57
+ return data;
58
+ },
59
+ }),
60
+
61
+ defineTool('search', {
62
+ description: 'Search the API with query parameters',
63
+ params: {
64
+ path: { type: 'string', description: 'API endpoint path' },
65
+ query: { type: 'string', description: 'Query string (e.g. "q=hello&limit=10")' },
66
+ },
67
+ handler: async ({ path, query }) => {
68
+ const separator = path.includes('?') ? '&' : '?';
69
+ const data = await apiFetch(`${path}${separator}${query}`);
70
+ return data;
71
+ },
72
+ }),
73
+ ],
74
+ });
75
+
76
+ server.start();
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "outDir": "dist",
7
+ "rootDir": "src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "resolveJsonModule": true
12
+ },
13
+ "include": ["src"]
14
+ }
@@ -0,0 +1,36 @@
1
+ # air MCP Server -- AI Context
2
+
3
+ This project is an MCP server built with the air framework.
4
+
5
+ ## Stack
6
+ - TypeScript + Node.js
7
+ - @airmcp-dev/core for server definition
8
+ - MCP protocol (JSON-RPC 2.0)
9
+
10
+ ## Key APIs
11
+ - defineServer({ name, tools, resources, prompts, use, shield, meter })
12
+ - defineTool(name, { params, handler })
13
+ - defineResource({ uri, name, handler })
14
+ - definePrompt(name, { args, handler })
15
+
16
+ ## Adding Features
17
+ - Add tool: `air add tool <name> --params "key:type"`
18
+ - Add resource: `air add resource <name>`
19
+ - Add prompt: `air add prompt <name>`
20
+
21
+ ## Plugins (import from @airmcp-dev/core)
22
+ timeoutPlugin, retryPlugin, circuitBreakerPlugin, fallbackPlugin,
23
+ cachePlugin, dedupPlugin, queuePlugin,
24
+ authPlugin, sanitizerPlugin, validatorPlugin,
25
+ corsPlugin, webhookPlugin, transformPlugin, i18nPlugin,
26
+ jsonLoggerPlugin, perUserRateLimitPlugin, dryrunPlugin
27
+
28
+ ## Transport
29
+ - stdio (default): for Claude Desktop direct execution
30
+ - sse: for remote connections (set transport.type and transport.port)
31
+ - http: for Streamable HTTP
32
+
33
+ ## Commands
34
+ - `air dev --console` -- dev mode with test console
35
+ - `air connect claude-desktop` -- register with client
36
+ - `air check` -- project diagnostics
@@ -0,0 +1,178 @@
1
+ {
2
+ // ═══════════════════════════════════════════
3
+ // air — MCP Server Development Snippets
4
+ // ═══════════════════════════════════════════
5
+
6
+ "air: defineServer": {
7
+ "prefix": "airserver",
8
+ "description": "Create a new MCP server with air",
9
+ "body": [
10
+ "import { defineServer, defineTool } from '@air/core';",
11
+ "",
12
+ "export default defineServer({",
13
+ " name: '${1:my-server}',",
14
+ " version: '${2:0.1.0}',",
15
+ " description: '${3:MCP server description}',",
16
+ "",
17
+ " shield: {",
18
+ " enabled: ${4|true,false|},",
19
+ " threatDetection: true,",
20
+ " },",
21
+ "",
22
+ " meter: {",
23
+ " enabled: true,",
24
+ " classify: true,",
25
+ " trackCalls: true,",
26
+ " },",
27
+ "",
28
+ " tools: [",
29
+ " $0",
30
+ " ],",
31
+ "});"
32
+ ]
33
+ },
34
+
35
+ "air: defineTool": {
36
+ "prefix": "airtool",
37
+ "description": "Define a new MCP tool",
38
+ "body": [
39
+ "defineTool('${1:tool_name}', {",
40
+ " description: '${2:Tool description}',",
41
+ " params: {",
42
+ " ${3:param}: { type: '${4|string,number,boolean,object|}', description: '${5:param description}' },",
43
+ " },",
44
+ " handler: async ({ ${3:param} }) => {",
45
+ " $0",
46
+ " return '${6:result}';",
47
+ " },",
48
+ "}),"
49
+ ]
50
+ },
51
+
52
+ "air: defineTool (no params)": {
53
+ "prefix": "airtool0",
54
+ "description": "Define a tool with no parameters",
55
+ "body": [
56
+ "defineTool('${1:tool_name}', {",
57
+ " description: '${2:Tool description}',",
58
+ " params: {},",
59
+ " handler: async () => {",
60
+ " $0",
61
+ " return '${3:result}';",
62
+ " },",
63
+ "}),"
64
+ ]
65
+ },
66
+
67
+ "air: defineTool (multi params)": {
68
+ "prefix": "airtoolm",
69
+ "description": "Define a tool with multiple parameters",
70
+ "body": [
71
+ "defineTool('${1:tool_name}', {",
72
+ " description: '${2:Tool description}',",
73
+ " params: {",
74
+ " ${3:param1}: { type: 'string', description: '${4:first param}' },",
75
+ " ${5:param2}: { type: 'string', description: '${6:second param}' },",
76
+ " },",
77
+ " handler: async ({ ${3:param1}, ${5:param2} }) => {",
78
+ " $0",
79
+ " return '${7:result}';",
80
+ " },",
81
+ "}),"
82
+ ]
83
+ },
84
+
85
+ "air: defineResource": {
86
+ "prefix": "airresource",
87
+ "description": "Define an MCP resource",
88
+ "body": [
89
+ "defineResource({",
90
+ " name: '${1:resource_name}',",
91
+ " uri: '${2:resource://path}',",
92
+ " description: '${3:Resource description}',",
93
+ " handler: async (uri, ctx) => {",
94
+ " $0",
95
+ " return '${4:content}';",
96
+ " },",
97
+ "}),"
98
+ ]
99
+ },
100
+
101
+ "air: definePrompt": {
102
+ "prefix": "airprompt",
103
+ "description": "Define an MCP prompt template",
104
+ "body": [
105
+ "definePrompt({",
106
+ " name: '${1:prompt_name}',",
107
+ " description: '${2:Prompt description}',",
108
+ " args: [",
109
+ " { name: '${3:arg}', description: '${4:arg description}' },",
110
+ " ],",
111
+ " handler: async ({ ${3:arg} }) => [",
112
+ " { role: 'user', content: `${5:prompt text \\${${3:arg}\\}}` },",
113
+ " ],",
114
+ "}),"
115
+ ]
116
+ },
117
+
118
+ "air: shield config": {
119
+ "prefix": "airshield",
120
+ "description": "Add shield (security) configuration",
121
+ "body": [
122
+ "shield: {",
123
+ " enabled: true,",
124
+ " policies: [",
125
+ " { name: '${1:policy_name}', target: '${2:*}', action: '${3|allow,deny|}', priority: ${4:10} },",
126
+ " ],",
127
+ " threatDetection: true,",
128
+ " rateLimit: {",
129
+ " maxCalls: ${5:100},",
130
+ " windowMs: ${6:60000},",
131
+ " },",
132
+ " audit: true,",
133
+ "},"
134
+ ]
135
+ },
136
+
137
+ "air: meter config": {
138
+ "prefix": "airmeter",
139
+ "description": "Add meter (metrics) configuration",
140
+ "body": [
141
+ "meter: {",
142
+ " enabled: true,",
143
+ " classify: true,",
144
+ " trackCalls: true,",
145
+ "},"
146
+ ]
147
+ },
148
+
149
+ "air: import core": {
150
+ "prefix": "airimport",
151
+ "description": "Import air/core essentials",
152
+ "body": [
153
+ "import { defineServer, defineTool${1:, getAuditLog, getMetricsSnapshot} } from '@air/core';"
154
+ ]
155
+ },
156
+
157
+ "air: import all": {
158
+ "prefix": "airimportall",
159
+ "description": "Import from all air packages",
160
+ "body": [
161
+ "import { defineServer, defineTool, getAuditLog, getMetricsSnapshot } from '@air/core';",
162
+ "import { AirLogger, PrettyFormatter, ConsoleTransport } from '@air/logger';",
163
+ "import { PolicyEngine, ThreatDetector, RateLimiter } from '@air/shield';",
164
+ "import { LayerClassifier, CallTracker } from '@air/meter';"
165
+ ]
166
+ },
167
+
168
+ "air: handler async": {
169
+ "prefix": "airhandler",
170
+ "description": "Async handler function for a tool",
171
+ "body": [
172
+ "handler: async ({ ${1:params} }) => {",
173
+ " $0",
174
+ " return '${2:result}';",
175
+ "},"
176
+ ]
177
+ }
178
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "my-api-server",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "air dev",
8
+ "start": "air start",
9
+ "build": "tsc"
10
+ },
11
+ "dependencies": {
12
+ "@airmcp-dev/core": "^0.1.0"
13
+ },
14
+ "devDependencies": {
15
+ "typescript": "^5.5.0"
16
+ }
17
+ }
@@ -0,0 +1,70 @@
1
+ // Copyright 2026 CodePedia Labs. Licensed under Apache-2.0.
2
+ // my-api-server — src/index.ts
3
+ //
4
+ // 외부 API 래핑 도구 서버 템플릿.
5
+ // fetch로 외부 API를 호출하고 결과를 MCP 도구로 제공합니다.
6
+ // BASE_URL과 API_KEY를 환경변수로 설정하세요.
7
+
8
+ import { defineServer, defineTool } from '@airmcp-dev/core';
9
+
10
+ const BASE_URL = process.env.API_BASE_URL || 'https://jsonplaceholder.typicode.com';
11
+ const API_KEY = process.env.API_KEY || '';
12
+
13
+ /** 공통 fetch 헬퍼 */
14
+ async function apiFetch(path: string, options?: RequestInit): Promise<any> {
15
+ const headers: Record<string, string> = {
16
+ 'Content-Type': 'application/json',
17
+ };
18
+ if (API_KEY) headers['Authorization'] = `Bearer ${API_KEY}`;
19
+
20
+ const res = await fetch(`${BASE_URL}${path}`, { ...options, headers });
21
+ if (!res.ok) {
22
+ throw new Error(`API 오류: ${res.status} ${res.statusText}`);
23
+ }
24
+ return res.json();
25
+ }
26
+
27
+ const server = defineServer({
28
+ name: 'my-api-server',
29
+ version: '0.1.0',
30
+
31
+ // transport: { type: 'sse', port: 3510 },
32
+ description: '외부 API를 MCP 도구로 제공하는 서버',
33
+
34
+ tools: [
35
+ defineTool('fetch', {
36
+ description: 'API에서 데이터를 가져옵니다',
37
+ params: {
38
+ path: { type: 'string', description: 'API 경로 (예: /users, /posts/1)' },
39
+ },
40
+ handler: async ({ path }) => {
41
+ return await apiFetch(path);
42
+ },
43
+ }),
44
+
45
+ defineTool('post', {
46
+ description: 'API에 데이터를 생성합니다',
47
+ params: {
48
+ path: { type: 'string', description: 'API 경로' },
49
+ body: { type: 'string', description: '요청 본문 (JSON 문자열)' },
50
+ },
51
+ handler: async ({ path, body }) => {
52
+ return await apiFetch(path, { method: 'POST', body });
53
+ },
54
+ }),
55
+
56
+ defineTool('search', {
57
+ description: 'API를 검색합니다',
58
+ params: {
59
+ path: { type: 'string', description: 'API 경로' },
60
+ query: { type: 'string', description: '쿼리 문자열 (예: "q=hello&limit=10")' },
61
+ },
62
+ handler: async ({ path, query }) => {
63
+ const separator = path.includes('?') ? '&' : '?';
64
+ return await apiFetch(`${path}${separator}${query}`);
65
+ },
66
+ }),
67
+ ],
68
+ });
69
+
70
+ server.start();
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "outDir": "dist",
7
+ "rootDir": "src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "resolveJsonModule": true
12
+ },
13
+ "include": ["src"]
14
+ }
@@ -0,0 +1,36 @@
1
+ # air MCP Server -- AI Context
2
+
3
+ This project is an MCP server built with the air framework.
4
+
5
+ ## Stack
6
+ - TypeScript + Node.js
7
+ - @airmcp-dev/core for server definition
8
+ - MCP protocol (JSON-RPC 2.0)
9
+
10
+ ## Key APIs
11
+ - defineServer({ name, tools, resources, prompts, use, shield, meter })
12
+ - defineTool(name, { params, handler })
13
+ - defineResource({ uri, name, handler })
14
+ - definePrompt(name, { args, handler })
15
+
16
+ ## Adding Features
17
+ - Add tool: `air add tool <name> --params "key:type"`
18
+ - Add resource: `air add resource <name>`
19
+ - Add prompt: `air add prompt <name>`
20
+
21
+ ## Plugins (import from @airmcp-dev/core)
22
+ timeoutPlugin, retryPlugin, circuitBreakerPlugin, fallbackPlugin,
23
+ cachePlugin, dedupPlugin, queuePlugin,
24
+ authPlugin, sanitizerPlugin, validatorPlugin,
25
+ corsPlugin, webhookPlugin, transformPlugin, i18nPlugin,
26
+ jsonLoggerPlugin, perUserRateLimitPlugin, dryrunPlugin
27
+
28
+ ## Transport
29
+ - stdio (default): for Claude Desktop direct execution
30
+ - sse: for remote connections (set transport.type and transport.port)
31
+ - http: for Streamable HTTP
32
+
33
+ ## Commands
34
+ - `air dev --console` -- dev mode with test console
35
+ - `air connect claude-desktop` -- register with client
36
+ - `air check` -- project diagnostics