import { z } from 'zod';
import type { MCPTool, MCPToolHandler } from '../types.js';
import { getToolContext, getApiBaseUrl } from '../utils/api.js';
export const memoCreateTool: MCPTool = {
name: 'memo_create',
description: 'Creates a new memo by AI assistant. Created memos require user approval and will be saved as regular memos after approval. Channel ID is optional, and the currently active channel is used when omitted.',
inputSchema: {
type: 'object',
properties: {
content: {
type: 'string',
description: 'Memo content (Markdown format)',
minLength: 1
},
channelId: {
type: 'string',
description: 'Channel ID to create memo in (defaults to currently active channel if omitted)'
},
metadata: {
oneOf: [
{ type: 'string' },
{ type: 'object' }
],
description: 'Metadata related to the memo (JSON string or object)'
},
originalId: {
type: 'string',
description: 'Original memo ID for ReMemo'
}
},
required: ['content']
}
};
export const handleMemoCreate: MCPToolHandler = async (args: any) => {
try {
const schema = z.object({
content: z.string().min(1),
channelId: z.string().optional(),
metadata: z.union([z.string(), z.record(z.any())]).optional(),
originalId: z.string().optional()
});
const { content, channelId, metadata, originalId } = schema.parse(args);
const toolContext = await getToolContext();
const targetChannelId = channelId || toolContext.activeChannelId;
if (!targetChannelId) {
return {
content: [
{
type: 'text',
text: JSON.stringify({
success: false,
error: 'No channel ID specified and no active channel is set',
memo: null
})
}
]
};
}
const draftMemoData = {
content,
channelId: targetChannelId,
type: 'assistant',
metadata: metadata ? (typeof metadata === 'string' ? JSON.parse(metadata) : metadata) : null,
originalId: originalId || null,
isRememo: !!originalId,
hasAttachment: false,
approvalStatus: 'pending'
};
const response = await fetch(`${getApiBaseUrl()}/api/draft-memos`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(draftMemoData)
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({})) as { error?: string };
return {
content: [
{
type: 'text',
text: JSON.stringify({
success: false,
error: `API Error: ${response.statusText} - ${errorData.error || 'Unknown error'}`,
memo: null
})
}
]
};
}
const result = await response.json() as { draftMemo: any };
return {
content: [
{
type: 'text',
text: JSON.stringify({
success: true,
message: 'Memo created successfully. Waiting for user approval.',
memo: result.draftMemo
})
}
]
};
} catch (error: unknown) {
const errorMessage = error instanceof Error ? error.message : String(error);
return {
content: [
{
type: 'text',
text: JSON.stringify({
success: false,
error: `Error occurred during memo creation: ${errorMessage}`,
memo: null
})
}
]
};
}
};