@syntholoc/mcp 0.1.0 → 0.1.1
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 +30 -29
- package/dist/build-server.js +1 -2
- package/dist/{chunk-N4PXYXAP.js → chunk-RJ5GG3TT.js} +0 -1
- package/dist/index.js +2 -3
- package/package.json +4 -5
- package/dist/build-server.js.map +0 -1
- package/dist/chunk-N4PXYXAP.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/src/build-server.ts +0 -18
- package/src/config.ts +0 -8
- package/src/index.ts +0 -20
- package/src/prompts.ts +0 -73
- package/src/resources.ts +0 -43
- package/src/tools/analytics.ts +0 -55
- package/src/tools/config.ts +0 -19
- package/src/tools/git.ts +0 -68
- package/src/tools/glossary.ts +0 -84
- package/src/tools/index.ts +0 -30
- package/src/tools/jobs.ts +0 -53
- package/src/tools/keys.ts +0 -114
- package/src/tools/locales.ts +0 -60
- package/src/tools/projects.ts +0 -74
- package/src/tools/providers.ts +0 -35
- package/src/tools/qa.ts +0 -46
- package/src/tools/styleguides.ts +0 -49
- package/src/tools/translations.ts +0 -156
- package/src/util.ts +0 -9
package/src/tools/glossary.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import {
|
|
4
|
-
CREATE_GLOSSARY_TERM,
|
|
5
|
-
DELETE_GLOSSARY_TERM,
|
|
6
|
-
LIST_GLOSSARY,
|
|
7
|
-
SUGGEST_GLOSSARY_TERMS,
|
|
8
|
-
UPDATE_GLOSSARY_TERM,
|
|
9
|
-
type GraphQLClient,
|
|
10
|
-
} from '@syntholoc/sdk';
|
|
11
|
-
import { jsonResult } from '../util';
|
|
12
|
-
|
|
13
|
-
export function registerGlossaryTools(server: McpServer, gql: GraphQLClient): void {
|
|
14
|
-
server.registerTool(
|
|
15
|
-
'list_glossary',
|
|
16
|
-
{
|
|
17
|
-
title: 'List glossary terms',
|
|
18
|
-
description: 'Lists glossary terms (project-scoped if projectId given, else org-wide).',
|
|
19
|
-
inputSchema: {
|
|
20
|
-
projectId: z.string().optional(),
|
|
21
|
-
skip: z.number().int().min(0).default(0),
|
|
22
|
-
take: z.number().int().min(1).max(100).default(25),
|
|
23
|
-
},
|
|
24
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
25
|
-
},
|
|
26
|
-
async (vars) => jsonResult((await gql.request(LIST_GLOSSARY, vars)).glossaryTerms),
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
server.registerTool(
|
|
30
|
-
'upsert_glossary_term',
|
|
31
|
-
{
|
|
32
|
-
title: 'Create or update glossary term',
|
|
33
|
-
description:
|
|
34
|
-
'Creates a glossary term, or updates it when `termId` is given. `translations` is a ' +
|
|
35
|
-
'per-locale map, e.g. {"de-DE":"…"}. `forbidden` lists disallowed renderings.',
|
|
36
|
-
inputSchema: {
|
|
37
|
-
termId: z.string().optional().describe('Provide to update an existing term'),
|
|
38
|
-
projectId: z.string().optional().describe('Project scope; omit for org-wide (create only)'),
|
|
39
|
-
term: z.string().optional(),
|
|
40
|
-
description: z.string().optional(),
|
|
41
|
-
partOfSpeech: z.string().optional(),
|
|
42
|
-
doNotTranslate: z.boolean().optional(),
|
|
43
|
-
forbidden: z.array(z.string()).optional(),
|
|
44
|
-
translations: z.record(z.string(), z.string()).optional(),
|
|
45
|
-
},
|
|
46
|
-
annotations: { idempotentHint: true, openWorldHint: true },
|
|
47
|
-
},
|
|
48
|
-
async ({ termId, projectId, ...rest }) => {
|
|
49
|
-
if (termId) {
|
|
50
|
-
const data = await gql.request(UPDATE_GLOSSARY_TERM, { id: termId, input: rest });
|
|
51
|
-
return jsonResult(data.updateGlossaryTerm);
|
|
52
|
-
}
|
|
53
|
-
if (!rest.term) throw new Error('`term` is required when creating a glossary term');
|
|
54
|
-
const data = await gql.request(CREATE_GLOSSARY_TERM, {
|
|
55
|
-
input: { term: rest.term, ...rest, projectId },
|
|
56
|
-
});
|
|
57
|
-
return jsonResult(data.createGlossaryTerm);
|
|
58
|
-
},
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
server.registerTool(
|
|
62
|
-
'delete_glossary_term',
|
|
63
|
-
{
|
|
64
|
-
title: 'Delete glossary term',
|
|
65
|
-
description: 'Deletes a glossary term. Destructive — confirm first.',
|
|
66
|
-
inputSchema: { termId: z.string() },
|
|
67
|
-
annotations: { destructiveHint: true, openWorldHint: true },
|
|
68
|
-
},
|
|
69
|
-
async ({ termId }) =>
|
|
70
|
-
jsonResult((await gql.request(DELETE_GLOSSARY_TERM, { id: termId })).deleteGlossaryTerm),
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
server.registerTool(
|
|
74
|
-
'suggest_glossary_terms',
|
|
75
|
-
{
|
|
76
|
-
title: 'Suggest glossary terms',
|
|
77
|
-
description: 'AI-suggested glossary terms extracted from the project source strings.',
|
|
78
|
-
inputSchema: { projectId: z.string() },
|
|
79
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
80
|
-
},
|
|
81
|
-
async ({ projectId }) =>
|
|
82
|
-
jsonResult((await gql.request(SUGGEST_GLOSSARY_TERMS, { projectId })).suggestGlossaryTerms),
|
|
83
|
-
);
|
|
84
|
-
}
|
package/src/tools/index.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import type { GraphQLClient } from '@syntholoc/sdk';
|
|
3
|
-
import { registerAnalyticsTools } from './analytics';
|
|
4
|
-
import { registerConfigTools } from './config';
|
|
5
|
-
import { registerGitTools } from './git';
|
|
6
|
-
import { registerGlossaryTools } from './glossary';
|
|
7
|
-
import { registerJobTools } from './jobs';
|
|
8
|
-
import { registerKeyTools } from './keys';
|
|
9
|
-
import { registerLocaleTools } from './locales';
|
|
10
|
-
import { registerProjectTools } from './projects';
|
|
11
|
-
import { registerProviderTools } from './providers';
|
|
12
|
-
import { registerQaTools } from './qa';
|
|
13
|
-
import { registerStyleGuideTools } from './styleguides';
|
|
14
|
-
import { registerTranslationTools } from './translations';
|
|
15
|
-
|
|
16
|
-
/** Registers the full Syntholoc tool surface on the given MCP server. */
|
|
17
|
-
export function registerAllTools(server: McpServer, gql: GraphQLClient): void {
|
|
18
|
-
registerConfigTools(server, gql);
|
|
19
|
-
registerProjectTools(server, gql);
|
|
20
|
-
registerLocaleTools(server, gql);
|
|
21
|
-
registerKeyTools(server, gql);
|
|
22
|
-
registerTranslationTools(server, gql);
|
|
23
|
-
registerQaTools(server, gql);
|
|
24
|
-
registerGlossaryTools(server, gql);
|
|
25
|
-
registerStyleGuideTools(server, gql);
|
|
26
|
-
registerGitTools(server, gql);
|
|
27
|
-
registerProviderTools(server, gql);
|
|
28
|
-
registerJobTools(server, gql);
|
|
29
|
-
registerAnalyticsTools(server, gql);
|
|
30
|
-
}
|
package/src/tools/jobs.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { GET_JOB, LIST_JOBS, waitForJob, type GraphQLClient } from '@syntholoc/sdk';
|
|
4
|
-
import { jsonResult } from '../util';
|
|
5
|
-
|
|
6
|
-
export function registerJobTools(server: McpServer, gql: GraphQLClient): void {
|
|
7
|
-
server.registerTool(
|
|
8
|
-
'get_job',
|
|
9
|
-
{
|
|
10
|
-
title: 'Get job',
|
|
11
|
-
description: 'Status, progress, token usage and cost of a background job by id.',
|
|
12
|
-
inputSchema: { jobId: z.string(), projectId: z.string() },
|
|
13
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
14
|
-
},
|
|
15
|
-
async ({ jobId, projectId }) => jsonResult((await gql.request(GET_JOB, { id: jobId, projectId })).job),
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
server.registerTool(
|
|
19
|
-
'list_jobs',
|
|
20
|
-
{
|
|
21
|
-
title: 'List jobs',
|
|
22
|
-
description: 'Recent background jobs for a project (translate / QA / git sync).',
|
|
23
|
-
inputSchema: {
|
|
24
|
-
projectId: z.string(),
|
|
25
|
-
skip: z.number().int().min(0).default(0),
|
|
26
|
-
take: z.number().int().min(1).max(100).default(25),
|
|
27
|
-
},
|
|
28
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
29
|
-
},
|
|
30
|
-
async (vars) => jsonResult((await gql.request(LIST_JOBS, vars)).jobs),
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
server.registerTool(
|
|
34
|
-
'wait_for_job',
|
|
35
|
-
{
|
|
36
|
-
title: 'Wait for job',
|
|
37
|
-
description:
|
|
38
|
-
'Polls a job until it reaches a terminal state (COMPLETED/FAILED/CANCELLED) or the timeout ' +
|
|
39
|
-
'elapses, then returns its final detail. Use after translate/QA to follow a run.',
|
|
40
|
-
inputSchema: {
|
|
41
|
-
jobId: z.string(),
|
|
42
|
-
projectId: z.string(),
|
|
43
|
-
timeoutSec: z.number().int().min(1).max(900).default(180),
|
|
44
|
-
pollIntervalSec: z.number().int().min(1).max(30).default(2),
|
|
45
|
-
},
|
|
46
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
47
|
-
},
|
|
48
|
-
async ({ jobId, projectId, timeoutSec, pollIntervalSec }) => {
|
|
49
|
-
const { job, timedOut } = await waitForJob(gql, projectId, jobId, { timeoutSec, pollIntervalSec });
|
|
50
|
-
return jsonResult({ ...job, timedOut });
|
|
51
|
-
},
|
|
52
|
-
);
|
|
53
|
-
}
|
package/src/tools/keys.ts
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import {
|
|
4
|
-
DELETE_KEY,
|
|
5
|
-
IMPORT_SOURCE_STRINGS,
|
|
6
|
-
LIST_KEYS,
|
|
7
|
-
UPDATE_KEY,
|
|
8
|
-
UPSERT_KEYS,
|
|
9
|
-
type GraphQLClient,
|
|
10
|
-
} from '@syntholoc/sdk';
|
|
11
|
-
import { jsonResult } from '../util';
|
|
12
|
-
|
|
13
|
-
const FORMATS = ['JSON', 'YAML', 'CSV', 'PO', 'XLIFF', 'ANDROID_XML', 'IOS_STRINGS'] as const;
|
|
14
|
-
|
|
15
|
-
export function registerKeyTools(server: McpServer, gql: GraphQLClient): void {
|
|
16
|
-
server.registerTool(
|
|
17
|
-
'list_keys',
|
|
18
|
-
{
|
|
19
|
-
title: 'List keys',
|
|
20
|
-
description:
|
|
21
|
-
'Lists source keys. With `localeId` + `status` (untranslated | flagged | approved) the ' +
|
|
22
|
-
'result `totalCount` is the pending count for that status — use it for the batch threshold.',
|
|
23
|
-
inputSchema: {
|
|
24
|
-
projectId: z.string(),
|
|
25
|
-
localeId: z.string().optional(),
|
|
26
|
-
status: z.enum(['untranslated', 'flagged', 'approved']).optional(),
|
|
27
|
-
search: z.string().optional(),
|
|
28
|
-
skip: z.number().int().min(0).default(0),
|
|
29
|
-
take: z.number().int().min(1).max(200).default(25),
|
|
30
|
-
},
|
|
31
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
32
|
-
},
|
|
33
|
-
async (vars) => jsonResult((await gql.request(LIST_KEYS, vars)).keys),
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
server.registerTool(
|
|
37
|
-
'upsert_keys',
|
|
38
|
-
{
|
|
39
|
-
title: 'Upsert keys (bulk)',
|
|
40
|
-
description:
|
|
41
|
-
'Bulk-upserts source keys by name (delta sync from local i18n files). Keys not listed are ' +
|
|
42
|
-
'left untouched. Returns added/updated/unchanged counts; set `dryRun` to preview.',
|
|
43
|
-
inputSchema: {
|
|
44
|
-
projectId: z.string(),
|
|
45
|
-
keys: z
|
|
46
|
-
.array(
|
|
47
|
-
z.object({
|
|
48
|
-
key: z.string(),
|
|
49
|
-
sourceText: z.string(),
|
|
50
|
-
context: z.string().optional(),
|
|
51
|
-
maxLength: z.number().int().positive().optional(),
|
|
52
|
-
}),
|
|
53
|
-
)
|
|
54
|
-
.min(1),
|
|
55
|
-
dryRun: z.boolean().default(false),
|
|
56
|
-
},
|
|
57
|
-
annotations: { idempotentHint: true, openWorldHint: true },
|
|
58
|
-
},
|
|
59
|
-
async ({ projectId, keys, dryRun }) =>
|
|
60
|
-
jsonResult((await gql.request(UPSERT_KEYS, { projectId, input: keys, dryRun })).upsertKeys),
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
server.registerTool(
|
|
64
|
-
'update_key',
|
|
65
|
-
{
|
|
66
|
-
title: 'Update key',
|
|
67
|
-
description: 'Updates a single key (source text, context, max length).',
|
|
68
|
-
inputSchema: {
|
|
69
|
-
projectId: z.string(),
|
|
70
|
-
keyId: z.string(),
|
|
71
|
-
sourceText: z.string().optional(),
|
|
72
|
-
context: z.string().optional(),
|
|
73
|
-
maxLength: z.number().int().positive().optional(),
|
|
74
|
-
},
|
|
75
|
-
annotations: { idempotentHint: true, openWorldHint: true },
|
|
76
|
-
},
|
|
77
|
-
async ({ projectId, keyId, ...input }) =>
|
|
78
|
-
jsonResult((await gql.request(UPDATE_KEY, { projectId, id: keyId, input })).updateKey),
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
server.registerTool(
|
|
82
|
-
'delete_key',
|
|
83
|
-
{
|
|
84
|
-
title: 'Delete key',
|
|
85
|
-
description: 'Deletes a key and its translations. Destructive — confirm first.',
|
|
86
|
-
inputSchema: { projectId: z.string(), keyId: z.string() },
|
|
87
|
-
annotations: { destructiveHint: true, openWorldHint: true },
|
|
88
|
-
},
|
|
89
|
-
async ({ projectId, keyId }) =>
|
|
90
|
-
jsonResult((await gql.request(DELETE_KEY, { projectId, id: keyId })).deleteKey),
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
server.registerTool(
|
|
94
|
-
'import_source_strings',
|
|
95
|
-
{
|
|
96
|
-
title: 'Import source strings',
|
|
97
|
-
description:
|
|
98
|
-
'Imports source strings from a file (paste the raw content) and returns the diff summary. ' +
|
|
99
|
-
'Use `dryRun` to preview. For a structured delta prefer upsert_keys.',
|
|
100
|
-
inputSchema: {
|
|
101
|
-
projectId: z.string(),
|
|
102
|
-
content: z.string(),
|
|
103
|
-
format: z.enum(FORMATS),
|
|
104
|
-
dryRun: z.boolean().default(false),
|
|
105
|
-
},
|
|
106
|
-
annotations: { idempotentHint: true, openWorldHint: true },
|
|
107
|
-
},
|
|
108
|
-
async ({ projectId, content, format, dryRun }) =>
|
|
109
|
-
jsonResult(
|
|
110
|
-
(await gql.request(IMPORT_SOURCE_STRINGS, { projectId, input: { content, format, dryRun } }))
|
|
111
|
-
.importSourceStrings,
|
|
112
|
-
),
|
|
113
|
-
);
|
|
114
|
-
}
|
package/src/tools/locales.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { ADD_LOCALE, LIST_LOCALES, REMOVE_LOCALE, SEED_STARTER_LOCALES, type GraphQLClient } from '@syntholoc/sdk';
|
|
4
|
-
import { jsonResult } from '../util';
|
|
5
|
-
|
|
6
|
-
export function registerLocaleTools(server: McpServer, gql: GraphQLClient): void {
|
|
7
|
-
server.registerTool(
|
|
8
|
-
'list_locales',
|
|
9
|
-
{
|
|
10
|
-
title: 'List locales',
|
|
11
|
-
description: 'Lists the target locales configured for a project.',
|
|
12
|
-
inputSchema: { projectId: z.string() },
|
|
13
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
14
|
-
},
|
|
15
|
-
async ({ projectId }) => jsonResult((await gql.request(LIST_LOCALES, { projectId })).locales),
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
server.registerTool(
|
|
19
|
-
'add_locale',
|
|
20
|
-
{
|
|
21
|
-
title: 'Add locale',
|
|
22
|
-
description: 'Adds a target locale (BCP-47 code) to a project.',
|
|
23
|
-
inputSchema: {
|
|
24
|
-
projectId: z.string(),
|
|
25
|
-
code: z.string().describe('BCP-47 code, e.g. "de-DE"'),
|
|
26
|
-
name: z.string().optional(),
|
|
27
|
-
formality: z.string().optional(),
|
|
28
|
-
gender: z.string().optional(),
|
|
29
|
-
variant: z.string().optional(),
|
|
30
|
-
},
|
|
31
|
-
annotations: { openWorldHint: true },
|
|
32
|
-
},
|
|
33
|
-
async ({ projectId, ...input }) =>
|
|
34
|
-
jsonResult((await gql.request(ADD_LOCALE, { projectId, input })).addLocale),
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
server.registerTool(
|
|
38
|
-
'seed_starter_locales',
|
|
39
|
-
{
|
|
40
|
-
title: 'Seed starter locales',
|
|
41
|
-
description: 'Adds a set of common starter locales to a project (omit codes for the defaults).',
|
|
42
|
-
inputSchema: { projectId: z.string(), codes: z.array(z.string()).optional() },
|
|
43
|
-
annotations: { openWorldHint: true },
|
|
44
|
-
},
|
|
45
|
-
async ({ projectId, codes }) =>
|
|
46
|
-
jsonResult((await gql.request(SEED_STARTER_LOCALES, { projectId, codes })).seedStarterLocales),
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
server.registerTool(
|
|
50
|
-
'remove_locale',
|
|
51
|
-
{
|
|
52
|
-
title: 'Remove locale',
|
|
53
|
-
description: 'Removes a target locale and its translations. Destructive — confirm first.',
|
|
54
|
-
inputSchema: { projectId: z.string(), localeId: z.string() },
|
|
55
|
-
annotations: { destructiveHint: true, openWorldHint: true },
|
|
56
|
-
},
|
|
57
|
-
async ({ projectId, localeId }) =>
|
|
58
|
-
jsonResult((await gql.request(REMOVE_LOCALE, { projectId, id: localeId })).removeLocale),
|
|
59
|
-
);
|
|
60
|
-
}
|
package/src/tools/projects.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { CREATE_PROJECT, GET_PROJECT, LIST_PROJECTS, UPDATE_PROJECT, type GraphQLClient } from '@syntholoc/sdk';
|
|
4
|
-
import { jsonResult } from '../util';
|
|
5
|
-
|
|
6
|
-
export function registerProjectTools(server: McpServer, gql: GraphQLClient): void {
|
|
7
|
-
server.registerTool(
|
|
8
|
-
'list_projects',
|
|
9
|
-
{
|
|
10
|
-
title: 'List projects',
|
|
11
|
-
description: 'Lists localization projects in the active organization (paginated).',
|
|
12
|
-
inputSchema: {
|
|
13
|
-
skip: z.number().int().min(0).default(0),
|
|
14
|
-
take: z.number().int().min(1).max(100).default(25),
|
|
15
|
-
},
|
|
16
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
17
|
-
},
|
|
18
|
-
async ({ skip, take }) => jsonResult((await gql.request(LIST_PROJECTS, { skip, take })).projects),
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
server.registerTool(
|
|
22
|
-
'get_project',
|
|
23
|
-
{
|
|
24
|
-
title: 'Get project',
|
|
25
|
-
description:
|
|
26
|
-
'Project settings plus analytics, including per-locale progress with the `untranslated` ' +
|
|
27
|
-
'count used to decide the batch threshold (see get_config).',
|
|
28
|
-
inputSchema: { projectId: z.string() },
|
|
29
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
30
|
-
},
|
|
31
|
-
async ({ projectId }) => jsonResult(await gql.request(GET_PROJECT, { id: projectId })),
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
server.registerTool(
|
|
35
|
-
'create_project',
|
|
36
|
-
{
|
|
37
|
-
title: 'Create project',
|
|
38
|
-
description: 'Creates a localization project. `sourceLocale` defaults to "en".',
|
|
39
|
-
inputSchema: {
|
|
40
|
-
name: z.string(),
|
|
41
|
-
sourceLocale: z.string().default('en'),
|
|
42
|
-
description: z.string().optional(),
|
|
43
|
-
context: z.string().optional(),
|
|
44
|
-
requireReview: z.boolean().optional(),
|
|
45
|
-
qaCriticEnabled: z.boolean().optional(),
|
|
46
|
-
},
|
|
47
|
-
annotations: { openWorldHint: true },
|
|
48
|
-
},
|
|
49
|
-
async (input) => jsonResult((await gql.request(CREATE_PROJECT, { input })).createProject),
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
server.registerTool(
|
|
53
|
-
'update_project',
|
|
54
|
-
{
|
|
55
|
-
title: 'Update project',
|
|
56
|
-
description: 'Updates project settings (name, source locale, review/QA flags, context).',
|
|
57
|
-
inputSchema: {
|
|
58
|
-
projectId: z.string(),
|
|
59
|
-
name: z.string().optional(),
|
|
60
|
-
sourceLocale: z.string().optional(),
|
|
61
|
-
description: z.string().optional(),
|
|
62
|
-
context: z.string().optional(),
|
|
63
|
-
requireReview: z.boolean().optional(),
|
|
64
|
-
qaCriticEnabled: z.boolean().optional(),
|
|
65
|
-
exportApprovedOnly: z.boolean().optional(),
|
|
66
|
-
sortKeysAlphabetically: z.boolean().optional(),
|
|
67
|
-
status: z.string().optional(),
|
|
68
|
-
},
|
|
69
|
-
annotations: { idempotentHint: true, openWorldHint: true },
|
|
70
|
-
},
|
|
71
|
-
async ({ projectId, ...input }) =>
|
|
72
|
-
jsonResult((await gql.request(UPDATE_PROJECT, { id: projectId, input })).updateProject),
|
|
73
|
-
);
|
|
74
|
-
}
|
package/src/tools/providers.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { CONFIGURE_LLM_PROVIDER, LIST_LLM_PROVIDERS, type GraphQLClient } from '@syntholoc/sdk';
|
|
4
|
-
import { jsonResult } from '../util';
|
|
5
|
-
|
|
6
|
-
export function registerProviderTools(server: McpServer, gql: GraphQLClient): void {
|
|
7
|
-
server.registerTool(
|
|
8
|
-
'list_llm_providers',
|
|
9
|
-
{
|
|
10
|
-
title: 'List LLM providers',
|
|
11
|
-
description: 'Configured LLM providers for the org (never exposes the API key).',
|
|
12
|
-
inputSchema: {},
|
|
13
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
14
|
-
},
|
|
15
|
-
async () => jsonResult((await gql.request(LIST_LLM_PROVIDERS)).llmProviders),
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
server.registerTool(
|
|
19
|
-
'configure_llm_provider',
|
|
20
|
-
{
|
|
21
|
-
title: 'Configure LLM provider',
|
|
22
|
-
description:
|
|
23
|
-
'Adds a BYOK LLM provider (OPENROUTER | OPENAI | ANTHROPIC). The key is stored encrypted at rest.',
|
|
24
|
-
inputSchema: {
|
|
25
|
-
type: z.enum(['OPENROUTER', 'OPENAI', 'ANTHROPIC']),
|
|
26
|
-
label: z.string(),
|
|
27
|
-
apiKey: z.string(),
|
|
28
|
-
baseUrl: z.string().optional(),
|
|
29
|
-
defaultModel: z.string().optional(),
|
|
30
|
-
},
|
|
31
|
-
annotations: { openWorldHint: true },
|
|
32
|
-
},
|
|
33
|
-
async (input) => jsonResult((await gql.request(CONFIGURE_LLM_PROVIDER, { input })).configureLlmProvider),
|
|
34
|
-
);
|
|
35
|
-
}
|
package/src/tools/qa.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { LIST_QA_ISSUES, RUN_LOCALE_QA, RUN_QA, type GraphQLClient } from '@syntholoc/sdk';
|
|
4
|
-
import { jsonResult } from '../util';
|
|
5
|
-
|
|
6
|
-
export function registerQaTools(server: McpServer, gql: GraphQLClient): void {
|
|
7
|
-
server.registerTool(
|
|
8
|
-
'run_locale_qa',
|
|
9
|
-
{
|
|
10
|
-
title: 'Run locale QA',
|
|
11
|
-
description:
|
|
12
|
-
"Queues an LLM QA-critic pass over a locale's non-approved translations. Returns tracking `jobIds`.",
|
|
13
|
-
inputSchema: { projectId: z.string(), localeId: z.string() },
|
|
14
|
-
annotations: { openWorldHint: true },
|
|
15
|
-
},
|
|
16
|
-
async (vars) => jsonResult((await gql.request(RUN_LOCALE_QA, vars)).runLocaleQa),
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
server.registerTool(
|
|
20
|
-
'run_qa',
|
|
21
|
-
{
|
|
22
|
-
title: 'Run QA on a translation',
|
|
23
|
-
description: 'Runs QA on one translation and returns its score and issues (synchronous).',
|
|
24
|
-
inputSchema: { projectId: z.string(), translationId: z.string() },
|
|
25
|
-
annotations: { openWorldHint: true },
|
|
26
|
-
},
|
|
27
|
-
async (vars) => jsonResult((await gql.request(RUN_QA, vars)).runQa),
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
server.registerTool(
|
|
31
|
-
'list_qa_issues',
|
|
32
|
-
{
|
|
33
|
-
title: 'List QA issues',
|
|
34
|
-
description: 'Open QA issues for a locale, plus the issue-type facets (filter tabs).',
|
|
35
|
-
inputSchema: {
|
|
36
|
-
projectId: z.string(),
|
|
37
|
-
localeId: z.string(),
|
|
38
|
-
type: z.string().optional(),
|
|
39
|
-
skip: z.number().int().min(0).default(0),
|
|
40
|
-
take: z.number().int().min(1).max(100).default(25),
|
|
41
|
-
},
|
|
42
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
43
|
-
},
|
|
44
|
-
async (vars) => jsonResult(await gql.request(LIST_QA_ISSUES, vars)),
|
|
45
|
-
);
|
|
46
|
-
}
|
package/src/tools/styleguides.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { CREATE_STYLE_GUIDE, GENERATE_STYLE_GUIDE, LIST_STYLE_GUIDES, type GraphQLClient } from '@syntholoc/sdk';
|
|
4
|
-
import { jsonResult } from '../util';
|
|
5
|
-
|
|
6
|
-
export function registerStyleGuideTools(server: McpServer, gql: GraphQLClient): void {
|
|
7
|
-
server.registerTool(
|
|
8
|
-
'list_style_guides',
|
|
9
|
-
{
|
|
10
|
-
title: 'List style guides',
|
|
11
|
-
description: 'Lists style guides (project-scoped if projectId given, else org-wide).',
|
|
12
|
-
inputSchema: { projectId: z.string().optional() },
|
|
13
|
-
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
14
|
-
},
|
|
15
|
-
async ({ projectId }) => jsonResult((await gql.request(LIST_STYLE_GUIDES, { projectId })).styleGuides),
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
server.registerTool(
|
|
19
|
-
'generate_style_guide',
|
|
20
|
-
{
|
|
21
|
-
title: 'Generate style guide (draft)',
|
|
22
|
-
description:
|
|
23
|
-
'Drafts a tone/rules/prompt-fragment style guide from the project (optionally per locale). ' +
|
|
24
|
-
'Returns a draft — persist it with create_style_guide.',
|
|
25
|
-
inputSchema: { projectId: z.string(), localeCode: z.string().optional() },
|
|
26
|
-
annotations: { openWorldHint: true },
|
|
27
|
-
},
|
|
28
|
-
async ({ projectId, localeCode }) =>
|
|
29
|
-
jsonResult((await gql.request(GENERATE_STYLE_GUIDE, { input: { projectId, localeCode } })).generateStyleGuide),
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
server.registerTool(
|
|
33
|
-
'create_style_guide',
|
|
34
|
-
{
|
|
35
|
-
title: 'Create style guide',
|
|
36
|
-
description: 'Persists a style guide (tone, rules JSON, prompt fragment), project- or locale-scoped.',
|
|
37
|
-
inputSchema: {
|
|
38
|
-
name: z.string(),
|
|
39
|
-
projectId: z.string().optional(),
|
|
40
|
-
localeCode: z.string().optional(),
|
|
41
|
-
tone: z.string().optional(),
|
|
42
|
-
promptFragment: z.string().optional(),
|
|
43
|
-
rules: z.array(z.string()).optional(),
|
|
44
|
-
},
|
|
45
|
-
annotations: { openWorldHint: true },
|
|
46
|
-
},
|
|
47
|
-
async (input) => jsonResult((await gql.request(CREATE_STYLE_GUIDE, { input })).createStyleGuide),
|
|
48
|
-
);
|
|
49
|
-
}
|