feat(mcp): update server with hierarchy support, batch operations, and tree view
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 16s

This commit is contained in:
Antigravity
2026-05-10 19:12:55 +00:00
parent 210b01c385
commit a139f92686
4 changed files with 140 additions and 1 deletions

View File

@@ -204,6 +204,29 @@ const toolDefinitions = [
required: ['id'],
},
},
{
name: 'batch_move_notes',
description: 'Move multiple notes to a notebook simultaneously.',
inputSchema: {
type: 'object',
properties: {
ids: { type: 'array', items: { type: 'string' }, description: 'Array of Note IDs' },
notebookId: { type: 'string', description: 'Target notebook ID, or null for Inbox' },
},
required: ['ids'],
},
},
{
name: 'batch_delete_notes',
description: 'Permanently delete multiple notes.',
inputSchema: {
type: 'object',
properties: {
ids: { type: 'array', items: { type: 'string' }, description: 'Array of Note IDs' },
},
required: ['ids'],
},
},
{
name: 'toggle_pin',
description: 'Toggle the pin status of a note.',
@@ -264,6 +287,7 @@ const toolDefinitions = [
icon: { type: 'string', description: 'Icon (emoji)', default: '📁' },
color: { type: 'string', description: 'Hex color', default: '#3B82F6' },
order: { type: 'number', description: 'Sort position (auto if omitted)' },
parentId: { type: 'string', description: 'Parent notebook ID for sub-notebooks' },
},
required: ['name'],
},
@@ -293,6 +317,7 @@ const toolDefinitions = [
icon: { type: 'string' },
color: { type: 'string' },
order: { type: 'number' },
parentId: { type: 'string', description: 'Parent notebook ID (set to null to move to root)' },
},
required: ['id'],
},
@@ -321,6 +346,11 @@ const toolDefinitions = [
required: ['notebookIds'],
},
},
{
name: 'get_notebook_hierarchy',
description: 'Get a nested tree structure of all notebooks (parents and children).',
inputSchema: { type: 'object', properties: {} },
},
// ═══ LABELS ═══
{
@@ -546,6 +576,26 @@ export function registerTools(server, prisma) {
});
}
case 'batch_move_notes': {
const targetId = args.notebookId || null;
const ids = args.ids || [];
await prisma.note.updateMany({
where: { id: { in: ids }, ...(uid ? { userId: uid } : {}), trashedAt: null },
data: { notebookId: targetId, updatedAt: new Date() },
});
return textResult({ success: true, count: ids.length, notebookId: targetId });
}
case 'batch_delete_notes': {
const ids = args.ids || [];
await prisma.note.deleteMany({
where: { id: { in: ids }, ...(uid ? { userId: uid } : {}), trashedAt: null },
});
return textResult({ success: true, count: ids.length });
}
case 'toggle_pin': {
const note = await prisma.note.findUnique({
where: { id: args.id, ...(uid ? { userId: uid } : {}), trashedAt: null },
@@ -711,6 +761,7 @@ export function registerTools(server, prisma) {
icon: args.icon || '📁',
color: args.color || '#3B82F6',
order: nextOrder,
parentId: args.parentId || null,
userId: uid || await ensureUserId(),
},
include: { labels: true, _count: { select: { notes: true } } },
@@ -754,6 +805,7 @@ export function registerTools(server, prisma) {
if ('icon' in args) d.icon = args.icon;
if ('color' in args) d.color = args.color;
if ('order' in args) d.order = args.order;
if ('parentId' in args) d.parentId = args.parentId;
const where = { id: args.id, ...(uid ? { userId: uid } : {}) };
const notebook = await prisma.notebook.update({
@@ -799,6 +851,32 @@ export function registerTools(server, prisma) {
return textResult({ success: true });
}
case 'get_notebook_hierarchy': {
const where = uid ? { userId: uid } : {};
const notebooks = await prisma.notebook.findMany({
where,
include: {
_count: { select: { notes: true } },
},
orderBy: { order: 'asc' },
});
// Build tree
const nbMap = new Map();
notebooks.forEach(nb => nbMap.set(nb.id, { ...nb, notesCount: nb._count.notes, children: [] }));
const root = [];
nbMap.forEach(nb => {
if (nb.parentId && nbMap.has(nb.parentId)) {
nbMap.get(nb.parentId).children.push(nb);
} else {
root.push(nb);
}
});
return textResult(root);
}
// ═══ LABELS ═══
case 'create_label': {
const existing = await prisma.label.findFirst({