import type { FastMCP } from 'fastmcp';
import { UserError } from 'fastmcp';
import { getDocsClient } from '../../../clients.js';
import {
ApplyTextStyleToolParameters,
ApplyTextStyleToolArgs,
NotImplementedError,
} from '../../../types.js';
import * as GDocsHelpers from '../../../googleDocsApiHelpers.js';
export function register(server: FastMCP) {
server.addTool({
name: 'applyTextStyle',
description:
'Applies character-level formatting (bold, italic, color, font, etc.) to text identified by a character range or by searching for a text string. This is the primary tool for styling text in a document.',
parameters: ApplyTextStyleToolParameters,
execute: async (args: ApplyTextStyleToolArgs, { log }) => {
const docs = await getDocsClient();
let { startIndex, endIndex } = args.target as any; // Will be updated if target is text
log.info(
`Applying text style in doc ${args.documentId}${args.tabId ? ` (tab: ${args.tabId})` : ''}. Target: ${JSON.stringify(args.target)}, Style: ${JSON.stringify(args.style)}`
);
try {
// Determine target range
if ('textToFind' in args.target) {
const range = await GDocsHelpers.findTextRange(
docs,
args.documentId,
args.target.textToFind,
args.target.matchInstance,
args.tabId
);
if (!range) {
throw new UserError(
`Could not find instance ${args.target.matchInstance} of text "${args.target.textToFind}"${args.tabId ? ` in tab ${args.tabId}` : ''}.`
);
}
startIndex = range.startIndex;
endIndex = range.endIndex;
log.info(
`Found text "${args.target.textToFind}" (instance ${args.target.matchInstance}) at range ${startIndex}-${endIndex}`
);
}
if (startIndex === undefined || endIndex === undefined) {
throw new UserError('Target range could not be determined.');
}
if (endIndex <= startIndex) {
throw new UserError('End index must be greater than start index for styling.');
}
// Build the request
const requestInfo = GDocsHelpers.buildUpdateTextStyleRequest(
startIndex,
endIndex,
args.style,
args.tabId
);
if (!requestInfo) {
return 'No valid text styling options were provided.';
}
await GDocsHelpers.executeBatchUpdate(docs, args.documentId, [requestInfo.request]);
return `Successfully applied text style (${requestInfo.fields.join(', ')}) to range ${startIndex}-${endIndex}${args.tabId ? ` in tab ${args.tabId}` : ''}.`;
} catch (error: any) {
log.error(`Error applying text style in doc ${args.documentId}: ${error.message || error}`);
if (error instanceof UserError) throw error;
if (error instanceof NotImplementedError) throw error; // Should not happen here
throw new UserError(`Failed to apply text style: ${error.message || 'Unknown error'}`);
}
},
});
}