google-docs-mcp / src /clients.ts
iFightDucks's picture
Initial HF Space deploy: a-bonus/google-docs-mcp with HF metadata
7dc28be
// src/clients.ts
import { google, docs_v1, drive_v3, sheets_v4, script_v1, gmail_v1, calendar_v3 } from 'googleapis';
import { UserError } from 'fastmcp';
import { OAuth2Client } from 'google-auth-library';
import { authorize } from './auth.js';
import { logger } from './logger.js';
import { requestClients } from './remoteWrapper.js';
const isRemote = process.env.MCP_TRANSPORT === 'httpStream';
let authClient: OAuth2Client | null = null;
let googleDocs: docs_v1.Docs | null = null;
let googleDrive: drive_v3.Drive | null = null;
let googleSheets: sheets_v4.Sheets | null = null;
let googleScript: script_v1.Script | null = null;
let googleGmail: gmail_v1.Gmail | null = null;
let googleCalendar: calendar_v3.Calendar | null = null;
// --- Initialization ---
export async function initializeGoogleClient() {
if (googleDocs && googleDrive && googleSheets)
return {
authClient,
googleDocs,
googleDrive,
googleSheets,
googleScript,
googleGmail,
googleCalendar,
};
if (!authClient) {
try {
logger.info('Attempting to authorize Google API client...');
const client = await authorize();
authClient = client;
googleDocs = google.docs({ version: 'v1', auth: authClient });
googleDrive = google.drive({ version: 'v3', auth: authClient });
googleSheets = google.sheets({ version: 'v4', auth: authClient });
googleScript = google.script({ version: 'v1', auth: authClient });
googleGmail = google.gmail({ version: 'v1', auth: authClient });
googleCalendar = google.calendar({ version: 'v3', auth: authClient });
logger.info('Google API client authorized successfully.');
} catch (error) {
logger.error('FATAL: Failed to initialize Google API client:', error);
authClient = null;
googleDocs = null;
googleDrive = null;
googleSheets = null;
googleScript = null;
googleGmail = null;
googleCalendar = null;
throw new Error('Google client initialization failed. Cannot start server tools.');
}
}
if (authClient && !googleDocs) {
googleDocs = google.docs({ version: 'v1', auth: authClient });
}
if (authClient && !googleDrive) {
googleDrive = google.drive({ version: 'v3', auth: authClient });
}
if (authClient && !googleSheets) {
googleSheets = google.sheets({ version: 'v4', auth: authClient });
}
if (authClient && !googleScript) {
googleScript = google.script({ version: 'v1', auth: authClient });
}
if (authClient && !googleGmail) {
googleGmail = google.gmail({ version: 'v1', auth: authClient });
}
if (authClient && !googleCalendar) {
googleCalendar = google.calendar({ version: 'v3', auth: authClient });
}
if (!googleDocs || !googleDrive || !googleSheets) {
throw new Error('Google Docs, Drive, and Sheets clients could not be initialized.');
}
return {
authClient,
googleDocs,
googleDrive,
googleSheets,
googleScript,
googleGmail,
googleCalendar,
};
}
// --- Helper to get Docs client within tools ---
export async function getDocsClient() {
const remote = requestClients.getStore();
if (remote) return remote.docs;
if (isRemote) {
throw new UserError('Request context missing. Tool must be called within an MCP request.');
}
const { googleDocs: docs } = await initializeGoogleClient();
if (!docs) {
throw new UserError(
'Google Docs client is not initialized. Authentication might have failed during startup or lost connection.'
);
}
return docs;
}
// --- Helper to get Drive client within tools ---
export async function getDriveClient() {
const remote = requestClients.getStore();
if (remote) return remote.drive;
if (isRemote) {
throw new UserError('Request context missing. Tool must be called within an MCP request.');
}
const { googleDrive: drive } = await initializeGoogleClient();
if (!drive) {
throw new UserError(
'Google Drive client is not initialized. Authentication might have failed during startup or lost connection.'
);
}
return drive;
}
// --- Helper to get Sheets client within tools ---
export async function getSheetsClient() {
const remote = requestClients.getStore();
if (remote) return remote.sheets;
if (isRemote) {
throw new UserError('Request context missing. Tool must be called within an MCP request.');
}
const { googleSheets: sheets } = await initializeGoogleClient();
if (!sheets) {
throw new UserError(
'Google Sheets client is not initialized. Authentication might have failed during startup or lost connection.'
);
}
return sheets;
}
// --- Helper to get Auth client for direct API usage ---
export async function getAuthClient() {
const remote = requestClients.getStore();
if (remote) return remote.auth;
if (isRemote) {
throw new UserError('Request context missing. Tool must be called within an MCP request.');
}
const { authClient: client } = await initializeGoogleClient();
if (!client) {
throw new UserError(
'Auth client is not initialized. Authentication might have failed during startup or lost connection.'
);
}
return client;
}
// --- Helper to get Script client within tools ---
export async function getScriptClient() {
const remote = requestClients.getStore();
if (remote) return remote.script;
if (isRemote) {
throw new UserError('Request context missing. Tool must be called within an MCP request.');
}
const { googleScript: script } = await initializeGoogleClient();
if (!script) {
throw new UserError(
'Google Script client is not initialized. Authentication might have failed during startup or lost connection.'
);
}
return script;
}
// --- Helper to get Gmail client within tools ---
export async function getGmailClient() {
const remote = requestClients.getStore();
if (remote) return remote.gmail;
if (isRemote) {
throw new UserError('Request context missing. Tool must be called within an MCP request.');
}
const { googleGmail: gmail } = await initializeGoogleClient();
if (!gmail) {
throw new UserError(
'Gmail client is not initialized. Authentication might have failed during startup or lost connection.'
);
}
return gmail;
}
// --- Helper to get Calendar client within tools ---
export async function getCalendarClient() {
const remote = requestClients.getStore();
if (remote) return remote.calendar;
if (isRemote) {
throw new UserError('Request context missing. Tool must be called within an MCP request.');
}
const { googleCalendar: calendar } = await initializeGoogleClient();
if (!calendar) {
throw new UserError(
'Google Calendar client is not initialized. Authentication might have failed during startup or lost connection.'
);
}
return calendar;
}