@cnbcool/mcp-server 0.3.0 → 0.3.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/CHANGELOG.md +17 -0
- package/README.md +4 -0
- package/dist/api/group.js +40 -0
- package/dist/api/repository.js +11 -0
- package/dist/api/user.js +5 -0
- package/dist/tools/groupTools.js +121 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/issueTools.js +31 -15
- package/dist/tools/repoTools.js +67 -17
- package/dist/tools/workspaceTools.js +17 -9
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
## 0.3.2 (May 6, 2025)
|
|
2
|
+
|
|
3
|
+
### New Features
|
|
4
|
+
|
|
5
|
+
- Supports list groups with various filters
|
|
6
|
+
- Supports list sub-groups with various filters
|
|
7
|
+
- Supports get group details
|
|
8
|
+
- Supports create group
|
|
9
|
+
- Supports create repository
|
|
10
|
+
|
|
11
|
+
## 0.3.1 (April 23, 2025)
|
|
12
|
+
|
|
13
|
+
### New Features
|
|
14
|
+
|
|
15
|
+
- Bump to @modelcontextprotocol/sdk 1.10.2
|
|
16
|
+
- Add zod preprocess, convert null to undefined
|
|
17
|
+
|
|
1
18
|
## 0.3.0 (April 23, 2025)
|
|
2
19
|
|
|
3
20
|
### New Features
|
package/README.md
CHANGED
|
@@ -19,6 +19,10 @@ https://cnb.cool/examples/ecosystem/cnb-mcp-client-with-ollama
|
|
|
19
19
|
4. `npm build`
|
|
20
20
|
5. `npx @modelcontextprotocol/inspector -e API_TOKEN=xxxxxxxxxx node dist/index.js`
|
|
21
21
|
|
|
22
|
+
> @modelcontextprotocol/inspector requires Node.js: ^22.7.5
|
|
23
|
+
|
|
24
|
+
> https://github.com/modelcontextprotocol/inspector?tab=readme-ov-file#requirements
|
|
25
|
+
|
|
22
26
|
## How to configure
|
|
23
27
|
|
|
24
28
|
### Local
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import CnbApiClient from './client.js';
|
|
2
|
+
export async function listGroups(params) {
|
|
3
|
+
const cnbInst = CnbApiClient.getInstance();
|
|
4
|
+
const url = new URL('/user/groups', cnbInst.baseUrl);
|
|
5
|
+
if (params) {
|
|
6
|
+
for (const [key, value] of Object.entries(params)) {
|
|
7
|
+
if (value === undefined)
|
|
8
|
+
continue;
|
|
9
|
+
url.searchParams.set(key, value.toString());
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return cnbInst.request('GET', `${url.pathname}${url.search}`);
|
|
13
|
+
}
|
|
14
|
+
export async function listSubGroups(group, params) {
|
|
15
|
+
const cnbInst = CnbApiClient.getInstance();
|
|
16
|
+
const url = new URL(`/user/groups/${group}`, cnbInst.baseUrl);
|
|
17
|
+
if (params) {
|
|
18
|
+
for (const [key, value] of Object.entries(params)) {
|
|
19
|
+
if (value === undefined)
|
|
20
|
+
continue;
|
|
21
|
+
url.searchParams.set(key, value.toString());
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return cnbInst.request('GET', `${url.pathname}${url.search}`);
|
|
25
|
+
}
|
|
26
|
+
export async function getGroup(group) {
|
|
27
|
+
const cnbInst = CnbApiClient.getInstance();
|
|
28
|
+
return cnbInst.request('GET', `/${group}`);
|
|
29
|
+
}
|
|
30
|
+
export async function createGroup(params) {
|
|
31
|
+
const body = Object.entries(params).reduce((acc, [key, value]) => {
|
|
32
|
+
if (value === undefined)
|
|
33
|
+
return acc;
|
|
34
|
+
Object.assign(acc, { [key]: value });
|
|
35
|
+
return acc;
|
|
36
|
+
}, {});
|
|
37
|
+
return CnbApiClient.getInstance().request('POST', '/groups', body, {
|
|
38
|
+
header: { 'Content-Type': 'application/json' }
|
|
39
|
+
});
|
|
40
|
+
}
|
package/dist/api/repository.js
CHANGED
|
@@ -26,3 +26,14 @@ export async function listGroupRepositories(group, params) {
|
|
|
26
26
|
export async function getRepository(repo) {
|
|
27
27
|
return CnbApiClient.getInstance().request('GET', `/${repo}`);
|
|
28
28
|
}
|
|
29
|
+
export async function createRepository(group, params) {
|
|
30
|
+
const body = Object.entries(params).reduce((acc, [key, value]) => {
|
|
31
|
+
if (value === undefined)
|
|
32
|
+
return acc;
|
|
33
|
+
Object.assign(acc, { [key]: value });
|
|
34
|
+
return acc;
|
|
35
|
+
}, {});
|
|
36
|
+
return CnbApiClient.getInstance().request('POST', `/${group}/-/repos`, body, {
|
|
37
|
+
header: { 'Content-Type': 'application/json' }
|
|
38
|
+
});
|
|
39
|
+
}
|
package/dist/api/user.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createGroup, getGroup, listGroups, listSubGroups } from '../api/group.js';
|
|
3
|
+
export default function registerGroupTools(server) {
|
|
4
|
+
server.tool('list-groups', '获取当前用户拥有权限的顶层组织列表', {
|
|
5
|
+
page: z.number().default(1).describe('第几页,从1开始'),
|
|
6
|
+
page_size: z.number().default(10).describe('每页多少条数据'),
|
|
7
|
+
search: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('仓库关键字'),
|
|
8
|
+
role: z
|
|
9
|
+
.preprocess((val) => (val === null ? undefined : val), z.enum(['Guest', 'Reporter', 'Developer', 'Master', 'Owner']).optional())
|
|
10
|
+
.describe('最小仓库权限')
|
|
11
|
+
}, async ({ page, page_size, search, role }) => {
|
|
12
|
+
try {
|
|
13
|
+
const repos = await listGroups({ page, page_size, search, role });
|
|
14
|
+
return {
|
|
15
|
+
content: [
|
|
16
|
+
{
|
|
17
|
+
type: 'text',
|
|
18
|
+
text: JSON.stringify(repos, null, 2)
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
return {
|
|
25
|
+
content: [
|
|
26
|
+
{
|
|
27
|
+
type: 'text',
|
|
28
|
+
text: `Error listing repositories: ${error instanceof Error ? error.message : String(error)}`
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
isError: true
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
server.tool('list-sub-groups', '查询当前用户在指定组织下拥有指定权限的子组织列表', {
|
|
36
|
+
group: z.string().describe('组织名称'),
|
|
37
|
+
page: z.number().default(1).describe('第几页,从1开始'),
|
|
38
|
+
page_size: z.number().default(10).describe('每页多少条数据'),
|
|
39
|
+
access: z.preprocess((val) => (val === null ? undefined : val), z.number().optional()).describe('权限等级')
|
|
40
|
+
}, async ({ group, page, page_size, access }) => {
|
|
41
|
+
try {
|
|
42
|
+
const subGroups = await listSubGroups(group, { page, page_size, access });
|
|
43
|
+
return {
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: 'text',
|
|
47
|
+
text: JSON.stringify(subGroups, null, 2)
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: `Error listing repositories: ${error instanceof Error ? error.message : String(error)}`
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
isError: true
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
server.tool('get-group', '获取指定组织信息', {
|
|
65
|
+
group: z.string().describe('组织路径')
|
|
66
|
+
}, async ({ group }) => {
|
|
67
|
+
try {
|
|
68
|
+
const data = await getGroup(group);
|
|
69
|
+
return {
|
|
70
|
+
content: [
|
|
71
|
+
{
|
|
72
|
+
type: 'text',
|
|
73
|
+
text: JSON.stringify(data, null, 2)
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{
|
|
82
|
+
type: 'text',
|
|
83
|
+
text: `Error getting repository: ${error instanceof Error ? error.message : String(error)}`
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
isError: true
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
server.tool('create-group', '创建新组织', {
|
|
91
|
+
path: z.string().describe('组织路径'),
|
|
92
|
+
description: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('组织描述'),
|
|
93
|
+
remark: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('仓库备注'),
|
|
94
|
+
bind_domain: z
|
|
95
|
+
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
96
|
+
.describe('根组织绑定的域名')
|
|
97
|
+
}, async ({ path, description, remark, bind_domain }) => {
|
|
98
|
+
try {
|
|
99
|
+
const data = await createGroup({ path, description, remark, bind_domain });
|
|
100
|
+
return {
|
|
101
|
+
content: [
|
|
102
|
+
{
|
|
103
|
+
type: 'text',
|
|
104
|
+
text: JSON.stringify(data, null, 2)
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
return {
|
|
111
|
+
content: [
|
|
112
|
+
{
|
|
113
|
+
type: 'text',
|
|
114
|
+
text: `Error creating repository: ${error instanceof Error ? error.message : String(error)}`
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
isError: true
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
package/dist/tools/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import CnbApiClient from '../api/client.js';
|
|
2
|
+
import registerGroupTools from './groupTools.js';
|
|
2
3
|
import registerRepoTools from './repoTools.js';
|
|
3
4
|
import registerIssueTools from './issueTools.js';
|
|
4
5
|
import registerWorkspaceTools from './workspaceTools.js';
|
|
@@ -7,6 +8,7 @@ export function registerTools(server) {
|
|
|
7
8
|
baseUrl: process.env.API_BASE_URL || 'https://api.cnb.cool',
|
|
8
9
|
token: process.env.API_TOKEN || ''
|
|
9
10
|
});
|
|
11
|
+
registerGroupTools(server);
|
|
10
12
|
registerRepoTools(server);
|
|
11
13
|
registerIssueTools(server);
|
|
12
14
|
registerWorkspaceTools(server);
|
package/dist/tools/issueTools.js
CHANGED
|
@@ -3,17 +3,29 @@ 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().
|
|
7
|
-
page_size: z.number().
|
|
8
|
-
state: z
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
page: z.number().default(1).describe('第几页,从1开始'),
|
|
7
|
+
page_size: z.number().default(10).describe('每页多少条数据'),
|
|
8
|
+
state: z
|
|
9
|
+
.preprocess((val) => (val === null ? undefined : val), z.enum(['open', 'closed']).optional())
|
|
10
|
+
.describe('Issue 状态'),
|
|
11
|
+
keyword: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('Issue 关键字'),
|
|
12
|
+
priority: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('Issue 优先级'),
|
|
13
|
+
labels: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('Issue 标签'),
|
|
14
|
+
authors: z
|
|
15
|
+
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
16
|
+
.describe('Issue 作者的名字'),
|
|
17
|
+
assignees: z
|
|
18
|
+
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
19
|
+
.describe('Issue 处理人'),
|
|
20
|
+
updated_time_begin: z
|
|
21
|
+
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
22
|
+
.describe('Issue 更新时间的范围,开始时间点'),
|
|
23
|
+
updated_time_end: z
|
|
24
|
+
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
25
|
+
.describe('Issue 更新时间的范围,结束时间点'),
|
|
26
|
+
order_by: z
|
|
27
|
+
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
28
|
+
.describe('Issue 排序顺序')
|
|
17
29
|
}, async ({ repo, page, page_size, state, keyword, priority, labels, authors, assignees, updated_time_begin, updated_time_end, order_by }) => {
|
|
18
30
|
try {
|
|
19
31
|
const issues = await listIssues(repo, {
|
|
@@ -80,10 +92,14 @@ export default function registerIssueTools(server) {
|
|
|
80
92
|
server.tool('create-issue', '创建一个 Issue', {
|
|
81
93
|
repo: z.string().describe('仓库路径'),
|
|
82
94
|
title: z.string().describe('Issue 标题'),
|
|
83
|
-
body: z.string().optional().describe('Issue 描述'),
|
|
84
|
-
assignees: z
|
|
85
|
-
|
|
86
|
-
|
|
95
|
+
body: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('Issue 描述'),
|
|
96
|
+
assignees: z
|
|
97
|
+
.preprocess((val) => (val === null ? undefined : val), z.array(z.string()).optional())
|
|
98
|
+
.describe('一个或多个 Issue 处理人的用户名'),
|
|
99
|
+
labels: z
|
|
100
|
+
.preprocess((val) => (val === null ? undefined : val), z.array(z.string()).optional())
|
|
101
|
+
.describe('一个或多个 Issue 标签'),
|
|
102
|
+
priority: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('Issue 优先级')
|
|
87
103
|
}, async ({ repo, title, body, assignees, labels, priority }) => {
|
|
88
104
|
try {
|
|
89
105
|
const issue = await createIssue(repo, {
|
package/dist/tools/repoTools.js
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { getRepository, listGroupRepositories, listRepositories } from '../api/repository.js';
|
|
2
|
+
import { createRepository, getRepository, listGroupRepositories, listRepositories } from '../api/repository.js';
|
|
3
|
+
import { getUser } from '../api/user.js';
|
|
3
4
|
export default function registerRepoTools(server) {
|
|
4
5
|
server.tool('list-repositories', '获取当前用户拥有指定权限及其以上权限的仓库', {
|
|
5
6
|
page: z.number().default(1).describe('第几页,从1开始'),
|
|
6
|
-
page_size: z.number().default(
|
|
7
|
-
search: z.string().optional().describe('仓库关键字'),
|
|
8
|
-
filter_type: z
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
page_size: z.number().default(10).describe('每页多少条数据'),
|
|
8
|
+
search: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('仓库关键字'),
|
|
9
|
+
filter_type: z
|
|
10
|
+
.preprocess((val) => (val === null ? undefined : val), z.enum(['private', 'public', 'encrypted']).optional())
|
|
11
|
+
.describe('仓库类型'),
|
|
12
|
+
role: z
|
|
13
|
+
.preprocess((val) => (val === null ? undefined : val), z.enum(['Reporter', 'Developer', 'Master', 'Owner']).optional())
|
|
14
|
+
.describe('最小仓库权限'),
|
|
15
|
+
order_by: z
|
|
16
|
+
.preprocess((val) => (val === null ? undefined : val), z.enum(['created_at', 'last_updated_at', 'stars']).optional())
|
|
17
|
+
.describe('排序类型'),
|
|
18
|
+
desc: z.preprocess((val) => (val === null ? undefined : val), z.boolean().optional()).describe('排序顺序')
|
|
12
19
|
}, async ({ page, page_size, search, filter_type, role, order_by, desc }) => {
|
|
13
20
|
try {
|
|
14
21
|
const repos = await listRepositories({ page, page_size, search, filter_type, role, order_by, desc });
|
|
@@ -36,12 +43,18 @@ export default function registerRepoTools(server) {
|
|
|
36
43
|
server.tool('list-group-repositories', '获取分组里当前用户有权限的仓库', {
|
|
37
44
|
group: z.string().describe('组织名称'),
|
|
38
45
|
page: z.number().default(1).describe('第几页,从1开始'),
|
|
39
|
-
page_size: z.number().default(
|
|
40
|
-
search: z.string().optional().describe('仓库关键字'),
|
|
41
|
-
filter_type: z
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
page_size: z.number().default(10).describe('每页多少条数据'),
|
|
47
|
+
search: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('仓库关键字'),
|
|
48
|
+
filter_type: z
|
|
49
|
+
.preprocess((val) => (val === null ? undefined : val), z.enum(['private', 'public', 'encrypted']).optional())
|
|
50
|
+
.describe('仓库类型'),
|
|
51
|
+
descendant: z
|
|
52
|
+
.preprocess((val) => (val === null ? undefined : val), z.enum(['all', 'sub', 'grand']).optional())
|
|
53
|
+
.describe('查全部、直接属于当前组织的仓库、子组织的仓库'),
|
|
54
|
+
order_by: z
|
|
55
|
+
.preprocess((val) => (val === null ? undefined : val), z.enum(['created_at', 'last_updated_at', 'stars', 'slug_path']).optional())
|
|
56
|
+
.describe('排序类型'),
|
|
57
|
+
desc: z.preprocess((val) => (val === null ? undefined : val), z.boolean().optional()).describe('排序顺序')
|
|
45
58
|
}, async ({ group, page, page_size, search, filter_type, descendant, order_by, desc }) => {
|
|
46
59
|
try {
|
|
47
60
|
const repos = await listGroupRepositories(group, {
|
|
@@ -75,15 +88,15 @@ export default function registerRepoTools(server) {
|
|
|
75
88
|
}
|
|
76
89
|
});
|
|
77
90
|
server.tool('get-repository', '获取指定仓库信息', {
|
|
78
|
-
|
|
79
|
-
}, async ({
|
|
91
|
+
repo: z.string().describe('仓库路径')
|
|
92
|
+
}, async ({ repo }) => {
|
|
80
93
|
try {
|
|
81
|
-
const
|
|
94
|
+
const data = await getRepository(repo);
|
|
82
95
|
return {
|
|
83
96
|
content: [
|
|
84
97
|
{
|
|
85
98
|
type: 'text',
|
|
86
|
-
text: JSON.stringify(
|
|
99
|
+
text: JSON.stringify(data, null, 2)
|
|
87
100
|
}
|
|
88
101
|
]
|
|
89
102
|
};
|
|
@@ -100,4 +113,41 @@ export default function registerRepoTools(server) {
|
|
|
100
113
|
};
|
|
101
114
|
}
|
|
102
115
|
});
|
|
116
|
+
server.tool('create-repository', '创建仓库', {
|
|
117
|
+
group: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('仓库所属分组'),
|
|
118
|
+
name: z.string().describe('仓库名称'),
|
|
119
|
+
description: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('仓库描述'),
|
|
120
|
+
license: z.preprocess((val) => (val === null ? undefined : val), z.string().optional()).describe('仓库许可'),
|
|
121
|
+
visibility: z
|
|
122
|
+
.preprocess((val) => (val === null ? undefined : val), z.enum(['public', 'private', 'secret']).default('public'))
|
|
123
|
+
.describe('仓库可见性')
|
|
124
|
+
}, async ({ group, name, description, license, visibility }) => {
|
|
125
|
+
let repoGroup = group;
|
|
126
|
+
if (!repoGroup) {
|
|
127
|
+
const { username = '' } = await getUser();
|
|
128
|
+
repoGroup = username;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const data = await createRepository(repoGroup, { name, description, license, visibility });
|
|
132
|
+
return {
|
|
133
|
+
content: [
|
|
134
|
+
{
|
|
135
|
+
type: 'text',
|
|
136
|
+
text: JSON.stringify(data, null, 2)
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
return {
|
|
143
|
+
content: [
|
|
144
|
+
{
|
|
145
|
+
type: 'text',
|
|
146
|
+
text: `Error creating repository: ${error instanceof Error ? error.message : String(error)}`
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
isError: true
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
});
|
|
103
153
|
}
|
|
@@ -2,18 +2,26 @@ import { z } from 'zod';
|
|
|
2
2
|
import { deleteWorkspace, listWorkspace } from '../api/workspace.js';
|
|
3
3
|
export default function registerWorkspaceTools(server) {
|
|
4
4
|
server.tool('list-workspace', '获取我的云原生开发环境列表', {
|
|
5
|
-
branch: z
|
|
5
|
+
branch: z
|
|
6
|
+
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
7
|
+
.describe('分支名,例如:main'),
|
|
6
8
|
start: z
|
|
7
|
-
.string()
|
|
8
|
-
.optional()
|
|
9
|
+
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
9
10
|
.describe('查询结束时间,格式:YYYY-MM-DD HH:mm:ssZZ,例如:2024-12-01 00:00:00+0800'),
|
|
10
|
-
end: z
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
end: z
|
|
12
|
+
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
13
|
+
.describe('查询开始时间,格式:YYYY-MM-DD HH:mm:ssZZ,例如:2024-12-01 00:00:00+0800'),
|
|
14
|
+
page: z
|
|
15
|
+
.preprocess((val) => (val === null ? undefined : val), z.number().optional())
|
|
16
|
+
.describe('分页页码,从 1 开始,默认为 1'),
|
|
17
|
+
page_size: z
|
|
18
|
+
.preprocess((val) => (val === null ? undefined : val), z.number().optional())
|
|
19
|
+
.describe('每页条数,默认为 20,最高 100'),
|
|
20
|
+
slug: z
|
|
21
|
+
.preprocess((val) => (val === null ? undefined : val), z.string().optional())
|
|
22
|
+
.describe('仓库路径,例如:groupname/reponame'),
|
|
14
23
|
status: z
|
|
15
|
-
.enum(['running', 'closed'])
|
|
16
|
-
.optional()
|
|
24
|
+
.preprocess((val) => (val === null ? undefined : val), z.enum(['running', 'closed']).optional())
|
|
17
25
|
.describe('开发环境状态,running: 开发环境已启动,closed:开发环境已关闭,默认为所有状态')
|
|
18
26
|
}, async ({ branch, page, page_size, start, end, slug, status }) => {
|
|
19
27
|
try {
|
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.3.
|
|
4
|
+
"version": "0.3.2",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"cnb-mcp-server": "dist/index.js"
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"typescript": ">=5.5"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@modelcontextprotocol/sdk": "1.
|
|
41
|
-
"dotenv": "16.
|
|
42
|
-
"zod": "3.24.
|
|
40
|
+
"@modelcontextprotocol/sdk": "1.10.2",
|
|
41
|
+
"dotenv": "16.5.0",
|
|
42
|
+
"zod": "3.24.3"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@commitlint/cli": "19.8.0",
|