/**
* MCP Tool Handlers for Yuque operations
* 语雀操作MCP工具处理器
*/
import { YuqueClient } from '../yuque-client.js';
import { CallToolRequest } from '@modelcontextprotocol/sdk/types.js';
export interface ToolHandlerContext {
client: YuqueClient;
}
/**
* Handle tool execution requests
*/
export async function handleTool(
request: CallToolRequest,
{ client }: ToolHandlerContext
) {
const { name, arguments: args } = request.params;
try {
switch (name) {
case 'yuque_get_user':
return await handleGetUser(client);
case 'yuque_get_repos':
return await handleGetRepos(client, args as { userId?: string });
case 'yuque_get_docs':
return await handleGetDocs(
client,
args as { repoId: number; limit?: number; offset?: number }
);
case 'yuque_get_doc':
return await handleGetDoc(
client,
args as { docId: number; repoId: number }
);
case 'yuque_create_doc':
return await handleCreateDoc(
client,
args as {
repoId: number;
title: string;
content: string;
format?: 'markdown' | 'lake' | 'html';
}
);
case 'yuque_update_doc':
return await handleUpdateDoc(
client,
args as {
docId: number;
repoId: number;
title?: string;
content?: string;
format?: 'markdown' | 'lake' | 'html';
}
);
case 'yuque_delete_doc':
return await handleDeleteDoc(
client,
args as { docId: number; repoId: number }
);
case 'yuque_search_docs':
return await handleSearchDocs(
client,
args as { query: string; repoId?: number }
);
case 'yuque_create_repo':
return await handleCreateRepo(
client,
args as {
name: string;
description?: string;
isPublic?: boolean;
}
);
default:
throw new Error(`Unknown tool: ${name}`);
}
} catch (error) {
throw new Error(
`Error executing ${name}: ${
error instanceof Error ? error.message : String(error)
}`
);
}
}
/**
* Tool handler implementations
*/
async function handleGetUser(client: YuqueClient) {
const user = await client.getUser();
return {
content: [
{
type: 'text',
text: JSON.stringify(user, null, 2),
},
],
};
}
async function handleGetRepos(client: YuqueClient, args: { userId?: string }) {
const repos = await client.getRepos(args.userId);
return {
content: [
{
type: 'text',
text: JSON.stringify(repos, null, 2),
},
],
};
}
async function handleGetDocs(
client: YuqueClient,
args: { repoId: number; limit?: number; offset?: number }
) {
const docs = await client.getDocs(args.repoId, {
limit: args.limit,
offset: args.offset,
});
return {
content: [
{
type: 'text',
text: JSON.stringify(docs, null, 2),
},
],
};
}
async function handleGetDoc(
client: YuqueClient,
args: { docId: number; repoId: number }
) {
const doc = await client.getDoc(args.docId, args.repoId);
return {
content: [
{
type: 'text',
text: JSON.stringify(doc, null, 2),
},
],
};
}
async function handleCreateDoc(
client: YuqueClient,
args: {
repoId: number;
title: string;
content: string;
format?: 'markdown' | 'lake' | 'html';
}
) {
const doc = await client.createDoc(
args.repoId,
args.title,
args.content,
args.format
);
return {
content: [
{
type: 'text',
text: JSON.stringify(doc, null, 2),
},
],
};
}
async function handleUpdateDoc(
client: YuqueClient,
args: {
docId: number;
repoId: number;
title?: string;
content?: string;
format?: 'markdown' | 'lake' | 'html';
}
) {
const doc = await client.updateDoc(
args.docId,
args.repoId,
args.title,
args.content,
args.format
);
return {
content: [
{
type: 'text',
text: JSON.stringify(doc, null, 2),
},
],
};
}
async function handleDeleteDoc(
client: YuqueClient,
args: { docId: number; repoId: number }
) {
await client.deleteDoc(args.docId, args.repoId);
return {
content: [
{
type: 'text',
text: '文档删除成功 (Document deleted successfully)',
},
],
};
}
async function handleSearchDocs(
client: YuqueClient,
args: { query: string; repoId?: number }
) {
const docs = await client.searchDocs(args.query, args.repoId);
return {
content: [
{
type: 'text',
text: JSON.stringify(docs, null, 2),
},
],
};
}
async function handleCreateRepo(
client: YuqueClient,
args: {
name: string;
description?: string;
isPublic?: boolean;
}
) {
const repo = await client.createRepo(
args.name,
args.description,
args.isPublic || false
);
return {
content: [
{
type: 'text',
text: JSON.stringify(repo, null, 2),
},
],
};
}