Skip to main content
Glama
notes-tools.ts9.48 kB
import { Tool } from '@modelcontextprotocol/sdk/types.js' import { NotesApi } from '../api/notes.js' import { SidvyApiClient } from '../api/client.js' export class NotesTools { constructor( private notesApi: NotesApi, private client: SidvyApiClient, ) {} getTools(): Tool[] { return [ { name: 'list_notes', description: 'List notes with optional filtering and search capabilities', inputSchema: { type: 'object', properties: { workspaceId: { type: 'string', description: 'Filter by workspace ID' }, groupId: { type: 'string', description: 'Filter by group ID' }, search: { type: 'string', description: 'Search notes by name or content' }, isDeleted: { type: 'boolean', description: 'Include deleted notes (default: false)' }, sort: { type: 'string', enum: [ 'name:asc', 'name:desc', 'createdAt:asc', 'createdAt:desc', 'updatedAt:asc', 'updatedAt:desc', ], description: 'Sort order for results', }, limit: { type: 'number', minimum: 1, maximum: 100, description: 'Number of notes to return', }, }, additionalProperties: false, }, }, { name: 'create_note', description: 'Create a new note with markdown content', inputSchema: { type: 'object', properties: { name: { type: 'string', minLength: 1, maxLength: 200, description: 'Note title/name' }, content: { type: 'string', description: 'Note content in markdown format' }, workspaceId: { type: 'string', description: 'Workspace to create note in (optional, uses default)', }, groupId: { type: 'string', description: 'Group to organize note under (optional)' }, }, required: ['name'], additionalProperties: false, }, }, { name: 'update_note', description: "Update an existing note's content or metadata", inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Note ID to update' }, name: { type: 'string', minLength: 1, maxLength: 200, description: 'New note title/name', }, content: { type: 'string', description: 'New note content in markdown format' }, groupId: { type: 'string', description: 'Move note to different group (can be null)' }, }, required: ['id'], additionalProperties: false, }, }, { name: 'delete_note', description: 'Delete a note (moves to trash)', inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Note ID to delete' }, }, required: ['id'], additionalProperties: false, }, }, { name: 'search_notes', description: 'Search notes by content or title with full-text search', inputSchema: { type: 'object', properties: { query: { type: 'string', minLength: 1, description: 'Search query' }, workspaceId: { type: 'string', description: 'Workspace to search in (optional)' }, limit: { type: 'number', minimum: 1, maximum: 100, description: 'Number of results to return', }, }, required: ['query'], additionalProperties: false, }, }, { name: 'get_note', description: 'Get a specific note by ID', inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Note ID to retrieve' }, workspaceId: { type: 'string', description: 'Workspace to search in (optional)' }, }, required: ['id'], additionalProperties: false, }, }, { name: 'get_recent_notes', description: 'Get recently updated notes', inputSchema: { type: 'object', properties: { workspaceId: { type: 'string', description: 'Workspace to get notes from (optional)' }, limit: { type: 'number', minimum: 1, maximum: 50, description: 'Number of notes to return (default: 10)', }, }, additionalProperties: false, }, }, { name: 'append_to_note', description: 'Append content to an existing note', inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Note ID to append to' }, content: { type: 'string', description: 'Content to append' }, workspaceId: { type: 'string', description: 'Workspace to search note in (optional)' }, }, required: ['id', 'content'], additionalProperties: false, }, }, ] } async handleToolCall(name: string, arguments_: any): Promise<any> { switch (name) { case 'list_notes': return this.handleListNotes(arguments_) case 'create_note': return this.handleCreateNote(arguments_) case 'update_note': return this.handleUpdateNote(arguments_) case 'delete_note': return this.handleDeleteNote(arguments_) case 'search_notes': return this.handleSearchNotes(arguments_) case 'get_note': return this.handleGetNote(arguments_) case 'get_recent_notes': return this.handleGetRecentNotes(arguments_) case 'append_to_note': return this.handleAppendToNote(arguments_) default: throw new Error(`Unknown tool: ${name}`) } } private async handleListNotes(args: any) { const response = await this.notesApi.listNotes(args) if (this.client.isSuccessResponse(response)) { return { success: true, notes: response.data, pagination: response.meta?.pagination, count: response.meta?.count, } } else { throw new Error(this.client.getErrorMessage(response)) } } private async handleCreateNote(args: any) { const response = await this.notesApi.createNote(args) if (this.client.isSuccessResponse(response)) { return { success: true, note: response.data, message: `Note "${response.data.name}" created successfully`, } } else { throw new Error(this.client.getErrorMessage(response)) } } private async handleUpdateNote(args: any) { const response = await this.notesApi.updateNote(args) if (this.client.isSuccessResponse(response)) { return { success: true, note: response.data, message: `Note "${response.data.name}" updated successfully`, } } else { throw new Error(this.client.getErrorMessage(response)) } } private async handleDeleteNote(args: any) { const response = await this.notesApi.deleteNote(args) if (this.client.isSuccessResponse(response)) { return { success: true, deleted: response.data.deleted, noteId: response.data.noteId, movedToTrash: response.data.movedToTrash, message: 'Note moved to trash successfully', } } else { throw new Error(this.client.getErrorMessage(response)) } } private async handleSearchNotes(args: any) { const response = await this.notesApi.searchNotes(args.query, args.workspaceId, args.limit || 20) if (this.client.isSuccessResponse(response)) { return { success: true, notes: response.data, query: args.query, count: response.data.length, } } else { throw new Error(this.client.getErrorMessage(response)) } } private async handleGetNote(args: any) { const response = await this.notesApi.getNoteById(args.id, args.workspaceId) if (this.client.isSuccessResponse(response)) { if (response.data) { return { success: true, note: response.data, } } else { return { success: false, error: 'Note not found', } } } else { throw new Error(this.client.getErrorMessage(response)) } } private async handleGetRecentNotes(args: any) { const response = await this.notesApi.getRecentNotes(args.workspaceId, args.limit || 10) if (this.client.isSuccessResponse(response)) { return { success: true, notes: response.data, count: response.data.length, } } else { throw new Error(this.client.getErrorMessage(response)) } } private async handleAppendToNote(args: any) { const response = await this.notesApi.appendToNote(args.id, args.content, args.workspaceId) if (this.client.isSuccessResponse(response)) { return { success: true, note: response.data, message: `Content appended to note "${response.data.name}"`, } } else { throw new Error(this.client.getErrorMessage(response)) } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/martinhjartmyr/sidvy-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server