@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 +94 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +307 -0
- package/package.json +41 -0
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
|
package/dist/index.d.ts
ADDED
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
|
+
}
|