import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
export function createSuccessResponse(data: any): CallToolResult {
// Defensive: never include raw base64 image data in responses
const sanitized = (() => {
try {
const clone = JSON.parse(JSON.stringify(data));
const stripBase64 = (obj: any) => {
if (!obj || typeof obj !== 'object') return;
for (const key of Object.keys(obj)) {
const value = obj[key];
if (key.toLowerCase() === 'base64') {
delete obj[key];
continue;
}
if (value && typeof value === 'object') stripBase64(value);
}
};
stripBase64(clone);
return clone;
} catch {
return data;
}
})();
return {
content: [
{
type: 'text',
text: JSON.stringify(sanitized)
}
]
};
}
export function createErrorResponse(error: string | Error): CallToolResult {
const errorMessage = error instanceof Error ? error.message : error;
return {
content: [
{
type: 'text',
text: JSON.stringify({
success: false,
error: errorMessage
})
}
]
};
}
/**
* Sanitize text by removing non-printable characters, zero-width chars,
* collapsing whitespace sequences, converting NBSP to space, and trimming.
*/
export function sanitizeText(input: string | null | undefined): string {
if (!input) return '';
let s = String(input);
s = s.replace(/\u00A0/g, ' '); // NBSP to regular space
s = s.replace(/[\u200B-\u200D\uFEFF]/g, ''); // zero-width chars
s = s.replace(/[\x00-\x09\x0B-\x1F\x7F]/g, ''); // control chars
s = s.replace(/\s+/g, ' '); // collapse whitespace
s = s.trim();
return s;
}