@koseha/api-mcp 0.0.0 → 0.0.2

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.
package/dist/index.js CHANGED
@@ -1,23 +1,20 @@
1
- import { McpServer, ResourceTemplate, } from "@modelcontextprotocol/sdk/server/mcp.js";
1
+ /**
2
+ * MCP 서버 엔트리포인트
3
+ */
2
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
- import { z } from "zod";
4
- const server = new McpServer({
5
- name: "api-mcp",
6
- version: "1.0.0",
5
+ import { createServer } from "./server.js";
6
+ import { registerTools } from "./tools/index.js";
7
+ import { registerResources } from "./resources/index.js";
8
+ async function main() {
9
+ const server = createServer();
10
+ registerTools(server);
11
+ registerResources(server);
12
+ const transport = new StdioServerTransport();
13
+ await server.connect(transport);
14
+ // 👇 이 줄이 핵심
15
+ process.stdin.resume();
16
+ }
17
+ main().catch((err) => {
18
+ process.stderr.write(err.stack + "\n");
19
+ process.exit(1);
7
20
  });
8
- server.registerTool("add", {
9
- title: "Addition Tool",
10
- description: "Add two numbers",
11
- inputSchema: { a: z.number(), b: z.number() },
12
- }, async ({ a, b }) => ({
13
- content: [{ type: "text", text: String(a + b) }],
14
- }));
15
- server.registerResource("greeting", new ResourceTemplate("greeting://{name}", { list: undefined }), {
16
- title: "Greeting Resource",
17
- description: "Dynamic greeting generator",
18
- }, async (uri, { name }) => ({
19
- contents: [{ uri: uri.href, text: `Hello, ${name}!` }],
20
- }));
21
- const transport = new StdioServerTransport();
22
- await server.connect(transport);
23
- console.log("MCP server is running via stdio.");
@@ -0,0 +1,9 @@
1
+ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export function registerGreetingResource(server) {
3
+ server.registerResource("greeting", new ResourceTemplate("greeting://{name}", { list: undefined }), {
4
+ title: "Greeting Resource",
5
+ description: "Dynamic greeting generator",
6
+ }, async (uri, { name }) => ({
7
+ contents: [{ uri: uri.href, text: `Hello, ${name}!` }],
8
+ }));
9
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 모든 Resource 등록
3
+ */
4
+ import { registerGreetingResource } from "./greeting.resource.js";
5
+ export function registerResources(server) {
6
+ registerGreetingResource(server);
7
+ }
package/dist/server.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * MCPServer 생성
3
+ */
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ export function createServer() {
6
+ return new McpServer({
7
+ name: "api-mcp",
8
+ version: "0.0.2",
9
+ });
10
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * openapi.json 파일 읽기 + TTL 캐시
3
+ */
4
+ import { readFile } from "fs/promises";
5
+ import { join, dirname } from "path";
6
+ import { fileURLToPath } from "url";
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
9
+ let cache = null;
10
+ let cachedAt = 0;
11
+ const TTL = 5 * 60 * 1000;
12
+ export async function loadSwagger() {
13
+ if (cache && Date.now() - cachedAt < TTL) {
14
+ return cache;
15
+ }
16
+ const openapiPath = join(__dirname, "../../openapi.json");
17
+ const fileContent = await readFile(openapiPath, "utf-8");
18
+ cache = JSON.parse(fileContent);
19
+ cachedAt = Date.now();
20
+ return cache;
21
+ }
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+ export function registerAddTool(server) {
3
+ server.registerTool("add", {
4
+ title: "Addition Tool",
5
+ description: "Add two numbers",
6
+ inputSchema: { a: z.number(), b: z.number() },
7
+ }, async ({ a, b }) => ({
8
+ content: [{ type: "text", text: String(a + b) }],
9
+ }));
10
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Tool: API 목록 조회
3
+ */
4
+ import { loadSwagger } from "../swagger/swaggerLoader.js";
5
+ export function registerGetApiList(server) {
6
+ server.registerTool("getApiList", {
7
+ title: "API 목록 조회",
8
+ description: "API 목록을 조회합니다.",
9
+ }, async () => {
10
+ const swagger = await loadSwagger();
11
+ // paths → list 가공
12
+ return {
13
+ content: [{ type: "text", text: JSON.stringify(swagger.paths) }],
14
+ };
15
+ });
16
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 모든 Tool 등록
3
+ */
4
+ import { registerAddTool } from "./add.tool.js";
5
+ import { registerGetApiList } from "./getApiList.tool.js";
6
+ export function registerTools(server) {
7
+ registerAddTool(server);
8
+ registerGetApiList(server);
9
+ }
package/openapi.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "openapi": "3.0.3",
3
+ "info": {
4
+ "title": "Swagger Petstore - OpenAPI 3.0",
5
+ "version": "1.0.11"
6
+ },
7
+ "servers": [
8
+ {
9
+ "url": "https://petstore3.swagger.io/api/v3"
10
+ }
11
+ ],
12
+ "tags": [
13
+ {
14
+ "name": "pet",
15
+ "description": "당신의 애완동물에 대한 모든 것"
16
+ }
17
+ ],
18
+ "paths": {
19
+ "/pet/{petId}/uploadImage": {
20
+ "post": {
21
+ "tags": ["pet"],
22
+ "summary": "이미지를 업로드합니다.",
23
+ "operationId": "uploadFile",
24
+ "parameters": [
25
+ {
26
+ "name": "petId",
27
+ "in": "path",
28
+ "description": "업데이트할 애완동물 ID",
29
+ "required": true,
30
+ "schema": {
31
+ "type": "integer",
32
+ "format": "int64"
33
+ }
34
+ },
35
+ {
36
+ "name": "additionalMetadata",
37
+ "in": "query",
38
+ "description": "추가 메타데이터",
39
+ "required": false,
40
+ "schema": {
41
+ "type": "string"
42
+ }
43
+ }
44
+ ],
45
+ "requestBody": {
46
+ "content": {
47
+ "application/octet-stream": {
48
+ "schema": {
49
+ "type": "string",
50
+ "format": "binary"
51
+ }
52
+ }
53
+ }
54
+ },
55
+ "responses": {
56
+ "200": {
57
+ "description": "성공적인 작업"
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koseha/api-mcp",
3
- "version": "0.0.0",
3
+ "version": "0.0.2",
4
4
  "description": "An API MCP based on Swagger docs",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/koseha/api-mcp#readme",