@lightdash-tools/mcp 0.2.4 → 0.2.6
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 +2 -2
- package/dist/bin.js +1 -1
- package/dist/tools/groups.js +80 -0
- package/dist/tools/spaces.js +88 -0
- package/package.json +3 -3
- package/src/bin.ts +1 -1
- package/src/tools/groups.ts +132 -1
- package/src/tools/spaces.ts +172 -1
package/README.md
CHANGED
|
@@ -98,9 +98,9 @@ The server registers the following tools (names prefixed with `lightdash_tools__
|
|
|
98
98
|
|
|
99
99
|
The MCP server implements a hierarchical safety model. You can control which tools are available to AI agents using the `LIGHTDASH_TOOL_SAFETY_MODE` environment variable or the `--safety-mode` CLI option.
|
|
100
100
|
|
|
101
|
-
- `read-only
|
|
101
|
+
- `read-only` (default): Only allows non-modifying tools (e.g., `list_*`, `get_*`).
|
|
102
102
|
- `write-idempotent`: Allows read tools and non-destructive writes (e.g., `upsert_chart_as_code`).
|
|
103
|
-
- `write-destructive
|
|
103
|
+
- `write-destructive`: Allows all tools, including destructive ones (e.g., `delete_member`).
|
|
104
104
|
|
|
105
105
|
### Enforcement Layers
|
|
106
106
|
|
package/dist/bin.js
CHANGED
|
@@ -44,7 +44,7 @@ const program = new commander_1.Command();
|
|
|
44
44
|
program
|
|
45
45
|
.name('lightdash-mcp')
|
|
46
46
|
.description('MCP server for Lightdash AI')
|
|
47
|
-
.version('0.2.
|
|
47
|
+
.version('0.2.6')
|
|
48
48
|
.option('--http', 'Run as HTTP server instead of Stdio')
|
|
49
49
|
.option('--safety-mode <mode>', 'Filter registered tools by safety mode (read-only, write-idempotent, write-destructive)')
|
|
50
50
|
.action((options) => {
|
package/dist/tools/groups.js
CHANGED
|
@@ -38,4 +38,84 @@ function registerGroupTools(server, client) {
|
|
|
38
38
|
const group = yield c.v1.groups.getGroup(groupUuid);
|
|
39
39
|
return { content: [{ type: 'text', text: JSON.stringify(group, null, 2) }] };
|
|
40
40
|
})));
|
|
41
|
+
(0, shared_js_1.registerToolSafe)(server, 'create_group', {
|
|
42
|
+
title: 'Create group',
|
|
43
|
+
description: 'Create a new group in the organization',
|
|
44
|
+
inputSchema: {
|
|
45
|
+
name: zod_1.z.string().describe('Group name'),
|
|
46
|
+
},
|
|
47
|
+
annotations: shared_js_1.WRITE_IDEMPOTENT,
|
|
48
|
+
}, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ name }) {
|
|
49
|
+
const group = yield c.v1.groups.createGroup({ name });
|
|
50
|
+
return { content: [{ type: 'text', text: JSON.stringify(group, null, 2) }] };
|
|
51
|
+
})));
|
|
52
|
+
(0, shared_js_1.registerToolSafe)(server, 'update_group', {
|
|
53
|
+
title: 'Update group',
|
|
54
|
+
description: 'Update a group name',
|
|
55
|
+
inputSchema: {
|
|
56
|
+
groupUuid: zod_1.z.string().describe('Group UUID'),
|
|
57
|
+
name: zod_1.z.string().describe('New group name'),
|
|
58
|
+
},
|
|
59
|
+
annotations: shared_js_1.WRITE_IDEMPOTENT,
|
|
60
|
+
}, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ groupUuid, name }) {
|
|
61
|
+
const group = yield c.v1.groups.updateGroup(groupUuid, { name });
|
|
62
|
+
return { content: [{ type: 'text', text: JSON.stringify(group, null, 2) }] };
|
|
63
|
+
})));
|
|
64
|
+
(0, shared_js_1.registerToolSafe)(server, 'delete_group', {
|
|
65
|
+
title: 'Delete group',
|
|
66
|
+
description: 'Delete a group by UUID',
|
|
67
|
+
inputSchema: {
|
|
68
|
+
groupUuid: zod_1.z.string().describe('Group UUID'),
|
|
69
|
+
},
|
|
70
|
+
annotations: shared_js_1.WRITE_DESTRUCTIVE,
|
|
71
|
+
}, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ groupUuid }) {
|
|
72
|
+
yield c.v1.groups.deleteGroup(groupUuid);
|
|
73
|
+
return { content: [{ type: 'text', text: `Group ${groupUuid} deleted successfully` }] };
|
|
74
|
+
})));
|
|
75
|
+
(0, shared_js_1.registerToolSafe)(server, 'list_group_members', {
|
|
76
|
+
title: 'List group members',
|
|
77
|
+
description: 'List members of a group',
|
|
78
|
+
inputSchema: {
|
|
79
|
+
groupUuid: zod_1.z.string().describe('Group UUID'),
|
|
80
|
+
},
|
|
81
|
+
annotations: shared_js_1.READ_ONLY_DEFAULT,
|
|
82
|
+
}, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ groupUuid }) {
|
|
83
|
+
const members = yield c.v1.groups.getGroupMembers(groupUuid);
|
|
84
|
+
return { content: [{ type: 'text', text: JSON.stringify(members, null, 2) }] };
|
|
85
|
+
})));
|
|
86
|
+
(0, shared_js_1.registerToolSafe)(server, 'add_user_to_group', {
|
|
87
|
+
title: 'Add user to group',
|
|
88
|
+
description: 'Add a user to a group',
|
|
89
|
+
inputSchema: {
|
|
90
|
+
groupUuid: zod_1.z.string().describe('Group UUID'),
|
|
91
|
+
userUuid: zod_1.z.string().describe('User UUID'),
|
|
92
|
+
},
|
|
93
|
+
annotations: shared_js_1.WRITE_IDEMPOTENT,
|
|
94
|
+
}, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ groupUuid, userUuid }) {
|
|
95
|
+
yield c.v1.groups.addUserToGroup(groupUuid, userUuid);
|
|
96
|
+
return {
|
|
97
|
+
content: [
|
|
98
|
+
{ type: 'text', text: `User ${userUuid} added to group ${groupUuid} successfully` },
|
|
99
|
+
],
|
|
100
|
+
};
|
|
101
|
+
})));
|
|
102
|
+
(0, shared_js_1.registerToolSafe)(server, 'remove_user_from_group', {
|
|
103
|
+
title: 'Remove user from group',
|
|
104
|
+
description: 'Remove a user from a group',
|
|
105
|
+
inputSchema: {
|
|
106
|
+
groupUuid: zod_1.z.string().describe('Group UUID'),
|
|
107
|
+
userUuid: zod_1.z.string().describe('User UUID'),
|
|
108
|
+
},
|
|
109
|
+
annotations: shared_js_1.WRITE_DESTRUCTIVE,
|
|
110
|
+
}, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ groupUuid, userUuid }) {
|
|
111
|
+
yield c.v1.groups.removeUserFromGroup(groupUuid, userUuid);
|
|
112
|
+
return {
|
|
113
|
+
content: [
|
|
114
|
+
{
|
|
115
|
+
type: 'text',
|
|
116
|
+
text: `User ${userUuid} removed from group ${groupUuid} successfully`,
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
})));
|
|
41
121
|
}
|
package/dist/tools/spaces.js
CHANGED
|
@@ -37,4 +37,92 @@ function registerSpaceTools(server, client) {
|
|
|
37
37
|
const space = yield c.v1.spaces.getSpace(projectUuid, spaceUuid);
|
|
38
38
|
return { content: [{ type: 'text', text: JSON.stringify(space, null, 2) }] };
|
|
39
39
|
})));
|
|
40
|
+
(0, shared_js_1.registerToolSafe)(server, 'grant_user_space_access', {
|
|
41
|
+
title: 'Grant user access to space',
|
|
42
|
+
description: 'Grant a user access to a space',
|
|
43
|
+
inputSchema: {
|
|
44
|
+
projectUuid: zod_1.z.string().describe('Project UUID'),
|
|
45
|
+
spaceUuid: zod_1.z.string().describe('Space UUID'),
|
|
46
|
+
userUuid: zod_1.z.string().describe('User UUID'),
|
|
47
|
+
spaceRole: zod_1.z.enum(['viewer', 'editor', 'admin']).describe('Space role'),
|
|
48
|
+
},
|
|
49
|
+
annotations: shared_js_1.WRITE_IDEMPOTENT,
|
|
50
|
+
}, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, spaceUuid, userUuid, spaceRole, }) {
|
|
51
|
+
yield c.v1.spaces.grantUserAccessToSpace(projectUuid, spaceUuid, {
|
|
52
|
+
userUuid,
|
|
53
|
+
spaceRole: spaceRole,
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
content: [
|
|
57
|
+
{
|
|
58
|
+
type: 'text',
|
|
59
|
+
text: `Successfully granted ${spaceRole} access to user ${userUuid} in space ${spaceUuid}`,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
})));
|
|
64
|
+
(0, shared_js_1.registerToolSafe)(server, 'revoke_user_space_access', {
|
|
65
|
+
title: 'Revoke user access to space',
|
|
66
|
+
description: "Revoke a user's access to a space",
|
|
67
|
+
inputSchema: {
|
|
68
|
+
projectUuid: zod_1.z.string().describe('Project UUID'),
|
|
69
|
+
spaceUuid: zod_1.z.string().describe('Space UUID'),
|
|
70
|
+
userUuid: zod_1.z.string().describe('User UUID'),
|
|
71
|
+
},
|
|
72
|
+
annotations: shared_js_1.WRITE_DESTRUCTIVE,
|
|
73
|
+
}, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, spaceUuid, userUuid, }) {
|
|
74
|
+
yield c.v1.spaces.revokeUserAccessToSpace(projectUuid, spaceUuid, userUuid);
|
|
75
|
+
return {
|
|
76
|
+
content: [
|
|
77
|
+
{
|
|
78
|
+
type: 'text',
|
|
79
|
+
text: `Successfully revoked access for user ${userUuid} in space ${spaceUuid}`,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
})));
|
|
84
|
+
(0, shared_js_1.registerToolSafe)(server, 'grant_group_space_access', {
|
|
85
|
+
title: 'Grant group access to space',
|
|
86
|
+
description: 'Grant a group access to a space',
|
|
87
|
+
inputSchema: {
|
|
88
|
+
projectUuid: zod_1.z.string().describe('Project UUID'),
|
|
89
|
+
spaceUuid: zod_1.z.string().describe('Space UUID'),
|
|
90
|
+
groupUuid: zod_1.z.string().describe('Group UUID'),
|
|
91
|
+
spaceRole: zod_1.z.enum(['viewer', 'editor', 'admin']).describe('Space role'),
|
|
92
|
+
},
|
|
93
|
+
annotations: shared_js_1.WRITE_IDEMPOTENT,
|
|
94
|
+
}, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, spaceUuid, groupUuid, spaceRole, }) {
|
|
95
|
+
yield c.v1.spaces.grantGroupAccessToSpace(projectUuid, spaceUuid, {
|
|
96
|
+
groupUuid,
|
|
97
|
+
spaceRole: spaceRole,
|
|
98
|
+
});
|
|
99
|
+
return {
|
|
100
|
+
content: [
|
|
101
|
+
{
|
|
102
|
+
type: 'text',
|
|
103
|
+
text: `Successfully granted ${spaceRole} access to group ${groupUuid} in space ${spaceUuid}`,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
};
|
|
107
|
+
})));
|
|
108
|
+
(0, shared_js_1.registerToolSafe)(server, 'revoke_group_space_access', {
|
|
109
|
+
title: 'Revoke group access to space',
|
|
110
|
+
description: "Revoke a group's access to a space",
|
|
111
|
+
inputSchema: {
|
|
112
|
+
projectUuid: zod_1.z.string().describe('Project UUID'),
|
|
113
|
+
spaceUuid: zod_1.z.string().describe('Space UUID'),
|
|
114
|
+
groupUuid: zod_1.z.string().describe('Group UUID'),
|
|
115
|
+
},
|
|
116
|
+
annotations: shared_js_1.WRITE_DESTRUCTIVE,
|
|
117
|
+
}, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, spaceUuid, groupUuid, }) {
|
|
118
|
+
yield c.v1.spaces.revokeGroupAccessToSpace(projectUuid, spaceUuid, groupUuid);
|
|
119
|
+
return {
|
|
120
|
+
content: [
|
|
121
|
+
{
|
|
122
|
+
type: 'text',
|
|
123
|
+
text: `Successfully revoked access for group ${groupUuid} in space ${spaceUuid}`,
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
};
|
|
127
|
+
})));
|
|
40
128
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightdash-tools/mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "MCP server and utilities for Lightdash AI.",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
15
15
|
"commander": "^14.0.3",
|
|
16
16
|
"zod": "^4.3.6",
|
|
17
|
-
"@lightdash-tools/
|
|
18
|
-
"@lightdash-tools/
|
|
17
|
+
"@lightdash-tools/common": "0.2.6",
|
|
18
|
+
"@lightdash-tools/client": "0.2.6"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/node": "^25.2.3"
|
package/src/bin.ts
CHANGED
package/src/tools/groups.ts
CHANGED
|
@@ -5,7 +5,13 @@
|
|
|
5
5
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
6
|
import type { LightdashClient } from '@lightdash-tools/client';
|
|
7
7
|
import { z } from 'zod';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
wrapTool,
|
|
10
|
+
registerToolSafe,
|
|
11
|
+
READ_ONLY_DEFAULT,
|
|
12
|
+
WRITE_IDEMPOTENT,
|
|
13
|
+
WRITE_DESTRUCTIVE,
|
|
14
|
+
} from './shared.js';
|
|
9
15
|
|
|
10
16
|
type ListGroupsParams = {
|
|
11
17
|
page?: number;
|
|
@@ -32,6 +38,7 @@ export function registerGroupTools(server: McpServer, client: LightdashClient):
|
|
|
32
38
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
33
39
|
}),
|
|
34
40
|
);
|
|
41
|
+
|
|
35
42
|
registerToolSafe(
|
|
36
43
|
server,
|
|
37
44
|
'get_group',
|
|
@@ -46,4 +53,128 @@ export function registerGroupTools(server: McpServer, client: LightdashClient):
|
|
|
46
53
|
return { content: [{ type: 'text', text: JSON.stringify(group, null, 2) }] };
|
|
47
54
|
}),
|
|
48
55
|
);
|
|
56
|
+
|
|
57
|
+
registerToolSafe(
|
|
58
|
+
server,
|
|
59
|
+
'create_group',
|
|
60
|
+
{
|
|
61
|
+
title: 'Create group',
|
|
62
|
+
description: 'Create a new group in the organization',
|
|
63
|
+
inputSchema: {
|
|
64
|
+
name: z.string().describe('Group name'),
|
|
65
|
+
},
|
|
66
|
+
annotations: WRITE_IDEMPOTENT,
|
|
67
|
+
},
|
|
68
|
+
wrapTool(client, (c) => async ({ name }: { name: string }) => {
|
|
69
|
+
const group = await c.v1.groups.createGroup({ name });
|
|
70
|
+
return { content: [{ type: 'text', text: JSON.stringify(group, null, 2) }] };
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
registerToolSafe(
|
|
75
|
+
server,
|
|
76
|
+
'update_group',
|
|
77
|
+
{
|
|
78
|
+
title: 'Update group',
|
|
79
|
+
description: 'Update a group name',
|
|
80
|
+
inputSchema: {
|
|
81
|
+
groupUuid: z.string().describe('Group UUID'),
|
|
82
|
+
name: z.string().describe('New group name'),
|
|
83
|
+
},
|
|
84
|
+
annotations: WRITE_IDEMPOTENT,
|
|
85
|
+
},
|
|
86
|
+
wrapTool(client, (c) => async ({ groupUuid, name }: { groupUuid: string; name: string }) => {
|
|
87
|
+
const group = await c.v1.groups.updateGroup(groupUuid, { name });
|
|
88
|
+
return { content: [{ type: 'text', text: JSON.stringify(group, null, 2) }] };
|
|
89
|
+
}),
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
registerToolSafe(
|
|
93
|
+
server,
|
|
94
|
+
'delete_group',
|
|
95
|
+
{
|
|
96
|
+
title: 'Delete group',
|
|
97
|
+
description: 'Delete a group by UUID',
|
|
98
|
+
inputSchema: {
|
|
99
|
+
groupUuid: z.string().describe('Group UUID'),
|
|
100
|
+
},
|
|
101
|
+
annotations: WRITE_DESTRUCTIVE,
|
|
102
|
+
},
|
|
103
|
+
wrapTool(client, (c) => async ({ groupUuid }: { groupUuid: string }) => {
|
|
104
|
+
await c.v1.groups.deleteGroup(groupUuid);
|
|
105
|
+
return { content: [{ type: 'text', text: `Group ${groupUuid} deleted successfully` }] };
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
registerToolSafe(
|
|
110
|
+
server,
|
|
111
|
+
'list_group_members',
|
|
112
|
+
{
|
|
113
|
+
title: 'List group members',
|
|
114
|
+
description: 'List members of a group',
|
|
115
|
+
inputSchema: {
|
|
116
|
+
groupUuid: z.string().describe('Group UUID'),
|
|
117
|
+
},
|
|
118
|
+
annotations: READ_ONLY_DEFAULT,
|
|
119
|
+
},
|
|
120
|
+
wrapTool(client, (c) => async ({ groupUuid }: { groupUuid: string }) => {
|
|
121
|
+
const members = await c.v1.groups.getGroupMembers(groupUuid);
|
|
122
|
+
return { content: [{ type: 'text', text: JSON.stringify(members, null, 2) }] };
|
|
123
|
+
}),
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
registerToolSafe(
|
|
127
|
+
server,
|
|
128
|
+
'add_user_to_group',
|
|
129
|
+
{
|
|
130
|
+
title: 'Add user to group',
|
|
131
|
+
description: 'Add a user to a group',
|
|
132
|
+
inputSchema: {
|
|
133
|
+
groupUuid: z.string().describe('Group UUID'),
|
|
134
|
+
userUuid: z.string().describe('User UUID'),
|
|
135
|
+
},
|
|
136
|
+
annotations: WRITE_IDEMPOTENT,
|
|
137
|
+
},
|
|
138
|
+
wrapTool(
|
|
139
|
+
client,
|
|
140
|
+
(c) =>
|
|
141
|
+
async ({ groupUuid, userUuid }: { groupUuid: string; userUuid: string }) => {
|
|
142
|
+
await c.v1.groups.addUserToGroup(groupUuid, userUuid);
|
|
143
|
+
return {
|
|
144
|
+
content: [
|
|
145
|
+
{ type: 'text', text: `User ${userUuid} added to group ${groupUuid} successfully` },
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
},
|
|
149
|
+
),
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
registerToolSafe(
|
|
153
|
+
server,
|
|
154
|
+
'remove_user_from_group',
|
|
155
|
+
{
|
|
156
|
+
title: 'Remove user from group',
|
|
157
|
+
description: 'Remove a user from a group',
|
|
158
|
+
inputSchema: {
|
|
159
|
+
groupUuid: z.string().describe('Group UUID'),
|
|
160
|
+
userUuid: z.string().describe('User UUID'),
|
|
161
|
+
},
|
|
162
|
+
annotations: WRITE_DESTRUCTIVE,
|
|
163
|
+
},
|
|
164
|
+
wrapTool(
|
|
165
|
+
client,
|
|
166
|
+
(c) =>
|
|
167
|
+
async ({ groupUuid, userUuid }: { groupUuid: string; userUuid: string }) => {
|
|
168
|
+
await c.v1.groups.removeUserFromGroup(groupUuid, userUuid);
|
|
169
|
+
return {
|
|
170
|
+
content: [
|
|
171
|
+
{
|
|
172
|
+
type: 'text',
|
|
173
|
+
text: `User ${userUuid} removed from group ${groupUuid} successfully`,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
},
|
|
178
|
+
),
|
|
179
|
+
);
|
|
49
180
|
}
|
package/src/tools/spaces.ts
CHANGED
|
@@ -5,7 +5,14 @@
|
|
|
5
5
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
6
|
import type { LightdashClient } from '@lightdash-tools/client';
|
|
7
7
|
import { z } from 'zod';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
wrapTool,
|
|
10
|
+
registerToolSafe,
|
|
11
|
+
READ_ONLY_DEFAULT,
|
|
12
|
+
WRITE_IDEMPOTENT,
|
|
13
|
+
WRITE_DESTRUCTIVE,
|
|
14
|
+
} from './shared.js';
|
|
15
|
+
import { type SpaceMemberRole } from '@lightdash-tools/common';
|
|
9
16
|
|
|
10
17
|
export function registerSpaceTools(server: McpServer, client: LightdashClient): void {
|
|
11
18
|
registerToolSafe(
|
|
@@ -43,4 +50,168 @@ export function registerSpaceTools(server: McpServer, client: LightdashClient):
|
|
|
43
50
|
},
|
|
44
51
|
),
|
|
45
52
|
);
|
|
53
|
+
|
|
54
|
+
registerToolSafe(
|
|
55
|
+
server,
|
|
56
|
+
'grant_user_space_access',
|
|
57
|
+
{
|
|
58
|
+
title: 'Grant user access to space',
|
|
59
|
+
description: 'Grant a user access to a space',
|
|
60
|
+
inputSchema: {
|
|
61
|
+
projectUuid: z.string().describe('Project UUID'),
|
|
62
|
+
spaceUuid: z.string().describe('Space UUID'),
|
|
63
|
+
userUuid: z.string().describe('User UUID'),
|
|
64
|
+
spaceRole: z.enum(['viewer', 'editor', 'admin']).describe('Space role'),
|
|
65
|
+
},
|
|
66
|
+
annotations: WRITE_IDEMPOTENT,
|
|
67
|
+
},
|
|
68
|
+
wrapTool(
|
|
69
|
+
client,
|
|
70
|
+
(c) =>
|
|
71
|
+
async ({
|
|
72
|
+
projectUuid,
|
|
73
|
+
spaceUuid,
|
|
74
|
+
userUuid,
|
|
75
|
+
spaceRole,
|
|
76
|
+
}: {
|
|
77
|
+
projectUuid: string;
|
|
78
|
+
spaceUuid: string;
|
|
79
|
+
userUuid: string;
|
|
80
|
+
spaceRole: string;
|
|
81
|
+
}) => {
|
|
82
|
+
await c.v1.spaces.grantUserAccessToSpace(projectUuid, spaceUuid, {
|
|
83
|
+
userUuid,
|
|
84
|
+
spaceRole: spaceRole as SpaceMemberRole,
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
content: [
|
|
88
|
+
{
|
|
89
|
+
type: 'text',
|
|
90
|
+
text: `Successfully granted ${spaceRole} access to user ${userUuid} in space ${spaceUuid}`,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
},
|
|
95
|
+
),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
registerToolSafe(
|
|
99
|
+
server,
|
|
100
|
+
'revoke_user_space_access',
|
|
101
|
+
{
|
|
102
|
+
title: 'Revoke user access to space',
|
|
103
|
+
description: "Revoke a user's access to a space",
|
|
104
|
+
inputSchema: {
|
|
105
|
+
projectUuid: z.string().describe('Project UUID'),
|
|
106
|
+
spaceUuid: z.string().describe('Space UUID'),
|
|
107
|
+
userUuid: z.string().describe('User UUID'),
|
|
108
|
+
},
|
|
109
|
+
annotations: WRITE_DESTRUCTIVE,
|
|
110
|
+
},
|
|
111
|
+
wrapTool(
|
|
112
|
+
client,
|
|
113
|
+
(c) =>
|
|
114
|
+
async ({
|
|
115
|
+
projectUuid,
|
|
116
|
+
spaceUuid,
|
|
117
|
+
userUuid,
|
|
118
|
+
}: {
|
|
119
|
+
projectUuid: string;
|
|
120
|
+
spaceUuid: string;
|
|
121
|
+
userUuid: string;
|
|
122
|
+
}) => {
|
|
123
|
+
await c.v1.spaces.revokeUserAccessToSpace(projectUuid, spaceUuid, userUuid);
|
|
124
|
+
return {
|
|
125
|
+
content: [
|
|
126
|
+
{
|
|
127
|
+
type: 'text',
|
|
128
|
+
text: `Successfully revoked access for user ${userUuid} in space ${spaceUuid}`,
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
};
|
|
132
|
+
},
|
|
133
|
+
),
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
registerToolSafe(
|
|
137
|
+
server,
|
|
138
|
+
'grant_group_space_access',
|
|
139
|
+
{
|
|
140
|
+
title: 'Grant group access to space',
|
|
141
|
+
description: 'Grant a group access to a space',
|
|
142
|
+
inputSchema: {
|
|
143
|
+
projectUuid: z.string().describe('Project UUID'),
|
|
144
|
+
spaceUuid: z.string().describe('Space UUID'),
|
|
145
|
+
groupUuid: z.string().describe('Group UUID'),
|
|
146
|
+
spaceRole: z.enum(['viewer', 'editor', 'admin']).describe('Space role'),
|
|
147
|
+
},
|
|
148
|
+
annotations: WRITE_IDEMPOTENT,
|
|
149
|
+
},
|
|
150
|
+
wrapTool(
|
|
151
|
+
client,
|
|
152
|
+
(c) =>
|
|
153
|
+
async ({
|
|
154
|
+
projectUuid,
|
|
155
|
+
spaceUuid,
|
|
156
|
+
groupUuid,
|
|
157
|
+
spaceRole,
|
|
158
|
+
}: {
|
|
159
|
+
projectUuid: string;
|
|
160
|
+
spaceUuid: string;
|
|
161
|
+
groupUuid: string;
|
|
162
|
+
spaceRole: string;
|
|
163
|
+
}) => {
|
|
164
|
+
await c.v1.spaces.grantGroupAccessToSpace(projectUuid, spaceUuid, {
|
|
165
|
+
groupUuid,
|
|
166
|
+
spaceRole: spaceRole as SpaceMemberRole,
|
|
167
|
+
});
|
|
168
|
+
return {
|
|
169
|
+
content: [
|
|
170
|
+
{
|
|
171
|
+
type: 'text',
|
|
172
|
+
text: `Successfully granted ${spaceRole} access to group ${groupUuid} in space ${spaceUuid}`,
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
};
|
|
176
|
+
},
|
|
177
|
+
),
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
registerToolSafe(
|
|
181
|
+
server,
|
|
182
|
+
'revoke_group_space_access',
|
|
183
|
+
{
|
|
184
|
+
title: 'Revoke group access to space',
|
|
185
|
+
description: "Revoke a group's access to a space",
|
|
186
|
+
inputSchema: {
|
|
187
|
+
projectUuid: z.string().describe('Project UUID'),
|
|
188
|
+
spaceUuid: z.string().describe('Space UUID'),
|
|
189
|
+
groupUuid: z.string().describe('Group UUID'),
|
|
190
|
+
},
|
|
191
|
+
annotations: WRITE_DESTRUCTIVE,
|
|
192
|
+
},
|
|
193
|
+
wrapTool(
|
|
194
|
+
client,
|
|
195
|
+
(c) =>
|
|
196
|
+
async ({
|
|
197
|
+
projectUuid,
|
|
198
|
+
spaceUuid,
|
|
199
|
+
groupUuid,
|
|
200
|
+
}: {
|
|
201
|
+
projectUuid: string;
|
|
202
|
+
spaceUuid: string;
|
|
203
|
+
groupUuid: string;
|
|
204
|
+
}) => {
|
|
205
|
+
await c.v1.spaces.revokeGroupAccessToSpace(projectUuid, spaceUuid, groupUuid);
|
|
206
|
+
return {
|
|
207
|
+
content: [
|
|
208
|
+
{
|
|
209
|
+
type: 'text',
|
|
210
|
+
text: `Successfully revoked access for group ${groupUuid} in space ${spaceUuid}`,
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
};
|
|
214
|
+
},
|
|
215
|
+
),
|
|
216
|
+
);
|
|
46
217
|
}
|