@tuteliq/mcp 3.2.5 → 3.3.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/dist/server.js +1 -1
- package/dist/src/formatters.d.ts +16 -0
- package/dist/src/formatters.d.ts.map +1 -1
- package/dist/src/formatters.js +36 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -5
- package/dist/src/tools/detection.d.ts.map +1 -1
- package/dist/src/tools/detection.js +10 -4
- package/dist-ui/detection-result.html +45 -45
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -34,7 +34,7 @@ app.post('/messages', (req, res) => {
|
|
|
34
34
|
});
|
|
35
35
|
});
|
|
36
36
|
app.get('/health', (_req, res) => {
|
|
37
|
-
res.json({ status: 'ok', version: '3.2.
|
|
37
|
+
res.json({ status: 'ok', version: '3.2.5' });
|
|
38
38
|
});
|
|
39
39
|
const server = app.listen(port, () => {
|
|
40
40
|
console.error(`Tuteliq MCP server running on http://localhost:${port}`);
|
package/dist/src/formatters.d.ts
CHANGED
|
@@ -4,5 +4,21 @@ export declare const riskEmoji: Record<string, string>;
|
|
|
4
4
|
export declare const trendEmoji: Record<string, string>;
|
|
5
5
|
export declare function formatDetectionResult(result: DetectionResult): string;
|
|
6
6
|
export declare function formatMultiResult(result: AnalyseMultiResult): string;
|
|
7
|
+
export declare function formatSupportText(support: {
|
|
8
|
+
country_name?: string;
|
|
9
|
+
emergency_number?: string;
|
|
10
|
+
helplines: Array<{
|
|
11
|
+
name: string;
|
|
12
|
+
number: string;
|
|
13
|
+
available?: string;
|
|
14
|
+
}>;
|
|
15
|
+
response_guide?: {
|
|
16
|
+
immediateActions: string[];
|
|
17
|
+
resources: Array<{
|
|
18
|
+
name: string;
|
|
19
|
+
url?: string;
|
|
20
|
+
}>;
|
|
21
|
+
};
|
|
22
|
+
}): string;
|
|
7
23
|
export declare function formatVideoResult(result: VideoAnalysisResult): string;
|
|
8
24
|
//# sourceMappingURL=formatters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAE7F,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKhD,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAO5C,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAI7C,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CA4CrE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CA2BpE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAoBrE"}
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAE7F,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKhD,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAO5C,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAI7C,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CA4CrE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CA2BpE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE,cAAc,CAAC,EAAE;QAAE,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CACnG,GAAG,MAAM,CAuCT;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAoBrE"}
|
package/dist/src/formatters.js
CHANGED
|
@@ -54,7 +54,7 @@ ${result.rationale}
|
|
|
54
54
|
|
|
55
55
|
${evidence}
|
|
56
56
|
${messageAnalysis}
|
|
57
|
-
${calibration}`.trim();
|
|
57
|
+
${calibration}`.trim() + (result.support ? formatSupportText(result.support) : '');
|
|
58
58
|
}
|
|
59
59
|
export function formatMultiResult(result) {
|
|
60
60
|
const s = result.summary;
|
|
@@ -81,6 +81,41 @@ ${r.rationale}`;
|
|
|
81
81
|
|
|
82
82
|
${perEndpoint}`;
|
|
83
83
|
}
|
|
84
|
+
export function formatSupportText(support) {
|
|
85
|
+
const lines = [
|
|
86
|
+
'',
|
|
87
|
+
'---',
|
|
88
|
+
'',
|
|
89
|
+
'\u{1F499} **You Are Not Alone**',
|
|
90
|
+
'If you or someone you know needs support, help is available.',
|
|
91
|
+
'',
|
|
92
|
+
];
|
|
93
|
+
if (support.emergency_number) {
|
|
94
|
+
lines.push(`\u{1F6A8} **Emergency:** ${support.emergency_number}${support.country_name ? ` (${support.country_name})` : ''}`);
|
|
95
|
+
lines.push('');
|
|
96
|
+
}
|
|
97
|
+
if (support.helplines.length > 0) {
|
|
98
|
+
lines.push('**Crisis Helplines:**');
|
|
99
|
+
for (const h of support.helplines) {
|
|
100
|
+
lines.push(`- \u{1F4DE} **${h.name}:** ${h.number}${h.available ? ` (${h.available})` : ''}`);
|
|
101
|
+
}
|
|
102
|
+
lines.push('');
|
|
103
|
+
}
|
|
104
|
+
if (support.response_guide?.immediateActions?.length) {
|
|
105
|
+
lines.push('**What you can do now:**');
|
|
106
|
+
for (const action of support.response_guide.immediateActions) {
|
|
107
|
+
lines.push(`- ${action}`);
|
|
108
|
+
}
|
|
109
|
+
lines.push('');
|
|
110
|
+
}
|
|
111
|
+
if (support.response_guide?.resources?.length) {
|
|
112
|
+
lines.push('**Resources:**');
|
|
113
|
+
for (const r of support.response_guide.resources) {
|
|
114
|
+
lines.push(r.url ? `- [${r.name}](${r.url})` : `- ${r.name}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return lines.join('\n');
|
|
118
|
+
}
|
|
84
119
|
export function formatVideoResult(result) {
|
|
85
120
|
const emoji = severityEmoji[result.overall_severity] || '\u2705';
|
|
86
121
|
const findingsSection = result.safety_findings.length > 0
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAUpE,wBAAgB,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAUpE,wBAAgB,YAAY,IAAI,SAAS,CAsBxC"}
|
package/dist/src/index.js
CHANGED
|
@@ -7,16 +7,16 @@ import { registerMediaTools } from './tools/media.js';
|
|
|
7
7
|
import { registerAnalysisTools } from './tools/analysis.js';
|
|
8
8
|
import { registerAdminTools } from './tools/admin.js';
|
|
9
9
|
import { getTransportMode, startStdio } from './transport.js';
|
|
10
|
-
export function createServer(
|
|
11
|
-
const
|
|
12
|
-
if (!
|
|
10
|
+
export function createServer() {
|
|
11
|
+
const apiKey = process.env.TUTELIQ_API_KEY;
|
|
12
|
+
if (!apiKey) {
|
|
13
13
|
console.error('Error: TUTELIQ_API_KEY environment variable is required');
|
|
14
14
|
process.exit(1);
|
|
15
15
|
}
|
|
16
|
-
const client = new Tuteliq(
|
|
16
|
+
const client = new Tuteliq(apiKey);
|
|
17
17
|
const server = new McpServer({
|
|
18
18
|
name: 'tuteliq-mcp',
|
|
19
|
-
version: '3.
|
|
19
|
+
version: '3.0.0',
|
|
20
20
|
});
|
|
21
21
|
// Register all tool groups
|
|
22
22
|
registerDetectionTools(server, client);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detection.d.ts","sourceRoot":"","sources":["../../../src/tools/detection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AA6C5C,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"detection.d.ts","sourceRoot":"","sources":["../../../src/tools/detection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AA6C5C,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAqN/E"}
|
|
@@ -3,7 +3,7 @@ import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from '@model
|
|
|
3
3
|
import { readFileSync } from 'fs';
|
|
4
4
|
import { resolve, dirname } from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
|
-
import { severityEmoji, riskEmoji } from '../formatters.js';
|
|
6
|
+
import { severityEmoji, riskEmoji, formatSupportText } from '../formatters.js';
|
|
7
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
8
|
const __dirname = dirname(__filename);
|
|
9
9
|
const DETECTION_WIDGET_URI = 'ui://tuteliq/detection-result.html';
|
|
@@ -63,7 +63,7 @@ export function registerDetectionTools(server, client) {
|
|
|
63
63
|
context: context,
|
|
64
64
|
});
|
|
65
65
|
const emoji = severityEmoji[result.severity] || '\u26AA';
|
|
66
|
-
|
|
66
|
+
let text = `## ${result.is_bullying ? '\u26A0\uFE0F Bullying Detected' : '\u2705 No Bullying Detected'}
|
|
67
67
|
|
|
68
68
|
**Severity:** ${emoji} ${result.severity.charAt(0).toUpperCase() + result.severity.slice(1)}
|
|
69
69
|
**Confidence:** ${(result.confidence * 100).toFixed(0)}%
|
|
@@ -76,6 +76,8 @@ ${result.rationale}
|
|
|
76
76
|
|
|
77
77
|
### Recommended Action
|
|
78
78
|
\`${result.recommended_action}\``;
|
|
79
|
+
if (result.support)
|
|
80
|
+
text += formatSupportText(result.support);
|
|
79
81
|
return {
|
|
80
82
|
structuredContent: { toolName: 'detect_bullying', result, branding: { appName: 'Tuteliq' } },
|
|
81
83
|
content: [{ type: 'text', text }],
|
|
@@ -108,7 +110,7 @@ ${result.rationale}
|
|
|
108
110
|
childAge,
|
|
109
111
|
});
|
|
110
112
|
const emoji = riskEmoji[result.grooming_risk] || '\u26AA';
|
|
111
|
-
|
|
113
|
+
let text = `## ${result.grooming_risk === 'none' ? '\u2705 No Grooming Detected' : '\u26A0\uFE0F Grooming Risk Detected'}
|
|
112
114
|
|
|
113
115
|
**Risk Level:** ${emoji} ${result.grooming_risk.charAt(0).toUpperCase() + result.grooming_risk.slice(1)}
|
|
114
116
|
**Confidence:** ${(result.confidence * 100).toFixed(0)}%
|
|
@@ -121,6 +123,8 @@ ${result.rationale}
|
|
|
121
123
|
|
|
122
124
|
### Recommended Action
|
|
123
125
|
\`${result.recommended_action}\``;
|
|
126
|
+
if (result.support)
|
|
127
|
+
text += formatSupportText(result.support);
|
|
124
128
|
return {
|
|
125
129
|
structuredContent: { toolName: 'detect_grooming', result, branding: { appName: 'Tuteliq' } },
|
|
126
130
|
content: [{ type: 'text', text }],
|
|
@@ -150,7 +154,7 @@ ${result.rationale}
|
|
|
150
154
|
context: context,
|
|
151
155
|
});
|
|
152
156
|
const emoji = severityEmoji[result.severity] || '\u26AA';
|
|
153
|
-
|
|
157
|
+
let text = `## ${result.unsafe ? '\u26A0\uFE0F Unsafe Content Detected' : '\u2705 Content is Safe'}
|
|
154
158
|
|
|
155
159
|
**Severity:** ${emoji} ${result.severity.charAt(0).toUpperCase() + result.severity.slice(1)}
|
|
156
160
|
**Confidence:** ${(result.confidence * 100).toFixed(0)}%
|
|
@@ -163,6 +167,8 @@ ${result.rationale}
|
|
|
163
167
|
|
|
164
168
|
### Recommended Action
|
|
165
169
|
\`${result.recommended_action}\``;
|
|
170
|
+
if (result.support)
|
|
171
|
+
text += formatSupportText(result.support);
|
|
166
172
|
return {
|
|
167
173
|
structuredContent: { toolName: 'detect_unsafe', result, branding: { appName: 'Tuteliq' } },
|
|
168
174
|
content: [{ type: 'text', text }],
|