@cnbcool/mcp-server 0.4.0-beta.0 → 0.4.0-beta.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/README.md +24 -23
- package/dist/tools/issueTools.js +10 -8
- package/dist/tools/repoTools.js +14 -10
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -2,30 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
CNB(https://cnb.cool) toolkits for LLMs supporting the MCP protocol
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## How to use
|
|
6
|
+
|
|
7
|
+
### STDIO
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"mcpServers": {
|
|
12
|
+
"cnb": {
|
|
13
|
+
"command": "npx",
|
|
14
|
+
"args": ["-y", "-p", "@cnbcool/mcp-server", "cnb-mcp-stdio"],
|
|
15
|
+
"env": {
|
|
16
|
+
"API_BASE_URL": "<BASE_URL>", // optional, defualt vaule: https://api.cnb.cool
|
|
17
|
+
"API_TOKEN": "<YOUR_TOKEN>"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
6
23
|
|
|
7
|
-
https://cnb.cool/examples/ecosystem/cnb-mcp-client-with-ollama
|
|
8
24
|
|
|
9
25
|
## Prerequisite
|
|
10
26
|
|
|
11
27
|
1. node >= 18
|
|
12
|
-
2. typescript >=5.5
|
|
13
28
|
|
|
14
29
|
## How to develop
|
|
15
30
|
|
|
16
31
|
1. `npm install`
|
|
17
32
|
2. `npx openapi-typescript@5.4.2 https://api.cnb.cool/swagger.json -o src/schema.d.ts`
|
|
18
|
-
3.
|
|
19
|
-
4. `npm build`
|
|
20
|
-
5. `npx @modelcontextprotocol/inspector
|
|
33
|
+
3. Copy `.env.example` and rename to `.env` and fill in the values
|
|
34
|
+
4. `npm run build`
|
|
35
|
+
5. `npx @modelcontextprotocol/inspector node dist/stdio.js`
|
|
21
36
|
|
|
22
37
|
> @modelcontextprotocol/inspector requires Node.js: ^22.7.5
|
|
23
38
|
|
|
24
39
|
> https://github.com/modelcontextprotocol/inspector?tab=readme-ov-file#requirements
|
|
25
40
|
|
|
26
|
-
## How to
|
|
41
|
+
## How to preview
|
|
27
42
|
|
|
28
|
-
|
|
43
|
+
1. npm run build
|
|
44
|
+
2. set mcpServers config:
|
|
29
45
|
|
|
30
46
|
```json
|
|
31
47
|
{
|
|
@@ -42,19 +58,4 @@ https://cnb.cool/examples/ecosystem/cnb-mcp-client-with-ollama
|
|
|
42
58
|
}
|
|
43
59
|
```
|
|
44
60
|
|
|
45
|
-
### Production
|
|
46
61
|
|
|
47
|
-
```json
|
|
48
|
-
{
|
|
49
|
-
"mcpServers": {
|
|
50
|
-
"cnb": {
|
|
51
|
-
"command": "npx",
|
|
52
|
-
"args": ["-y", "@cnbcool/mcp-server"],
|
|
53
|
-
"env": {
|
|
54
|
-
"API_BASE_URL": "<BASE_URL>",
|
|
55
|
-
"API_TOKEN": "<YOUR_TOKEN>"
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
```
|
package/dist/tools/issueTools.js
CHANGED
|
@@ -3,29 +3,31 @@ import { createIssue, getIssue, listIssues } from '../api/issue.js';
|
|
|
3
3
|
export default function registerIssueTools(server) {
|
|
4
4
|
server.tool('list-issues', '查询仓库的 Issues', {
|
|
5
5
|
repo: z.string().describe('仓库路径'),
|
|
6
|
-
page: z.number().default(1).describe('
|
|
7
|
-
page_size: z.number().default(10).describe('
|
|
6
|
+
page: z.number().default(1).describe('第几页,从1开始'),
|
|
7
|
+
page_size: z.number().default(10).describe('每页多少条数据,默认是30'),
|
|
8
8
|
state: z
|
|
9
9
|
.preprocess((val) => (val === null ? undefined : val), z.enum(['open', 'closed']).optional())
|
|
10
10
|
.describe('Issue 状态'),
|
|
11
11
|
keyword: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('Issue 关键字'),
|
|
12
|
-
priority: z
|
|
12
|
+
priority: z
|
|
13
|
+
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
14
|
+
.describe('Issue 优先级,example: p0,p1,p2,p3'),
|
|
13
15
|
labels: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('Issue 标签'),
|
|
14
16
|
authors: z
|
|
15
17
|
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
16
|
-
.describe('Issue
|
|
18
|
+
.describe('Issue 作者的名字, example: 张三,李四'),
|
|
17
19
|
assignees: z
|
|
18
20
|
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
19
|
-
.describe('Issue
|
|
21
|
+
.describe('Issue 处理人,example: 张三,李四,-; - means assign to nobody'),
|
|
20
22
|
updated_time_begin: z
|
|
21
23
|
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
22
|
-
.describe('Issue
|
|
24
|
+
.describe('Issue 更新时间的范围,开始时间点,example: 2022-01-31'),
|
|
23
25
|
updated_time_end: z
|
|
24
26
|
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
25
|
-
.describe('Issue
|
|
27
|
+
.describe('Issue 更新时间的范围,结束时间点,example: 2022-01-31'),
|
|
26
28
|
order_by: z
|
|
27
29
|
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
28
|
-
.describe('Issue
|
|
30
|
+
.describe('Issue 排序顺序.example: created_at, -updated_at, reference_count。‘-’ prefix means descending order')
|
|
29
31
|
}, async ({ repo, page, page_size, state, keyword, priority, labels, authors, assignees, updated_time_begin, updated_time_end, order_by }) => {
|
|
30
32
|
try {
|
|
31
33
|
const issues = await listIssues(repo, {
|
package/dist/tools/repoTools.js
CHANGED
|
@@ -2,19 +2,21 @@ import { z } from 'zod';
|
|
|
2
2
|
import { getRepository, listGroupRepositories, listRepositories } from '../api/repository.js';
|
|
3
3
|
export default function registerRepoTools(server) {
|
|
4
4
|
server.tool('list-repositories', '获取当前用户拥有指定权限及其以上权限的仓库', {
|
|
5
|
-
page: z.number().default(1).describe('
|
|
6
|
-
page_size: z.number().default(10).describe('
|
|
7
|
-
search: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('
|
|
5
|
+
page: z.number().default(1).describe('第几页,从1开始,默认值是1'),
|
|
6
|
+
page_size: z.number().default(10).describe('每页多少条数据,默认值为10'),
|
|
7
|
+
search: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('查询关键字'),
|
|
8
8
|
filter_type: z
|
|
9
9
|
.preprocess((val) => (val === null ? undefined : val), z.enum(['private', 'public', 'encrypted']).optional())
|
|
10
|
-
.describe('
|
|
10
|
+
.describe('仓库类型,为空表示所有仓库类型,默认值为空'),
|
|
11
11
|
role: z
|
|
12
12
|
.preprocess((val) => (val === null ? undefined : val), z.enum(['Reporter', 'Developer', 'Master', 'Owner']).optional())
|
|
13
|
-
.describe('
|
|
13
|
+
.describe('最小仓库权限,当用户未指定角色时,需要主动传入Reporter'),
|
|
14
14
|
order_by: z
|
|
15
15
|
.preprocess((val) => (val === null ? undefined : val), z.enum(['created_at', 'last_updated_at', 'stars']).optional())
|
|
16
|
-
.describe('
|
|
17
|
-
desc: z
|
|
16
|
+
.describe('排序类型,默认值是last_updated_at'),
|
|
17
|
+
desc: z
|
|
18
|
+
.preprocess((val) => (val === null ? undefined : val), z.boolean().optional())
|
|
19
|
+
.describe('是否开启倒叙排序,默认值是false')
|
|
18
20
|
}, async ({ page, page_size, search, filter_type, role, order_by, desc }) => {
|
|
19
21
|
try {
|
|
20
22
|
const repos = await listRepositories({ page, page_size, search, filter_type, role, order_by, desc });
|
|
@@ -41,8 +43,8 @@ export default function registerRepoTools(server) {
|
|
|
41
43
|
});
|
|
42
44
|
server.tool('list-group-repositories', '获取分组里当前用户有权限的仓库', {
|
|
43
45
|
group: z.string().describe('组织名称'),
|
|
44
|
-
page: z.number().default(1).describe('
|
|
45
|
-
page_size: z.number().default(10).describe('
|
|
46
|
+
page: z.number().default(1).describe('第几页,从1开始,默认值是1'),
|
|
47
|
+
page_size: z.number().default(10).describe('每页多少条数据,默认值为10'),
|
|
46
48
|
search: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('仓库关键字'),
|
|
47
49
|
filter_type: z
|
|
48
50
|
.preprocess((val) => (val === null ? undefined : val), z.enum(['private', 'public', 'encrypted']).optional())
|
|
@@ -53,7 +55,9 @@ export default function registerRepoTools(server) {
|
|
|
53
55
|
order_by: z
|
|
54
56
|
.preprocess((val) => (val === null ? undefined : val), z.enum(['created_at', 'last_updated_at', 'stars', 'slug_path']).optional())
|
|
55
57
|
.describe('排序类型'),
|
|
56
|
-
desc: z
|
|
58
|
+
desc: z
|
|
59
|
+
.preprocess((val) => (val === null ? undefined : val), z.boolean().optional())
|
|
60
|
+
.describe('是否开启倒叙排序,默认值是false')
|
|
57
61
|
}, async ({ group, page, page_size, search, filter_type, descendant, order_by, desc }) => {
|
|
58
62
|
try {
|
|
59
63
|
const repos = await listGroupRepositories(group, {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cnbcool/mcp-server",
|
|
3
3
|
"description": "CNB MCP Server. A comprehensive MCP server that provides seamless integration to the CNB's API(https://cnb.cool), offering a wide range of tools for repository management, pipelines operations and collaboration features",
|
|
4
|
-
"version": "0.4.0-beta.
|
|
4
|
+
"version": "0.4.0-beta.2",
|
|
5
5
|
"main": "./dist/stdio.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"cnb-mcp-stdio": "dist/stdio.js",
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
"start": "node dist/stdio.js",
|
|
15
15
|
"prepare": "husky",
|
|
16
16
|
"lint": "eslint src",
|
|
17
|
-
"
|
|
17
|
+
"lint:fix": "eslint --fix src",
|
|
18
|
+
"format:check": "prettier --check src",
|
|
19
|
+
"format:fix": "prettier --write src"
|
|
18
20
|
},
|
|
19
21
|
"repository": {
|
|
20
22
|
"type": "git",
|
|
@@ -47,6 +49,7 @@
|
|
|
47
49
|
"@commitlint/cli": "19.8.0",
|
|
48
50
|
"@commitlint/config-conventional": "19.8.0",
|
|
49
51
|
"@eslint/js": "9.24.0",
|
|
52
|
+
"@modelcontextprotocol/inspector": "^0.11.0",
|
|
50
53
|
"@types/express": "5.0.1",
|
|
51
54
|
"@types/node": "22.13.9",
|
|
52
55
|
"eslint": "9.24.0",
|