@g1cloud/bluework4-tool 1.0.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.
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # Bluework4 MCP Tool (TypeScript)
2
+
3
+ Bluework4 API와 연동하는 MCP(Model Context Protocol) 서버입니다.
4
+
5
+ ## 기능
6
+
7
+ Bluework4에서 UI 모델 및 Entity 모델 정보를 조회하는 6개의 Tool을 제공합니다.
8
+
9
+ | Tool | 설명 |
10
+ |------|------|
11
+ | `getUiModel` | UI 모델 정보 조회 |
12
+ | `getEntityModel` | Entity 모델 조회 |
13
+ | `getEntityModelText` | 비즈니스 모듈별 Entity 텍스트 조회 |
14
+ | `getUiList` | UI 화면 목록 조회 (페이징) |
15
+ | `getBizModuleList` | 비즈니스 모듈 목록 조회 (페이징) |
16
+ | `getBizModuleEntities` | 모듈별 Entity 목록 조회 |
17
+
18
+ ## 설치
19
+
20
+ ```bash
21
+ npm install
22
+ npm run build
23
+ ```
24
+
25
+ ## 환경 변수
26
+
27
+ | 변수 | 설명 | 필수 |
28
+ |------|------|------|
29
+ | `BLUEWORK4_BASE_URL` | Bluework4 API 서버 URL | Yes |
30
+ | `BLUEWORK4_API_KEY` | API 인증 키 | Yes |
31
+ | `BLUEWORK4_PROJECT_ID` | 프로젝트 ID | Yes |
32
+
33
+ ## 실행
34
+
35
+ ```bash
36
+ # 빌드 후 실행
37
+ node dist/index.js
38
+
39
+ # 개발 모드 (tsx 사용)
40
+ npm run dev
41
+ ```
42
+
43
+ ## MCP 클라이언트 설정
44
+
45
+ ### Claude Desktop
46
+
47
+ `claude_desktop_config.json`:
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "bluework4-tool": {
53
+ "command": "node",
54
+ "args": ["/path/to/bluework4-tool-ts/dist/index.js"],
55
+ "env": {
56
+ "BLUEWORK4_BASE_URL": "https://your-bluework4-server.com",
57
+ "BLUEWORK4_API_KEY": "your-api-key",
58
+ "BLUEWORK4_PROJECT_ID": "your-project-id"
59
+ }
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### Claude Code
66
+
67
+ `.claude/settings.local.json` 또는 `~/.claude/settings.json`:
68
+
69
+ ```json
70
+ {
71
+ "mcpServers": {
72
+ "bluework4-tool": {
73
+ "command": "node",
74
+ "args": ["/path/to/bluework4-tool-ts/dist/index.js"],
75
+ "env": {
76
+ "BLUEWORK4_BASE_URL": "https://your-bluework4-server.com",
77
+ "BLUEWORK4_API_KEY": "your-api-key",
78
+ "BLUEWORK4_PROJECT_ID": "your-project-id"
79
+ }
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ ## 기술 스택
86
+
87
+ - Node.js 20+
88
+ - TypeScript
89
+ - MCP SDK (`@modelcontextprotocol/sdk`)
90
+ - tsup (빌드)
91
+
92
+ ## 라이선스
93
+
94
+ MIT
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+
7
+ // src/config.ts
8
+ function loadConfig() {
9
+ const baseUrl = process.env.BLUEWORK4_BASE_URL;
10
+ const apiKey = process.env.BLUEWORK4_API_KEY;
11
+ const projectId = process.env.BLUEWORK4_PROJECT_ID;
12
+ if (!baseUrl) {
13
+ throw new Error("BLUEWORK4_BASE_URL environment variable is required");
14
+ }
15
+ if (!apiKey) {
16
+ throw new Error("BLUEWORK4_API_KEY environment variable is required");
17
+ }
18
+ if (!projectId) {
19
+ throw new Error("BLUEWORK4_PROJECT_ID environment variable is required");
20
+ }
21
+ return { baseUrl, apiKey, projectId };
22
+ }
23
+
24
+ // src/client.ts
25
+ var Bluework4Client = class {
26
+ baseUrl;
27
+ apiKey;
28
+ constructor(config) {
29
+ this.baseUrl = config.baseUrl.replace(/\/$/, "");
30
+ this.apiKey = config.apiKey;
31
+ }
32
+ async get(path, params) {
33
+ const url = new URL(path, this.baseUrl);
34
+ if (params) {
35
+ Object.entries(params).forEach(([key, value]) => {
36
+ if (value !== void 0 && value !== null && value !== "") {
37
+ url.searchParams.set(key, String(value));
38
+ }
39
+ });
40
+ }
41
+ const response = await fetch(url.toString(), {
42
+ method: "GET",
43
+ headers: {
44
+ Authorization: `Bearer ${this.apiKey}`,
45
+ Accept: "application/json, text/plain, */*"
46
+ }
47
+ });
48
+ if (!response.ok) {
49
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
50
+ }
51
+ return response.text();
52
+ }
53
+ };
54
+
55
+ // src/tools/getUiModel.ts
56
+ import { z } from "zod";
57
+ var getUiModelSchema = z.object({
58
+ uiId: z.string().describe("The UI ID to retrieve")
59
+ });
60
+ async function getUiModel(args, client, config) {
61
+ try {
62
+ const path = `/tool/openapi/${config.projectId}/uiModel/${args.uiId}/text`;
63
+ return await client.get(path);
64
+ } catch (error) {
65
+ const message = error instanceof Error ? error.message : String(error);
66
+ return `Error fetching UI model: ${message}`;
67
+ }
68
+ }
69
+ var getUiModelTool = {
70
+ name: "getUiModel",
71
+ description: "Get UI model information from Bluework4. Returns the UI screen definition in text format.",
72
+ schema: getUiModelSchema,
73
+ handler: getUiModel
74
+ };
75
+
76
+ // src/tools/getEntityModel.ts
77
+ import { z as z2 } from "zod";
78
+ var getEntityModelSchema = z2.object({
79
+ entityName: z2.string().optional().describe(
80
+ "The entity name to retrieve. Optional - if not provided, returns all entities."
81
+ )
82
+ });
83
+ async function getEntityModel(args, client, config) {
84
+ try {
85
+ const path = `/tool/openapi/${config.projectId}/entityModel`;
86
+ const params = {};
87
+ if (args.entityName) {
88
+ params.entity = args.entityName;
89
+ }
90
+ return await client.get(path, params);
91
+ } catch (error) {
92
+ const message = error instanceof Error ? error.message : String(error);
93
+ return `Error fetching Entity model: ${message}`;
94
+ }
95
+ }
96
+ var getEntityModelTool = {
97
+ name: "getEntityModel",
98
+ description: "Get Entity model information from Bluework4. Returns entity definitions. If entityName is not provided, returns all entities.",
99
+ schema: getEntityModelSchema,
100
+ handler: getEntityModel
101
+ };
102
+
103
+ // src/tools/getEntityModelText.ts
104
+ import { z as z3 } from "zod";
105
+ var getEntityModelTextSchema = z3.object({
106
+ id: z3.string().describe("The business module ID or moduleId"),
107
+ entity: z3.string().optional().describe("Entity name filter (comma-separated)"),
108
+ table: z3.string().optional().describe("Table name filter (comma-separated)"),
109
+ packageName: z3.string().optional().describe("Package name filter (comma-separated)")
110
+ });
111
+ async function getEntityModelText(args, client, config) {
112
+ try {
113
+ const path = `/tool/openapi/${config.projectId}/entityModel/${args.id}/text`;
114
+ const params = {
115
+ entity: args.entity,
116
+ table: args.table,
117
+ package: args.packageName
118
+ };
119
+ return await client.get(path, params);
120
+ } catch (error) {
121
+ const message = error instanceof Error ? error.message : String(error);
122
+ return `Error fetching Entity model text: ${message}`;
123
+ }
124
+ }
125
+ var getEntityModelTextTool = {
126
+ name: "getEntityModelText",
127
+ description: "Get Entity model text from Bluework4. Returns entity definitions from a specific business module.",
128
+ schema: getEntityModelTextSchema,
129
+ handler: getEntityModelText
130
+ };
131
+
132
+ // src/tools/getUiList.ts
133
+ import { z as z4 } from "zod";
134
+ var getUiListSchema = z4.object({
135
+ uiId: z4.string().optional().describe("UI ID filter"),
136
+ uiName: z4.string().optional().describe("UI name filter"),
137
+ uiType: z4.string().optional().describe("UI type filter"),
138
+ menu1: z4.string().optional().describe("Menu level 1 filter"),
139
+ menu2: z4.string().optional().describe("Menu level 2 filter"),
140
+ sort: z4.string().optional().describe("Sort (e.g., 'uiId', '-updateDate')"),
141
+ offset: z4.number().optional().describe("Offset (default: 0)"),
142
+ limit: z4.number().optional().describe("Limit (default: 100)")
143
+ });
144
+ async function getUiList(args, client, config) {
145
+ try {
146
+ const path = `/tool/openapi/${config.projectId}/ui`;
147
+ const params = {
148
+ uiId: args.uiId,
149
+ uiName: args.uiName,
150
+ uiType: args.uiType,
151
+ menu1: args.menu1,
152
+ menu2: args.menu2,
153
+ sort: args.sort,
154
+ offset: args.offset,
155
+ limit: args.limit
156
+ };
157
+ return await client.get(path, params);
158
+ } catch (error) {
159
+ const message = error instanceof Error ? error.message : String(error);
160
+ return `Error fetching UI list: ${message}`;
161
+ }
162
+ }
163
+ var getUiListTool = {
164
+ name: "getUiList",
165
+ description: "Get UI screen list from Bluework4. Returns paginated list of UI screens.",
166
+ schema: getUiListSchema,
167
+ handler: getUiList
168
+ };
169
+
170
+ // src/tools/getBizModuleList.ts
171
+ import { z as z5 } from "zod";
172
+ var getBizModuleListSchema = z5.object({
173
+ moduleId: z5.string().optional().describe("Module ID filter"),
174
+ moduleName: z5.string().optional().describe("Module name filter"),
175
+ sort: z5.string().optional().describe("Sort (e.g., 'moduleId', '-updateDate')"),
176
+ offset: z5.number().optional().describe("Offset (default: 0)"),
177
+ limit: z5.number().optional().describe("Limit (default: 100)")
178
+ });
179
+ async function getBizModuleList(args, client, config) {
180
+ try {
181
+ const path = `/tool/openapi/${config.projectId}/bizModule`;
182
+ const params = {
183
+ moduleId: args.moduleId,
184
+ moduleName: args.moduleName,
185
+ sort: args.sort,
186
+ offset: args.offset,
187
+ limit: args.limit
188
+ };
189
+ return await client.get(path, params);
190
+ } catch (error) {
191
+ const message = error instanceof Error ? error.message : String(error);
192
+ return `Error fetching business module list: ${message}`;
193
+ }
194
+ }
195
+ var getBizModuleListTool = {
196
+ name: "getBizModuleList",
197
+ description: "Get business module list from Bluework4. Returns paginated list.",
198
+ schema: getBizModuleListSchema,
199
+ handler: getBizModuleList
200
+ };
201
+
202
+ // src/tools/getBizModuleEntities.ts
203
+ import { z as z6 } from "zod";
204
+ var getBizModuleEntitiesSchema = z6.object({
205
+ id: z6.string().describe("Business module ID or moduleId"),
206
+ entityName: z6.string().optional().describe("Entity name filter"),
207
+ logicalName: z6.string().optional().describe("Logical name filter"),
208
+ physicalName: z6.string().optional().describe("Physical name filter")
209
+ });
210
+ async function getBizModuleEntities(args, client, config) {
211
+ try {
212
+ const path = `/tool/openapi/${config.projectId}/bizModule/${args.id}/entities`;
213
+ const params = {
214
+ entityName: args.entityName,
215
+ logicalName: args.logicalName,
216
+ physicalName: args.physicalName
217
+ };
218
+ return await client.get(path, params);
219
+ } catch (error) {
220
+ const message = error instanceof Error ? error.message : String(error);
221
+ return `Error fetching business module entities: ${message}`;
222
+ }
223
+ }
224
+ var getBizModuleEntitiesTool = {
225
+ name: "getBizModuleEntities",
226
+ description: "Get entity list for a specific business module from Bluework4.",
227
+ schema: getBizModuleEntitiesSchema,
228
+ handler: getBizModuleEntities
229
+ };
230
+
231
+ // src/tools/index.ts
232
+ function registerTools(server, client, config) {
233
+ server.tool(
234
+ getUiModelTool.name,
235
+ getUiModelTool.description,
236
+ getUiModelSchema.shape,
237
+ async (args) => {
238
+ const result = await getUiModel(args, client, config);
239
+ return { content: [{ type: "text", text: result }] };
240
+ }
241
+ );
242
+ server.tool(
243
+ getEntityModelTool.name,
244
+ getEntityModelTool.description,
245
+ getEntityModelSchema.shape,
246
+ async (args) => {
247
+ const result = await getEntityModel(args, client, config);
248
+ return { content: [{ type: "text", text: result }] };
249
+ }
250
+ );
251
+ server.tool(
252
+ getEntityModelTextTool.name,
253
+ getEntityModelTextTool.description,
254
+ getEntityModelTextSchema.shape,
255
+ async (args) => {
256
+ const result = await getEntityModelText(args, client, config);
257
+ return { content: [{ type: "text", text: result }] };
258
+ }
259
+ );
260
+ server.tool(
261
+ getUiListTool.name,
262
+ getUiListTool.description,
263
+ getUiListSchema.shape,
264
+ async (args) => {
265
+ const result = await getUiList(args, client, config);
266
+ return { content: [{ type: "text", text: result }] };
267
+ }
268
+ );
269
+ server.tool(
270
+ getBizModuleListTool.name,
271
+ getBizModuleListTool.description,
272
+ getBizModuleListSchema.shape,
273
+ async (args) => {
274
+ const result = await getBizModuleList(args, client, config);
275
+ return { content: [{ type: "text", text: result }] };
276
+ }
277
+ );
278
+ server.tool(
279
+ getBizModuleEntitiesTool.name,
280
+ getBizModuleEntitiesTool.description,
281
+ getBizModuleEntitiesSchema.shape,
282
+ async (args) => {
283
+ const result = await getBizModuleEntities(args, client, config);
284
+ return { content: [{ type: "text", text: result }] };
285
+ }
286
+ );
287
+ }
288
+
289
+ // src/index.ts
290
+ var SERVER_NAME = "bluework4-mcp-server";
291
+ var SERVER_VERSION = "0.0.1";
292
+ async function main() {
293
+ const config = loadConfig();
294
+ const client = new Bluework4Client(config);
295
+ const server = new McpServer({
296
+ name: SERVER_NAME,
297
+ version: SERVER_VERSION
298
+ });
299
+ registerTools(server, client, config);
300
+ const transport = new StdioServerTransport();
301
+ await server.connect(transport);
302
+ console.error(`${SERVER_NAME} v${SERVER_VERSION} started`);
303
+ }
304
+ main().catch((error) => {
305
+ console.error("Fatal error:", error);
306
+ process.exit(1);
307
+ });
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@g1cloud/bluework4-tool",
3
+ "private": false,
4
+ "version": "1.0.0",
5
+ "description": "Bluework4 MCP Server - TypeScript version",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "bin": {
9
+ "bluework4-tool": "./dist/index.js"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "keywords": [
18
+ "mcp",
19
+ "bluework4",
20
+ "ai"
21
+ ],
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "@modelcontextprotocol/sdk": "^1.12.0",
25
+ "zod": "^3.24.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^22.0.0",
29
+ "tsup": "^8.0.0",
30
+ "tsx": "^4.0.0",
31
+ "typescript": "^5.7.0"
32
+ },
33
+ "engines": {
34
+ "node": ">=20.0.0"
35
+ },
36
+ "scripts": {
37
+ "build": "tsup",
38
+ "start": "node dist/index.js",
39
+ "dev": "tsx src/index.ts"
40
+ }
41
+ }