@l10nmonster/mcp 3.0.0-alpha.17 → 3.1.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/.releaserc.json +31 -0
- package/CHANGELOG.md +13 -0
- package/package.json +2 -2
- package/tests/mcpToolValidation.test.js +11 -9
- package/tools/sourceQuery.js +23 -17
package/.releaserc.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"branches": [
|
|
3
|
+
"main",
|
|
4
|
+
{
|
|
5
|
+
"name": "next",
|
|
6
|
+
"prerelease": "alpha"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"name": "beta",
|
|
10
|
+
"prerelease": "beta"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"tagFormat": "@l10nmonster/mcp@${version}",
|
|
14
|
+
"plugins": [
|
|
15
|
+
"@semantic-release/commit-analyzer",
|
|
16
|
+
"@semantic-release/release-notes-generator",
|
|
17
|
+
{
|
|
18
|
+
"path": "@semantic-release/changelog",
|
|
19
|
+
"changelogFile": "CHANGELOG.md"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"path": "@semantic-release/npm",
|
|
23
|
+
"npmPublish": false
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"path": "@semantic-release/git",
|
|
27
|
+
"assets": ["CHANGELOG.md", "package.json"],
|
|
28
|
+
"message": "chore(release): @l10nmonster/mcp@${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @l10nmonster/mcp [3.1.0](https://public-github/l10nmonster/l10nmonster/compare/@l10nmonster/mcp@3.0.0...@l10nmonster/mcp@3.1.0) (2025-12-20)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Make source query channel optional ([1addc68](https://public-github/l10nmonster/l10nmonster/commit/1addc68d009794a92588a28b816d7e9edbab6b47))
|
|
7
|
+
* Pluralization improvements ([5964250](https://public-github/l10nmonster/l10nmonster/commit/596425092c425cc8d6c312ef58509c4c3c537431))
|
|
8
|
+
* Version bumps ([d3030bd](https://public-github/l10nmonster/l10nmonster/commit/d3030bdd0af6ddbc79b3076af7427111ca9b04d0))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* implement an approach for mcp extensibility ([#50](https://public-github/l10nmonster/l10nmonster/issues/50)) ([5fcc89b](https://public-github/l10nmonster/l10nmonster/commit/5fcc89bef8c8af01d88f35dece8290989d04e4d5))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@l10nmonster/mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "L10n Monster Model Context Protocol (MCP) Server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"zod": "^3"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@l10nmonster/core": "
|
|
15
|
+
"@l10nmonster/core": "3.1.0"
|
|
16
16
|
},
|
|
17
17
|
"engines": {
|
|
18
18
|
"node": ">=22.11.0"
|
|
@@ -352,16 +352,16 @@ describe('MCP Tool Input Validation and Output', () => {
|
|
|
352
352
|
assert.ok(result2.isError);
|
|
353
353
|
});
|
|
354
354
|
|
|
355
|
-
it('should
|
|
355
|
+
it('should query all channels when channel is omitted', async () => {
|
|
356
356
|
const handler = SourceQueryTool.handler(mockMM);
|
|
357
357
|
const result = await handler({
|
|
358
358
|
sourceLang: 'en',
|
|
359
359
|
targetLang: 'fr'
|
|
360
360
|
});
|
|
361
|
-
|
|
362
|
-
assert.ok(result.isError);
|
|
363
|
-
const
|
|
364
|
-
assert.
|
|
361
|
+
|
|
362
|
+
assert.ok(!result.isError);
|
|
363
|
+
const json = JSON.parse(result.content[0].text);
|
|
364
|
+
assert.ok(json.translationUnits);
|
|
365
365
|
});
|
|
366
366
|
|
|
367
367
|
it('should accept optional whereCondition', async () => {
|
|
@@ -385,16 +385,18 @@ describe('MCP Tool Input Validation and Output', () => {
|
|
|
385
385
|
assert.ok(!result2.isError);
|
|
386
386
|
});
|
|
387
387
|
|
|
388
|
-
it('should
|
|
388
|
+
it('should treat empty channel as query all channels', async () => {
|
|
389
389
|
const handler = SourceQueryTool.handler(mockMM);
|
|
390
390
|
const result = await handler({
|
|
391
391
|
sourceLang: 'en',
|
|
392
392
|
targetLang: 'fr',
|
|
393
393
|
channel: ''
|
|
394
394
|
});
|
|
395
|
-
|
|
396
|
-
// Empty string
|
|
397
|
-
assert.ok(result.isError);
|
|
395
|
+
|
|
396
|
+
// Empty string channel is falsy, so queries all channels
|
|
397
|
+
assert.ok(!result.isError);
|
|
398
|
+
const json = JSON.parse(result.content[0].text);
|
|
399
|
+
assert.ok(json.translationUnits);
|
|
398
400
|
});
|
|
399
401
|
});
|
|
400
402
|
|
package/tools/sourceQuery.js
CHANGED
|
@@ -32,7 +32,8 @@ You can write your own where conditions using SQL syntaxt against the following
|
|
|
32
32
|
targetLang: z.string()
|
|
33
33
|
.describe('Target language code (e.g., "es-419")'),
|
|
34
34
|
channel: z.string()
|
|
35
|
-
.
|
|
35
|
+
.optional()
|
|
36
|
+
.describe('Channel ID to query sources from. If omitted, queries all channels.'),
|
|
36
37
|
whereCondition: z.string()
|
|
37
38
|
.optional()
|
|
38
39
|
.describe('SQL WHERE condition against sources (default: "true" to match all)'),
|
|
@@ -40,12 +41,14 @@ You can write your own where conditions using SQL syntaxt against the following
|
|
|
40
41
|
};
|
|
41
42
|
|
|
42
43
|
static async execute(mm, args) {
|
|
43
|
-
const { sourceLang, targetLang, channel
|
|
44
|
+
const { sourceLang, targetLang, channel } = args;
|
|
44
45
|
const whereCondition = args.whereCondition ?? 'true';
|
|
45
46
|
|
|
46
47
|
const availableChannels = mm.rm.channelIds ?? [];
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
const channels = channel ? [channel] : availableChannels;
|
|
49
|
+
|
|
50
|
+
if (channel && availableChannels.length > 0 && !availableChannels.includes(channel)) {
|
|
51
|
+
throw new McpNotFoundError(`Channel "${channel}" not found`, {
|
|
49
52
|
hints: [`Available channels: ${availableChannels.join(', ')}`]
|
|
50
53
|
});
|
|
51
54
|
}
|
|
@@ -61,19 +64,22 @@ You can write your own where conditions using SQL syntaxt against the following
|
|
|
61
64
|
});
|
|
62
65
|
}
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
const tus = [];
|
|
68
|
+
for (const channelId of channels) {
|
|
69
|
+
try {
|
|
70
|
+
const channelTus = await tm.querySource(channelId, whereCondition);
|
|
71
|
+
tus.push(...channelTus);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
throw new McpToolError('Failed to execute query against source snapshot', {
|
|
74
|
+
code: 'QUERY_FAILED',
|
|
75
|
+
hints: [
|
|
76
|
+
'Verify that your SQL WHERE clause only references supported columns.',
|
|
77
|
+
'Escaping: wrap string literals in single quotes.'
|
|
78
|
+
],
|
|
79
|
+
details: { channelId, whereCondition },
|
|
80
|
+
cause: error
|
|
81
|
+
});
|
|
82
|
+
}
|
|
77
83
|
}
|
|
78
84
|
|
|
79
85
|
return {
|