bmall-mcp 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,80 @@
1
+ # bmall-mcp
2
+
3
+ MCP Server for bmall development rules and tools.
4
+
5
+ ## Features
6
+
7
+ - 📋 Sync bmall Rules to IDE directories
8
+ - 🔄 Support for Kiro, Cursor, Windsurf
9
+ - 📦 Easy one-command setup
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install
15
+ npm run build
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ### Local Development
21
+
22
+ ```bash
23
+ npm run dev
24
+ ```
25
+
26
+ ### In Kiro
27
+
28
+ Add to `.kiro/settings/mcp.json`:
29
+
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "bmall": {
34
+ "command": "npx",
35
+ "args": ["-y", "bmall-mcp"],
36
+ "env": {}
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ Then restart Kiro and use the `sync_rules` tool:
43
+
44
+ ```
45
+ User: 帮我同步 Rules 到 Kiro
46
+ AI: Calling sync_rules(ide="kiro")
47
+ ```
48
+
49
+ ## Project Structure
50
+
51
+ ```
52
+ bmall-mcp/
53
+ ├── src/
54
+ │ ├── index.ts # MCP Server entry
55
+ │ └── tools/
56
+ │ └── sync.ts # sync_rules implementation
57
+ ├── rules/ # bmall Rules files
58
+ ├── package.json
59
+ └── tsconfig.json
60
+ ```
61
+
62
+ ## Development
63
+
64
+ ```bash
65
+ # Build
66
+ npm run build
67
+
68
+ # Run
69
+ npm start
70
+
71
+ # Dev with ts-node
72
+ npm run dev
73
+ ```
74
+
75
+ ## Next Steps
76
+
77
+ - [ ] Add Resources for component library
78
+ - [ ] Add Git sync functionality
79
+ - [ ] Publish to npm
80
+ - [ ] Create one-click setup script
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
+ import { pullRules } from "./tools/pull.js";
6
+ import { pushRules } from "./tools/push.js";
7
+ import { getGitCommitPrompt } from "./tools/gitPrompt.js";
8
+ const server = new Server({
9
+ name: "bmall-mcp",
10
+ version: "1.0.0",
11
+ }, {
12
+ capabilities: {
13
+ tools: {},
14
+ },
15
+ });
16
+ // 注册 Tools
17
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
18
+ tools: [
19
+ {
20
+ name: "pull_rules",
21
+ description: "从 Git 下载/克隆 bmall Rules 到 IDE 目录",
22
+ inputSchema: {
23
+ type: "object",
24
+ properties: {
25
+ ide: {
26
+ type: "string",
27
+ enum: ["kiro", "cursor", "windsurf"],
28
+ description: "目标 IDE (可选,默认自动检测)",
29
+ },
30
+ rulesType: {
31
+ type: "string",
32
+ enum: ["ios", "android", "web", "flutter"],
33
+ description: "Rules 类型 (可选,默认自动检测)",
34
+ },
35
+ },
36
+ },
37
+ },
38
+ {
39
+ name: "push_rules",
40
+ description: "上传本地修改的 bmall Rules 到 Git",
41
+ inputSchema: {
42
+ type: "object",
43
+ properties: {
44
+ message: {
45
+ type: "string",
46
+ description: "提交信息 (可选)",
47
+ },
48
+ rulesType: {
49
+ type: "string",
50
+ enum: ["ios", "android", "web", "flutter"],
51
+ description: "Rules 类型 (可选,默认自动检测)",
52
+ },
53
+ },
54
+ },
55
+ },
56
+ {
57
+ name: "standard_git_commit",
58
+ description: "规范化 Git 提交:自动分析改动内容,生成符合约定式提交规范的 commit message 并推送",
59
+ inputSchema: {
60
+ type: "object",
61
+ properties: {
62
+ scope: {
63
+ type: "string",
64
+ description: "需求名称,如:语音转写SDK、购物车、登录模块",
65
+ },
66
+ },
67
+ required: ["scope"],
68
+ },
69
+ },
70
+ ],
71
+ }));
72
+ // 处理 Tool 调用
73
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
74
+ if (request.params.name === "pull_rules") {
75
+ const ide = request.params.arguments?.ide;
76
+ const rulesType = request.params.arguments?.rulesType;
77
+ const result = await pullRules(ide, rulesType);
78
+ return {
79
+ content: [
80
+ {
81
+ type: "text",
82
+ text: result,
83
+ },
84
+ ],
85
+ };
86
+ }
87
+ if (request.params.name === "push_rules") {
88
+ const message = request.params.arguments?.message;
89
+ const rulesType = request.params.arguments?.rulesType;
90
+ const result = await pushRules(message, rulesType);
91
+ return {
92
+ content: [
93
+ {
94
+ type: "text",
95
+ text: result,
96
+ },
97
+ ],
98
+ };
99
+ }
100
+ if (request.params.name === "standard_git_commit") {
101
+ const scope = request.params.arguments?.scope;
102
+ if (!scope) {
103
+ return {
104
+ content: [
105
+ {
106
+ type: "text",
107
+ text: "❌ 缺少必填参数: scope (需求名称)",
108
+ },
109
+ ],
110
+ };
111
+ }
112
+ const prompt = getGitCommitPrompt(scope);
113
+ return {
114
+ content: [
115
+ {
116
+ type: "text",
117
+ text: prompt,
118
+ },
119
+ ],
120
+ };
121
+ }
122
+ throw new Error(`Unknown tool: ${request.params.name}`);
123
+ });
124
+ // 启动服务器
125
+ async function main() {
126
+ const transport = new StdioServerTransport();
127
+ await server.connect(transport);
128
+ console.error("[bmall-mcp] Server running on stdio");
129
+ }
130
+ main().catch((error) => {
131
+ console.error("[bmall-mcp] Fatal error:", error);
132
+ process.exit(1);
133
+ });
134
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Git 提交规范 Prompt Tool
3
+ * 返回提示词,让 Agent 按规范执行 git commit
4
+ */
5
+ export declare function getGitCommitPrompt(scope: string): string;
6
+ //# sourceMappingURL=gitPrompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitPrompt.d.ts","sourceRoot":"","sources":["../../src/tools/gitPrompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CA+CxD"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Git 提交规范 Prompt Tool
3
+ * 返回提示词,让 Agent 按规范执行 git commit
4
+ */
5
+ export function getGitCommitPrompt(scope) {
6
+ return `# Git 提交任务
7
+
8
+ ## 你的任务
9
+ 为需求「${scope}」提交代码到远程仓库。
10
+
11
+ ## 执行步骤
12
+
13
+ 1. **检查状态**: 执行 \`git status\` 查看改动
14
+ 2. **查看差异**: 执行 \`git diff\` 分析具体改动内容
15
+ 3. **判断类型**: 根据改动内容判断 commit type
16
+ 4. **提交推送**: 执行 \`git add . && git commit && git push\`
17
+
18
+ ## Commit Message 格式
19
+
20
+ \`\`\`
21
+ <type>(${scope}): <描述>
22
+
23
+ [可选正文]
24
+ \`\`\`
25
+
26
+ ## Type 类型
27
+
28
+ - **fix**: 修复 bug
29
+ - **feat**: 新增功能
30
+ - **docs**: 文档更新
31
+ - **refactor**: 代码重构
32
+ - **style**: 代码格式调整
33
+ - **perf**: 性能优化
34
+ - **test**: 测试相关
35
+ - **chore**: 构建/工具变动
36
+
37
+ ## 规则
38
+
39
+ - **[必须]** scope 使用「${scope}」
40
+ - **[必须]** 描述清晰简洁,说明做了什么
41
+ - **[必须]** 根据实际改动判断 type,不要猜测
42
+ - **[建议]** 重要功能添加正文说明改动细节
43
+
44
+ ## 示例
45
+
46
+ \`\`\`bash
47
+ git commit -m "feat(${scope}): 添加语音录制功能"
48
+ git commit -m "fix(${scope}): 修复登录失败问题"
49
+ \`\`\`
50
+
51
+ 现在请执行任务。`;
52
+ }
53
+ //# sourceMappingURL=gitPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitPrompt.js","sourceRoot":"","sources":["../../src/tools/gitPrompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO;;;MAGH,KAAK;;;;;;;;;;;;SAYF,KAAK;;;;;;;;;;;;;;;;;;sBAkBQ,KAAK;;;;;;;;sBAQL,KAAK;qBACN,KAAK;;;SAGjB,CAAC;AACV,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function pullRules(ide?: string, rulesType?: string): Promise<string>;
2
+ //# sourceMappingURL=pull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/tools/pull.ts"],"names":[],"mappings":"AAYA,wBAAsB,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8CjF"}
@@ -0,0 +1,43 @@
1
+ import * as path from "path";
2
+ import * as fs from "fs";
3
+ import { RULES_CACHE_DIR, log, validateAndGetRulesType, validateAndGetIDE, fetchRulesFromGit, copyMarkdownFiles, getGitRulesDir, } from "./utils.js";
4
+ export async function pullRules(ide, rulesType) {
5
+ try {
6
+ // 验证并获取 Rules 类型
7
+ const typeResult = validateAndGetRulesType(rulesType);
8
+ if (typeResult.error) {
9
+ return typeResult.error;
10
+ }
11
+ const projectType = typeResult.type;
12
+ // 验证并获取 IDE
13
+ const ideResult = validateAndGetIDE(ide);
14
+ if (ideResult.error) {
15
+ return ideResult.error;
16
+ }
17
+ const targetPath = ideResult.path;
18
+ // 确保父目录存在
19
+ fs.mkdirSync(targetPath, { recursive: true });
20
+ // 目标路径包含项目类型文件夹(如 .kiro/steering/bmall/iOS/)
21
+ const rulesTypeDir = getGitRulesDir(projectType);
22
+ const targetRulesTypeDir = path.join(targetPath, rulesTypeDir);
23
+ log(`Fetching rules from git...`);
24
+ const rulesSourceDir = await fetchRulesFromGit(projectType);
25
+ log(`Copying files to ${targetRulesTypeDir}...`);
26
+ // 直接覆盖,不备份(Git 本身有版本管理)
27
+ const result = copyMarkdownFiles(rulesSourceDir, targetRulesTypeDir, { backup: false });
28
+ if (result.count === 0) {
29
+ return `⚠️ 未找到任何 Markdown 文件\n源目录: ${rulesSourceDir}`;
30
+ }
31
+ return `✅ 下载完成!
32
+ Rules 类型: ${projectType}
33
+ IDE: ${ideResult.ide}
34
+ 目标目录: ${targetRulesTypeDir}
35
+ 复制文件数: ${result.count}
36
+ 缓存目录: ${RULES_CACHE_DIR}`;
37
+ }
38
+ catch (error) {
39
+ const errorMsg = error instanceof Error ? error.message : String(error);
40
+ return `❌ 下载失败: ${errorMsg}`;
41
+ }
42
+ }
43
+ //# sourceMappingURL=pull.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/tools/pull.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EACL,eAAe,EACf,GAAG,EACH,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAY,EAAE,SAAkB;IAC9D,IAAI,CAAC;QACH,iBAAiB;QACjB,MAAM,UAAU,GAAG,uBAAuB,CAAC,SAAS,CAAC,CAAC;QACtD,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,OAAO,UAAU,CAAC,KAAK,CAAC;QAC1B,CAAC;QACD,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC;QAEpC,YAAY;QACZ,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,OAAO,SAAS,CAAC,KAAK,CAAC;QACzB,CAAC;QAED,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC;QAElC,UAAU;QACV,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9C,6CAA6C;QAC7C,MAAM,YAAY,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;QACjD,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAE/D,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAClC,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;QAE5D,GAAG,CAAC,oBAAoB,kBAAkB,KAAK,CAAC,CAAC;QACjD,wBAAwB;QACxB,MAAM,MAAM,GAAG,iBAAiB,CAAC,cAAc,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAExF,IAAI,MAAM,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,8BAA8B,cAAc,EAAE,CAAC;QACxD,CAAC;QAED,OAAO;YACC,WAAW;OAChB,SAAS,CAAC,GAAG;QACZ,kBAAkB;SACjB,MAAM,CAAC,KAAK;QACb,eAAe,EAAE,CAAC;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,QAAQ,GACZ,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzD,OAAO,WAAW,QAAQ,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function pushRules(message?: string, rulesType?: string): Promise<string>;
2
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/tools/push.ts"],"names":[],"mappings":"AAiBA,wBAAsB,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6GrF"}
@@ -0,0 +1,93 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { GIT_BRANCH, RULES_CACHE_DIR, log, validateAndGetRulesType, validateAndGetIDE, detectProjectName, getGitRulesDir, copyMarkdownFiles, initializeGitCache, setupSparseCheckout, checkoutOrCreateBranch, } from "./utils.js";
4
+ import { execSync } from "child_process";
5
+ export async function pushRules(message, rulesType) {
6
+ try {
7
+ // 验证并获取 Rules 类型
8
+ const typeResult = validateAndGetRulesType(rulesType);
9
+ if (typeResult.error) {
10
+ return typeResult.error;
11
+ }
12
+ const projectType = typeResult.type;
13
+ // 验证并获取 IDE
14
+ const ideResult = validateAndGetIDE();
15
+ if (ideResult.error) {
16
+ return ideResult.error;
17
+ }
18
+ // 检测项目名称,用于创建项目级分支
19
+ const projectName = detectProjectName();
20
+ const projectBranch = `project/${projectName}`;
21
+ const localRulesPath = ideResult.path;
22
+ // 验证本地 Rules 目录
23
+ if (!fs.existsSync(localRulesPath)) {
24
+ return `❌ 本地 Rules 目录不存在: ${localRulesPath}`;
25
+ }
26
+ // 本地 Rules 目录中的项目类型文件夹(如 .kiro/steering/bmall/iOS/)
27
+ const localRulesTypeDir = path.join(localRulesPath, getGitRulesDir(projectType));
28
+ if (!fs.existsSync(localRulesTypeDir)) {
29
+ return `❌ 本地 Rules 类型目录不存在: ${localRulesTypeDir}\n请先运行 pull_rules 下载 Rules`;
30
+ }
31
+ log(`项目名称: ${projectName}`);
32
+ log(`项目分支: ${projectBranch}`);
33
+ log(`本地 Rules 类型目录: ${localRulesTypeDir}`);
34
+ // 初始化缓存仓库
35
+ initializeGitCache();
36
+ // 设置 sparse-checkout
37
+ const rulesDir = getGitRulesDir(projectType);
38
+ setupSparseCheckout(rulesDir);
39
+ // 拉取最新代码
40
+ log(`拉取最新代码...`);
41
+ execSync(`git -C ${RULES_CACHE_DIR} fetch origin`, {
42
+ stdio: "inherit",
43
+ });
44
+ // 检出或创建项目分支
45
+ checkoutOrCreateBranch(projectBranch);
46
+ // 复制本地修改到缓存仓库
47
+ const cacheRulesTypeDir = path.join(RULES_CACHE_DIR, rulesDir);
48
+ log(`复制本地修改到缓存仓库...`);
49
+ // 清空缓存目录中的旧文件
50
+ if (fs.existsSync(cacheRulesTypeDir)) {
51
+ fs.rmSync(cacheRulesTypeDir, { recursive: true, force: true });
52
+ }
53
+ // 复制时不需要备份(覆盖缓存目录)
54
+ const result = copyMarkdownFiles(localRulesTypeDir, cacheRulesTypeDir, { backup: false });
55
+ log(`复制文件数: ${result.count}`);
56
+ // 检查是否有修改
57
+ log(`检查修改...`);
58
+ const status = execSync(`git -C ${RULES_CACHE_DIR} status --porcelain`, {
59
+ encoding: "utf-8",
60
+ });
61
+ if (!status.trim()) {
62
+ return `⚠️ 没有检测到修改`;
63
+ }
64
+ // 添加修改
65
+ log(`添加修改...`);
66
+ execSync(`git -C ${RULES_CACHE_DIR} add -A`, { stdio: "inherit" });
67
+ // 提交修改
68
+ const commitMessage = message || `chore(${projectType}): 更新 Rules`;
69
+ log(`提交修改: ${commitMessage}`);
70
+ execSync(`git -C ${RULES_CACHE_DIR} commit -m "${commitMessage}"`, {
71
+ stdio: "inherit",
72
+ });
73
+ // 推送到远程
74
+ log(`推送到远程分支 ${projectBranch}...`);
75
+ execSync(`git -C ${RULES_CACHE_DIR} push -u origin ${projectBranch}`, {
76
+ stdio: "inherit",
77
+ });
78
+ return `✅ 上传完成!
79
+ 项目名称: ${projectName}
80
+ Rules 类型: ${projectType}
81
+ 项目分支: ${projectBranch}
82
+ 提交信息: ${commitMessage}
83
+ 修改文件数: ${result.count}
84
+
85
+ 💡 提示: 修改已推送到项目分支,不会影响主分支 (${GIT_BRANCH})
86
+ 可以通过 Pull Request 将改动合并到主分支`;
87
+ }
88
+ catch (error) {
89
+ const errorMsg = error instanceof Error ? error.message : String(error);
90
+ return `❌ 上传失败: ${errorMsg}`;
91
+ }
92
+ }
93
+ //# sourceMappingURL=push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/tools/push.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function syncRules(ide?: string, rulesType?: string): Promise<string>;
2
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/tools/sync.ts"],"names":[],"mappings":"AA8RA,wBAAsB,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqDjF"}