@pitcher/cli-scripts 2.8.0 → 2.10.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 +56 -1
- package/dist/index.js +2 -0
- package/dist/src/commands/canvases.js +11 -8
- package/dist/src/commands/dsrLanding.d.ts +2 -0
- package/dist/src/commands/dsrLanding.js +18 -10
- package/dist/src/commands/emailTemplate.d.ts +1 -0
- package/dist/src/commands/emailTemplate.js +8 -4
- package/dist/src/commands/mcp.d.ts +2 -0
- package/dist/src/commands/mcp.js +18 -0
- package/dist/src/core/readInput.d.ts +2 -0
- package/dist/src/core/readInput.js +24 -0
- package/dist/src/mcp/bundled.d.ts +4 -0
- package/dist/src/mcp/bundled.js +25 -0
- package/dist/src/mcp/env.d.ts +7 -0
- package/dist/src/mcp/env.js +13 -0
- package/dist/src/mcp/prompts/dsrLanding.d.ts +2 -0
- package/dist/src/mcp/prompts/dsrLanding.js +40 -0
- package/dist/src/mcp/prompts/emailTemplate.d.ts +2 -0
- package/dist/src/mcp/prompts/emailTemplate.js +34 -0
- package/dist/src/mcp/prompts/registry.d.ts +2 -0
- package/dist/src/mcp/prompts/registry.js +4 -0
- package/dist/src/mcp/prompts/shared.d.ts +2 -0
- package/dist/src/mcp/prompts/shared.js +26 -0
- package/dist/src/mcp/prompts/types.d.ts +9 -0
- package/dist/src/mcp/prompts/types.js +1 -0
- package/dist/src/mcp/registry.d.ts +2 -0
- package/dist/src/mcp/registry.js +46 -0
- package/dist/src/mcp/resources/contentDesign.d.ts +3 -0
- package/dist/src/mcp/resources/contentDesign.js +62 -0
- package/dist/src/mcp/resources/registry.d.ts +2 -0
- package/dist/src/mcp/resources/registry.js +3 -0
- package/dist/src/mcp/resources/types.d.ts +8 -0
- package/dist/src/mcp/resources/types.js +1 -0
- package/dist/src/mcp/result.d.ts +14 -0
- package/dist/src/mcp/result.js +80 -0
- package/dist/src/mcp/serve.d.ts +4 -0
- package/dist/src/mcp/serve.js +18 -0
- package/dist/src/mcp/server.d.ts +6 -0
- package/dist/src/mcp/server.js +88 -0
- package/dist/src/mcp/tools/analytics.d.ts +2 -0
- package/dist/src/mcp/tools/analytics.js +20 -0
- package/dist/src/mcp/tools/announcements.d.ts +2 -0
- package/dist/src/mcp/tools/announcements.js +32 -0
- package/dist/src/mcp/tools/canvases.d.ts +2 -0
- package/dist/src/mcp/tools/canvases.js +97 -0
- package/dist/src/mcp/tools/devSync.d.ts +2 -0
- package/dist/src/mcp/tools/devSync.js +53 -0
- package/dist/src/mcp/tools/dsr.d.ts +2 -0
- package/dist/src/mcp/tools/dsr.js +47 -0
- package/dist/src/mcp/tools/dsrLanding.d.ts +2 -0
- package/dist/src/mcp/tools/dsrLanding.js +53 -0
- package/dist/src/mcp/tools/emailTemplate.d.ts +2 -0
- package/dist/src/mcp/tools/emailTemplate.js +51 -0
- package/dist/src/mcp/tools/files.d.ts +2 -0
- package/dist/src/mcp/tools/files.js +65 -0
- package/dist/src/mcp/tools/folders.d.ts +2 -0
- package/dist/src/mcp/tools/folders.js +56 -0
- package/dist/src/mcp/tools/groups.d.ts +2 -0
- package/dist/src/mcp/tools/groups.js +60 -0
- package/dist/src/mcp/tools/instances.d.ts +2 -0
- package/dist/src/mcp/tools/instances.js +82 -0
- package/dist/src/mcp/tools/invitations.d.ts +2 -0
- package/dist/src/mcp/tools/invitations.js +23 -0
- package/dist/src/mcp/tools/memberships.d.ts +2 -0
- package/dist/src/mcp/tools/memberships.js +47 -0
- package/dist/src/mcp/tools/metadataTemplate.d.ts +2 -0
- package/dist/src/mcp/tools/metadataTemplate.js +42 -0
- package/dist/src/mcp/tools/org.d.ts +2 -0
- package/dist/src/mcp/tools/org.js +12 -0
- package/dist/src/mcp/tools/publishApp.d.ts +2 -0
- package/dist/src/mcp/tools/publishApp.js +39 -0
- package/dist/src/mcp/tools/roles.d.ts +2 -0
- package/dist/src/mcp/tools/roles.js +15 -0
- package/dist/src/mcp/tools/search.d.ts +2 -0
- package/dist/src/mcp/tools/search.js +16 -0
- package/dist/src/mcp/tools/sharedLinks.d.ts +2 -0
- package/dist/src/mcp/tools/sharedLinks.js +27 -0
- package/dist/src/mcp/tools/tags.d.ts +2 -0
- package/dist/src/mcp/tools/tags.js +20 -0
- package/dist/src/mcp/tools/themes.d.ts +2 -0
- package/dist/src/mcp/tools/themes.js +28 -0
- package/dist/src/mcp/tools/types.d.ts +15 -0
- package/dist/src/mcp/tools/types.js +1 -0
- package/dist/src/mcp/tools/users.d.ts +2 -0
- package/dist/src/mcp/tools/users.js +31 -0
- package/package.json +9 -3
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runFilesList, runFilesGet, runFilesCreate, runFilesUpdate } from '../../commands/files.js';
|
|
3
|
+
export const filesTools = [
|
|
4
|
+
{
|
|
5
|
+
name: 'pitcher_files_list',
|
|
6
|
+
title: 'List files',
|
|
7
|
+
description: 'List content files in an instance. Filter by tags or specific IDs.',
|
|
8
|
+
inputShape: {
|
|
9
|
+
instanceId: z.string().describe('Instance ID (required)'),
|
|
10
|
+
idIn: z.string().optional().describe('Comma-separated file IDs'),
|
|
11
|
+
tags: z.string().optional().describe('Comma-separated tags'),
|
|
12
|
+
page: z.number().int().optional(),
|
|
13
|
+
pageSize: z.number().int().optional(),
|
|
14
|
+
},
|
|
15
|
+
run: runFilesList,
|
|
16
|
+
readOnly: true,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'pitcher_files_get',
|
|
20
|
+
title: 'Get a file',
|
|
21
|
+
description: 'Retrieve a single file by its ID.',
|
|
22
|
+
inputShape: { id: z.string().describe('File ID') },
|
|
23
|
+
run: runFilesGet,
|
|
24
|
+
readOnly: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'pitcher_files_create',
|
|
28
|
+
title: 'Create a file',
|
|
29
|
+
description: 'Create a content file in an instance, from a local file path (on the server host) or a source URL. Additive.',
|
|
30
|
+
inputShape: {
|
|
31
|
+
instanceId: z.string().describe('Instance ID (required)'),
|
|
32
|
+
name: z.string().optional().describe('File name'),
|
|
33
|
+
folderId: z.string().optional().describe('Destination folder'),
|
|
34
|
+
filePath: z.string().optional().describe('Local file path to upload (on the MCP server host)'),
|
|
35
|
+
sourceUrl: z.string().optional().describe('Link/WEB file source URL'),
|
|
36
|
+
accessType: z.enum(['public', 'restricted', 'personal']).optional(),
|
|
37
|
+
tags: z.string().optional().describe('Comma-separated tags'),
|
|
38
|
+
metadata: z.string().optional().describe('metadata JSON object as a string'),
|
|
39
|
+
appMetadata: z.string().optional().describe('app_metadata JSON object as a string'),
|
|
40
|
+
},
|
|
41
|
+
run: runFilesCreate,
|
|
42
|
+
readOnly: false,
|
|
43
|
+
write: true,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'pitcher_files_update',
|
|
47
|
+
title: 'Update a file',
|
|
48
|
+
description: 'Update a file by ID (name, folder, access, tags, metadata). filePath or sourceUrl replaces/overwrites the file binary; metadata is deep-merged.',
|
|
49
|
+
inputShape: {
|
|
50
|
+
id: z.string().describe('File ID'),
|
|
51
|
+
instanceId: z.string().optional().describe('Instance ID (required only with filePath)'),
|
|
52
|
+
name: z.string().optional(),
|
|
53
|
+
folderId: z.string().optional(),
|
|
54
|
+
filePath: z.string().optional().describe('Local file path to replace the binary (on the MCP server host)'),
|
|
55
|
+
sourceUrl: z.string().optional(),
|
|
56
|
+
accessType: z.enum(['public', 'restricted', 'personal']).optional(),
|
|
57
|
+
tags: z.string().optional().describe('Comma-separated tags'),
|
|
58
|
+
metadata: z.string().optional().describe('metadata JSON object as a string (deep-merged)'),
|
|
59
|
+
appMetadata: z.string().optional().describe('app_metadata JSON object as a string (deep-merged)'),
|
|
60
|
+
},
|
|
61
|
+
run: runFilesUpdate,
|
|
62
|
+
readOnly: false,
|
|
63
|
+
write: true,
|
|
64
|
+
},
|
|
65
|
+
];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runFoldersList, runFoldersGet, runFoldersCreate, runFoldersUpdate } from '../../commands/folders.js';
|
|
3
|
+
export const foldersTools = [
|
|
4
|
+
{
|
|
5
|
+
name: 'pitcher_folders_list',
|
|
6
|
+
title: 'List folders',
|
|
7
|
+
description: 'List folders in an instance. Use to discover folder IDs before creating content or browsing structure.',
|
|
8
|
+
inputShape: {
|
|
9
|
+
instanceId: z.string().describe('Instance ID (required)'),
|
|
10
|
+
page: z.number().int().optional(),
|
|
11
|
+
pageSize: z.number().int().optional().describe('Page size (max 500)'),
|
|
12
|
+
},
|
|
13
|
+
run: runFoldersList,
|
|
14
|
+
readOnly: true,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'pitcher_folders_get',
|
|
18
|
+
title: 'Get a folder',
|
|
19
|
+
description: 'Retrieve a single folder by its ID, or the instance root folder via root + instanceId.',
|
|
20
|
+
inputShape: {
|
|
21
|
+
id: z.string().optional().describe('Folder ID (omit and set root=true for the instance root)'),
|
|
22
|
+
root: z.boolean().optional().describe('Fetch the instance root folder'),
|
|
23
|
+
instanceId: z.string().optional().describe('Instance ID (required with root)'),
|
|
24
|
+
},
|
|
25
|
+
run: runFoldersGet,
|
|
26
|
+
readOnly: true,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'pitcher_folders_create',
|
|
30
|
+
title: 'Create a folder',
|
|
31
|
+
description: 'Create a folder under a parent folder in an instance. Additive.',
|
|
32
|
+
inputShape: {
|
|
33
|
+
name: z.string().describe('Folder name (required)'),
|
|
34
|
+
parentFolderId: z.string().describe('Parent folder ID (required)'),
|
|
35
|
+
accessType: z.enum(['public', 'restricted', 'personal']).optional(),
|
|
36
|
+
rules: z.string().optional().describe('Smart-folder rules JSON array as a string'),
|
|
37
|
+
},
|
|
38
|
+
run: runFoldersCreate,
|
|
39
|
+
readOnly: false,
|
|
40
|
+
write: true,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'pitcher_folders_update',
|
|
44
|
+
title: 'Update a folder',
|
|
45
|
+
description: 'Update an existing folder by ID (name, access type, or smart-folder rules; rules replace existing).',
|
|
46
|
+
inputShape: {
|
|
47
|
+
id: z.string().describe('Folder ID'),
|
|
48
|
+
name: z.string().optional().describe('Folder name'),
|
|
49
|
+
accessType: z.enum(['public', 'restricted', 'personal']).optional(),
|
|
50
|
+
rules: z.string().optional().describe('Smart-folder rules JSON array as a string (replaces existing)'),
|
|
51
|
+
},
|
|
52
|
+
run: runFoldersUpdate,
|
|
53
|
+
readOnly: false,
|
|
54
|
+
write: true,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runGroupsList, runGroupsGet, runGroupsCreate, runGroupsAddUser, runGroupsListUsers, } from '../../commands/groups.js';
|
|
3
|
+
export const groupsTools = [
|
|
4
|
+
{
|
|
5
|
+
name: 'pitcher_groups_list',
|
|
6
|
+
title: 'List content-distribution groups',
|
|
7
|
+
description: 'List content-distribution groups. Filter by instance.',
|
|
8
|
+
inputShape: {
|
|
9
|
+
instanceId: z.string().optional().describe('Filter by instance'),
|
|
10
|
+
page: z.number().int().optional().describe('Page number'),
|
|
11
|
+
pageSize: z.number().int().optional().describe('Page size (max 500)'),
|
|
12
|
+
},
|
|
13
|
+
run: runGroupsList,
|
|
14
|
+
readOnly: true,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'pitcher_groups_get',
|
|
18
|
+
title: 'Get a group',
|
|
19
|
+
description: 'Retrieve a single content-distribution group by its ID.',
|
|
20
|
+
inputShape: { id: z.string().describe('Group ID') },
|
|
21
|
+
run: runGroupsGet,
|
|
22
|
+
readOnly: true,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'pitcher_groups_create',
|
|
26
|
+
title: 'Create a group',
|
|
27
|
+
description: 'Create a content-distribution group in an instance. Additive.',
|
|
28
|
+
inputShape: {
|
|
29
|
+
instanceId: z.string().describe('Instance ID (required)'),
|
|
30
|
+
name: z.string().describe('Group name (required)'),
|
|
31
|
+
},
|
|
32
|
+
run: runGroupsCreate,
|
|
33
|
+
readOnly: false,
|
|
34
|
+
write: true,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'pitcher_groups_add_user',
|
|
38
|
+
title: 'Add a user to a group',
|
|
39
|
+
description: 'Add a user to a content-distribution group. Rejected on auto-login-managed groups.',
|
|
40
|
+
inputShape: {
|
|
41
|
+
groupId: z.string().describe('Group ID (required)'),
|
|
42
|
+
userId: z.string().describe('User ID (integer, required)'),
|
|
43
|
+
},
|
|
44
|
+
run: runGroupsAddUser,
|
|
45
|
+
readOnly: false,
|
|
46
|
+
write: true,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'pitcher_groups_list_users',
|
|
50
|
+
title: "List a group's members",
|
|
51
|
+
description: "List a content-distribution group's members.",
|
|
52
|
+
inputShape: {
|
|
53
|
+
groupId: z.string().describe('Group whose members to list (required)'),
|
|
54
|
+
page: z.number().int().optional().describe('Page number'),
|
|
55
|
+
pageSize: z.number().int().optional().describe('Page size (max 500)'),
|
|
56
|
+
},
|
|
57
|
+
run: runGroupsListUsers,
|
|
58
|
+
readOnly: true,
|
|
59
|
+
},
|
|
60
|
+
];
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runInstancesList, runInstancesInfo } from '../../commands/instances.js';
|
|
3
|
+
// An instance's settings.translation_overrides (keyed by language, using Pitcher's UI keys) lets an
|
|
4
|
+
// admin relabel the canvas types in their UI — e.g. section → "Slide", canvas → "PitchDeck". Map those
|
|
5
|
+
// onto the canonical canvas `type` names so the model can address the user in each instance's own
|
|
6
|
+
// vocabulary while still reasoning/filtering on the stable `type`. Zero extra calls — the overrides are
|
|
7
|
+
// already in the instance payload.
|
|
8
|
+
function terminologyFromOverrides(overrides) {
|
|
9
|
+
var _a;
|
|
10
|
+
if (!overrides || typeof overrides !== 'object')
|
|
11
|
+
return undefined;
|
|
12
|
+
const out = {};
|
|
13
|
+
for (const [lang, raw] of Object.entries(overrides)) {
|
|
14
|
+
if (!raw || typeof raw !== 'object')
|
|
15
|
+
continue;
|
|
16
|
+
// Fold keys to lowercase: the platform's override engine matches dotless keys
|
|
17
|
+
// case-insensitively (RegExp('\\b'+key+'\\b','gi') in canvas-ui translations.ts), and real
|
|
18
|
+
// instances do use e.g. `CANVAS`. First occurrence wins on a (theoretical) case collision.
|
|
19
|
+
const m = {};
|
|
20
|
+
for (const [k, v] of Object.entries(raw))
|
|
21
|
+
m[_a = k.toLowerCase()] ?? (m[_a] = v);
|
|
22
|
+
const labels = {};
|
|
23
|
+
const put = (type, ...keys) => {
|
|
24
|
+
for (const k of keys) {
|
|
25
|
+
const v = m[k];
|
|
26
|
+
if (typeof v === 'string' && v) {
|
|
27
|
+
labels[type] = v;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
put('presentation', 'canvas');
|
|
33
|
+
put('section', 'section');
|
|
34
|
+
put('template', 'nav.templates', 'navigation.templates');
|
|
35
|
+
put('block', 'nav.blocks', 'navigation.blocks');
|
|
36
|
+
if (Object.keys(labels).length)
|
|
37
|
+
out[lang] = labels;
|
|
38
|
+
}
|
|
39
|
+
return Object.keys(out).length ? out : undefined;
|
|
40
|
+
}
|
|
41
|
+
// Wrapper: attach a normalized `terminology` map derived from the instance's translation_overrides,
|
|
42
|
+
// so the model knows what this customer calls each canvas type. `wraps` keeps the coverage guard happy.
|
|
43
|
+
async function runInstancesInfoWithTerminology(opts, deps) {
|
|
44
|
+
const env = await runInstancesInfo(opts, deps);
|
|
45
|
+
if (!env.ok || !env.data || typeof env.data !== 'object')
|
|
46
|
+
return env;
|
|
47
|
+
const data = env.data;
|
|
48
|
+
const settings = data.settings;
|
|
49
|
+
const terminology = terminologyFromOverrides(settings?.translation_overrides);
|
|
50
|
+
if (!terminology)
|
|
51
|
+
return env;
|
|
52
|
+
return { ...env, data: { ...data, terminology } };
|
|
53
|
+
}
|
|
54
|
+
export const instancesTools = [
|
|
55
|
+
{
|
|
56
|
+
name: 'pitcher_instances_list',
|
|
57
|
+
title: 'List instances',
|
|
58
|
+
description: 'Discover Pitcher instances in the org. Use to resolve instance names to instance IDs.' +
|
|
59
|
+
' Output may include raw instance settings/metadata (potentially integration credentials) - treat as sensitive.',
|
|
60
|
+
inputShape: {
|
|
61
|
+
region: z.string().optional().describe('Filter by region'),
|
|
62
|
+
storageRegion: z.string().optional().describe('Filter by storage region'),
|
|
63
|
+
environment: z.string().optional().describe('Filter by environment'),
|
|
64
|
+
page: z.number().int().optional(),
|
|
65
|
+
pageSize: z.number().int().optional().describe('Page size (max 500)'),
|
|
66
|
+
},
|
|
67
|
+
run: runInstancesList,
|
|
68
|
+
readOnly: true,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'pitcher_instances_info',
|
|
72
|
+
title: 'Get an instance',
|
|
73
|
+
description: 'Retrieve details for a single instance by its ID. If the instance renames canvas types in its UI, a ' +
|
|
74
|
+
'normalized `terminology` map is included ({ <lang>: { presentation, section, template, block } }, e.g. ' +
|
|
75
|
+
'section → "Slide") — use those labels when addressing the user, but keep filtering/reasoning on the canonical ' +
|
|
76
|
+
'canvas `type`. Output may include raw instance settings/metadata (potentially integration credentials) - treat as sensitive.',
|
|
77
|
+
inputShape: { id: z.string().describe('Instance ID') },
|
|
78
|
+
run: runInstancesInfoWithTerminology,
|
|
79
|
+
wraps: runInstancesInfo,
|
|
80
|
+
readOnly: true,
|
|
81
|
+
},
|
|
82
|
+
];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runInvitationsList, runInvitationsGet } from '../../commands/invitations.js';
|
|
3
|
+
export const invitationsTools = [
|
|
4
|
+
{
|
|
5
|
+
name: 'pitcher_invitations_list',
|
|
6
|
+
title: 'List invitations',
|
|
7
|
+
description: 'List pending user invitations in the org.',
|
|
8
|
+
inputShape: {
|
|
9
|
+
page: z.number().int().optional().describe('Page number'),
|
|
10
|
+
pageSize: z.number().int().optional().describe('Page size (max 500)'),
|
|
11
|
+
},
|
|
12
|
+
run: runInvitationsList,
|
|
13
|
+
readOnly: true,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'pitcher_invitations_get',
|
|
17
|
+
title: 'Get an invitation',
|
|
18
|
+
description: 'Retrieve a single pending invitation by ID.',
|
|
19
|
+
inputShape: { id: z.string().describe('Invitation ID') },
|
|
20
|
+
run: runInvitationsGet,
|
|
21
|
+
readOnly: true,
|
|
22
|
+
},
|
|
23
|
+
];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runMembershipsList, runMembershipsAdd, runMembershipsSetRole } from '../../commands/memberships.js';
|
|
3
|
+
export const membershipsTools = [
|
|
4
|
+
{
|
|
5
|
+
name: 'pitcher_memberships_list',
|
|
6
|
+
title: 'List instance memberships',
|
|
7
|
+
description: 'List instance memberships. Filter by instance or user to discover membership IDs before set-role.',
|
|
8
|
+
inputShape: {
|
|
9
|
+
instanceId: z.string().optional().describe('Filter by instance'),
|
|
10
|
+
userId: z.string().optional().describe('Filter by user (integer id)'),
|
|
11
|
+
page: z.number().int().optional().describe('Page number'),
|
|
12
|
+
pageSize: z.number().int().optional().describe('Page size (max 500)'),
|
|
13
|
+
},
|
|
14
|
+
run: runMembershipsList,
|
|
15
|
+
readOnly: true,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'pitcher_memberships_add',
|
|
19
|
+
title: 'Add a member',
|
|
20
|
+
description: "Add a user to an instance as 'member' (role is always 'member' — this endpoint never accepts a " +
|
|
21
|
+
"caller-supplied role). Use pitcher_memberships_set_role to change the role afterward.",
|
|
22
|
+
inputShape: {
|
|
23
|
+
instanceId: z.string().describe('Instance ID (required)'),
|
|
24
|
+
userId: z.string().describe('User ID (integer, required)'),
|
|
25
|
+
},
|
|
26
|
+
run: runMembershipsAdd,
|
|
27
|
+
readOnly: false,
|
|
28
|
+
write: true,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'pitcher_memberships_set_role',
|
|
32
|
+
title: 'Set a membership role',
|
|
33
|
+
description: "Change a membership's role via the validating next-core endpoint. Requires an org-admin key. " +
|
|
34
|
+
"--role is the SHORT role name (e.g. 'editor') from pitcher_roles_list, not a prefixed key.",
|
|
35
|
+
inputShape: {
|
|
36
|
+
membershipId: z.string().describe('Membership row ID (integer, required)'),
|
|
37
|
+
role: z.string().describe('Short role name, e.g. editor (required)'),
|
|
38
|
+
scope: z
|
|
39
|
+
.enum(['instance', 'organization'])
|
|
40
|
+
.optional()
|
|
41
|
+
.describe('Scope of the role assignment (default instance)'),
|
|
42
|
+
},
|
|
43
|
+
run: runMembershipsSetRole,
|
|
44
|
+
readOnly: false,
|
|
45
|
+
write: true,
|
|
46
|
+
},
|
|
47
|
+
];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runMetadataTemplateList, runMetadataTemplateGet, runMetadataTemplateUpsert, } from '../../commands/metadataTemplate.js';
|
|
3
|
+
export const metadataTemplateTools = [
|
|
4
|
+
{
|
|
5
|
+
name: 'pitcher_metadata_template_list',
|
|
6
|
+
title: 'List metadata templates',
|
|
7
|
+
description: "List an instance's metadata-field schema(s) (metadata templates).",
|
|
8
|
+
inputShape: {
|
|
9
|
+
instanceId: z.string().describe('Instance ID (required)'),
|
|
10
|
+
page: z.number().int().optional().describe('Page number'),
|
|
11
|
+
pageSize: z.number().int().optional().describe('Page size (max 500)'),
|
|
12
|
+
},
|
|
13
|
+
run: runMetadataTemplateList,
|
|
14
|
+
readOnly: true,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'pitcher_metadata_template_get',
|
|
18
|
+
title: 'Get a metadata template',
|
|
19
|
+
description: 'Retrieve a single metadata template by its ID (ULID).',
|
|
20
|
+
inputShape: { id: z.string().describe('Metadata template ID (ULID)') },
|
|
21
|
+
run: runMetadataTemplateGet,
|
|
22
|
+
readOnly: true,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'pitcher_metadata_template_upsert',
|
|
26
|
+
title: 'Upsert a metadata template',
|
|
27
|
+
description: "Upsert an instance's metadata-field schema. Merges the incoming sections by section 'label' — a " +
|
|
28
|
+
'section whose label matches an existing one is replaced, other sections are preserved. Cannot remove ' +
|
|
29
|
+
'a section or field. Pass exactly one of sections or sectionsFile. Requires an instance- or org-admin key.',
|
|
30
|
+
inputShape: {
|
|
31
|
+
instanceId: z.string().describe('Instance ID (required)'),
|
|
32
|
+
sections: z.string().optional().describe('Sections JSON array (inline)'),
|
|
33
|
+
sectionsFile: z
|
|
34
|
+
.string()
|
|
35
|
+
.optional()
|
|
36
|
+
.describe('Path to a JSON file (on the MCP server host) with the sections array'),
|
|
37
|
+
},
|
|
38
|
+
run: runMetadataTemplateUpsert,
|
|
39
|
+
readOnly: false,
|
|
40
|
+
write: true,
|
|
41
|
+
},
|
|
42
|
+
];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { runOrgGet } from '../../commands/org.js';
|
|
2
|
+
export const orgTools = [
|
|
3
|
+
{
|
|
4
|
+
name: 'pitcher_org_get',
|
|
5
|
+
title: 'Get the organization',
|
|
6
|
+
description: 'Retrieve the organization the API key belongs to. Response may include raw settings/metadata ' +
|
|
7
|
+
'(potentially integration credentials) — treat output as sensitive.',
|
|
8
|
+
inputShape: {},
|
|
9
|
+
run: runOrgGet,
|
|
10
|
+
readOnly: true,
|
|
11
|
+
},
|
|
12
|
+
];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runPublishApp } from '../../commands/publishApp.js';
|
|
3
|
+
// Narrow individual injected/validated values (the MCP zod schema already guarantees the runtime
|
|
4
|
+
// type) instead of casting the whole opts blob — same approach as the devSync wrappers.
|
|
5
|
+
const asString = (v) => (typeof v === 'string' ? v : undefined);
|
|
6
|
+
const asBool = (v) => (typeof v === 'boolean' ? v : undefined);
|
|
7
|
+
export const publishAppTools = [
|
|
8
|
+
{
|
|
9
|
+
name: 'pitcher_publish_app',
|
|
10
|
+
title: 'Publish an app release',
|
|
11
|
+
description: 'Zip a local app folder (on the MCP server host) and publish it as a new app release to the org, ' +
|
|
12
|
+
'optionally installing it to specific instances or all instances of an environment afterward. ' +
|
|
13
|
+
'Consequential: this creates a live, org-visible app release — use dryRun to preview first. ' +
|
|
14
|
+
'Re-publishing an already-existing version is a no-op (returns ok with a warning), not a failure. ' +
|
|
15
|
+
'Publish targets the org resolved from NG_ORG; the injected NG_URL is not used as the publish endpoint.',
|
|
16
|
+
inputShape: {
|
|
17
|
+
folder: z.string().optional().describe('Local folder to zip and publish (defaults to the MCP server cwd)'),
|
|
18
|
+
incrementVersion: z.boolean().optional().describe('Bump the version in app.json before publishing'),
|
|
19
|
+
dryRun: z.boolean().optional().describe('Preview the publish (version, target) without publishing anything'),
|
|
20
|
+
installTo: z.string().optional().describe('Comma-separated instance IDs to install the app to after publishing'),
|
|
21
|
+
installToEnvName: z.string().optional().describe('Environment name (e.g. "test") to install the app to after publishing'),
|
|
22
|
+
},
|
|
23
|
+
// runPublishApp overloads `url` as BOTH origin and publish endpoint; the server injects NG_URL into
|
|
24
|
+
// every tool, so forward only apiKey + org (never url) plus this tool's own inputs.
|
|
25
|
+
run: (opts) => runPublishApp({
|
|
26
|
+
folder: asString(opts.folder),
|
|
27
|
+
incrementVersion: asBool(opts.incrementVersion),
|
|
28
|
+
dryRun: asBool(opts.dryRun),
|
|
29
|
+
installTo: asString(opts.installTo),
|
|
30
|
+
installToEnvName: asString(opts.installToEnvName),
|
|
31
|
+
apiKey: opts.apiKey,
|
|
32
|
+
org: opts.org,
|
|
33
|
+
}),
|
|
34
|
+
wraps: runPublishApp,
|
|
35
|
+
readOnly: false,
|
|
36
|
+
write: true,
|
|
37
|
+
alwaysDestructive: true,
|
|
38
|
+
},
|
|
39
|
+
];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runRolesList } from '../../commands/roles.js';
|
|
3
|
+
export const rolesTools = [
|
|
4
|
+
{
|
|
5
|
+
name: 'pitcher_roles_list',
|
|
6
|
+
title: 'List roles',
|
|
7
|
+
description: 'List the org role set (system + custom roles) — use to discover valid short role names ' +
|
|
8
|
+
'before setting a membership role. Needs an org-admin key.',
|
|
9
|
+
inputShape: {
|
|
10
|
+
scope: z.enum(['instance', 'organization']).optional().describe('Filter by scope'),
|
|
11
|
+
},
|
|
12
|
+
run: runRolesList,
|
|
13
|
+
readOnly: true,
|
|
14
|
+
},
|
|
15
|
+
];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runSearch } from '../../commands/search.js';
|
|
3
|
+
export const searchTools = [
|
|
4
|
+
{
|
|
5
|
+
name: 'pitcher_search',
|
|
6
|
+
title: 'Search content',
|
|
7
|
+
description: 'Cross-type ranked search across an instance (files, canvases, users, apps). Use to find content by keyword when the ID is unknown.',
|
|
8
|
+
inputShape: {
|
|
9
|
+
instanceId: z.string().describe('Instance ID (required)'),
|
|
10
|
+
query: z.string().describe('Search query (required)'),
|
|
11
|
+
includeExpired: z.boolean().optional().describe('Include expired content'),
|
|
12
|
+
},
|
|
13
|
+
run: runSearch,
|
|
14
|
+
readOnly: true,
|
|
15
|
+
},
|
|
16
|
+
];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runSharedLinksCreate, runSharedLinksGet } from '../../commands/sharedLinks.js';
|
|
3
|
+
export const sharedLinksTools = [
|
|
4
|
+
{
|
|
5
|
+
name: 'pitcher_shared_links_create',
|
|
6
|
+
title: 'Create a shared link',
|
|
7
|
+
description: 'Create a share link (short_url) for a canvas or a file. Pass exactly one of canvasId or fileId. Additive.',
|
|
8
|
+
inputShape: {
|
|
9
|
+
canvasId: z.string().optional().describe('Canvas to share (exactly one of canvasId/fileId is required)'),
|
|
10
|
+
fileId: z.string().optional().describe('File to share (exactly one of canvasId/fileId is required)'),
|
|
11
|
+
},
|
|
12
|
+
run: runSharedLinksCreate,
|
|
13
|
+
readOnly: false,
|
|
14
|
+
write: true,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'pitcher_shared_links_get',
|
|
18
|
+
title: 'Get a shared link',
|
|
19
|
+
description: 'Retrieve the existing share link for a canvas or a file. Pass exactly one of canvasId or fileId.',
|
|
20
|
+
inputShape: {
|
|
21
|
+
canvasId: z.string().optional().describe('Canvas whose link to fetch (exactly one of canvasId/fileId is required)'),
|
|
22
|
+
fileId: z.string().optional().describe('File whose link to fetch (exactly one of canvasId/fileId is required)'),
|
|
23
|
+
},
|
|
24
|
+
run: runSharedLinksGet,
|
|
25
|
+
readOnly: true,
|
|
26
|
+
},
|
|
27
|
+
];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runTagsList } from '../../commands/tags.js';
|
|
3
|
+
export const tagsTools = [
|
|
4
|
+
{
|
|
5
|
+
name: 'pitcher_tags_list',
|
|
6
|
+
title: 'List tags',
|
|
7
|
+
description: 'List tags in an instance matching a search term (at least 3 characters). Use to discover tag values before filtering files/canvases.',
|
|
8
|
+
inputShape: {
|
|
9
|
+
instanceId: z.string().describe('Instance ID (required)'),
|
|
10
|
+
search: z.string().min(3).describe('Search term (required, at least 3 characters)'),
|
|
11
|
+
type: z.enum(['files', 'canvases']).optional(),
|
|
12
|
+
canvasType: z.string().optional().describe('Canvas type filter'),
|
|
13
|
+
includeHidden: z.boolean().optional().describe('Include hidden tags'),
|
|
14
|
+
page: z.number().int().optional(),
|
|
15
|
+
pageSize: z.number().int().optional().describe('Page size (max 500)'),
|
|
16
|
+
},
|
|
17
|
+
run: runTagsList,
|
|
18
|
+
readOnly: true,
|
|
19
|
+
},
|
|
20
|
+
];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runThemesList, runThemesGet } from '../../commands/themes.js';
|
|
3
|
+
export const themesTools = [
|
|
4
|
+
{
|
|
5
|
+
name: 'pitcher_themes_list',
|
|
6
|
+
title: 'List themes',
|
|
7
|
+
description: 'List canvas/branding themes (colors, fonts, assets) in the org. Omit instanceId to see all ' +
|
|
8
|
+
'org-level and instance themes; set it to narrow to themes bound to that instance.',
|
|
9
|
+
inputShape: {
|
|
10
|
+
instanceId: z
|
|
11
|
+
.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe('Filter to themes bound to this instance (excludes org-level themes)'),
|
|
14
|
+
withUsage: z.boolean().optional().describe('Include a per-theme count of canvases using it'),
|
|
15
|
+
withCanvasIds: z.boolean().optional().describe('Include the canvas ids using each theme'),
|
|
16
|
+
},
|
|
17
|
+
run: runThemesList,
|
|
18
|
+
readOnly: true,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'pitcher_themes_get',
|
|
22
|
+
title: 'Get a theme',
|
|
23
|
+
description: 'Retrieve a single theme by its ID.',
|
|
24
|
+
inputShape: { id: z.string().describe('Theme ID') },
|
|
25
|
+
run: runThemesGet,
|
|
26
|
+
readOnly: true,
|
|
27
|
+
},
|
|
28
|
+
];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { Envelope } from '../../core/envelope.js';
|
|
3
|
+
import type { CommonOpts } from '../../core/http.js';
|
|
4
|
+
export type InjectedAuth = Pick<CommonOpts, 'apiKey' | 'org' | 'url'>;
|
|
5
|
+
export interface ToolDescriptor {
|
|
6
|
+
name: string;
|
|
7
|
+
title: string;
|
|
8
|
+
description: string;
|
|
9
|
+
inputShape: z.ZodRawShape;
|
|
10
|
+
run: (opts: Record<string, unknown> & InjectedAuth, deps?: any) => Promise<Envelope<unknown>>;
|
|
11
|
+
wraps?: (...a: any[]) => unknown;
|
|
12
|
+
readOnly: boolean;
|
|
13
|
+
write?: boolean;
|
|
14
|
+
alwaysDestructive?: boolean;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|