{"name":"io.github.nicolascroce/keepsake","slug":"nicolascroce-keepsake","title":null,"description":"MCP server for Keepsake — the personal CRM for nurturing your relationships","url":"https://mcp.market/server/nicolascroce-keepsake","rating":null,"grade":"B","score":80,"certified":false,"status":"active","category":"sales","tags":["sales"],"presence":{"score":27,"stars":1,"forks":2,"downloads_week":72,"last_push_at":"2026-09-06T10:15:11.000Z","license":"MIT"},"uptime":null,"claimed":false,"transport":"npm","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/nicolascroce/keepsake-mcp","website":null,"version":"1.10.0","remotes":[],"packages":[{"registryType":"npm","identifier":"keepsake-mcp","version":"1.10.0","transport":{"type":"stdio"},"environmentVariables":[{"description":"Your Keepsake API key (starts with ksk_). Get one at https://keepsake.place → Account → API Keys.","isRequired":true,"format":"string","isSecret":true,"name":"KEEPSAKE_API_KEY"}]}],"tools":[{"name":"archive_note","description":"Transform a QuickNote into a permanent Note (archive it). Notes appear on contact pages, tag pages, and the Notes section.","write_action":false,"price_micros":0,"input_schema":null},{"name":"complete_task","description":"Mark a task as completed. If the task is recurring, this automatically creates the next occurrence.","write_action":false,"price_micros":0,"input_schema":null},{"name":"create_company","description":"Create a new company/organization. Only 'name' is required.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_contact","description":"Create a new contact. first_name is required. last_name is optional (useful for contacts where you only know the first name).","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_day_block","description":"Create a time block on a day's timeline. The block is auto-placed in the earliest free gap large enough for it (same first-fit engine as the app); pass anchor_time to pin it at a fixed hour instead. Its \"b:<id>\" ref is inserted into the day's timeline_order for you — never write timeline_order by hand.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_entry","description":"An ENTRY is a dated interaction log tied to contacts. Records something that happened (call, meeting, email…) on a specific date. Create a new interaction entry. Content supports #tag# and [[tag]] syntax for automatic tag linking.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_note","description":"Create a new QuickNote in the Inbox. QuickNotes are temporary captures — use archive_note to transform one into a permanent Note. Content supports #tag# and [[tag]] for automatic tag linking. Pass `dates` to attach the note to one or more days (\"note for tomorrow\", meeting prep for Thursday): it then surfaces in that day's view while staying in the notes list. A dated note is NOT a task (no action","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_note_comment","description":"","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_tag","description":"A TAG is a thematic grouping space. Syntax: #name# or [[name]]. Groups notes, entries, tasks, and contacts. Create a new tag. If a tag with the same name already exists, returns the existing tag.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_task","description":"A TASK is an action item to accomplish. Can have due date, recurrence, priority, linked to contacts and tags. Create a new task. Title supports #tag# and [[tag]] for automatic tag linking.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_task_header","description":"Create a new task header (section separator). Add it to a tag's items_order to position it.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_company","description":"Soft-delete a company. Use permanent=true for hard delete.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_contact","description":"Permanently delete a contact and all associated data.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_day_block","description":"Delete a time block. Its ref is pruned from the day's timeline_order; for a task bucket, the tasks themselves are untouched (they fall back to the day's computed bucket).","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_entry","description":"Delete an interaction entry.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_note","description":"Soft-delete a QuickNote or Note. Use permanent=true for hard delete.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_note_comment","description":"Delete a marginalia. Marginalia are temporary by design, so this is the normal way to retire one — there is no recoverable middle state.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_tag","description":"Permanently delete a tag and all its links to contacts, entries, tasks, notes, and companies.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_task","description":"Delete a task.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_task_header","description":"Permanently delete a task header.","write_action":true,"price_micros":0,"input_schema":null},{"name":"get_agent_instructions","description":"Get best practices and instructions for being an effective Keepsake AI agent. Call this at the start of each session to refresh your instructions.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_changelog","description":"Get all items modified since a given timestamp, across all entity types. Perfect for 'heartbeat' checks to see what changed since your last visit. Returns server_time to use as 'since' for the next call.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_company","description":"Get a single company by ID, including linked contacts (with roles) and tags.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_contact","description":"Get a single contact by ID, including recent entries (interactions), tags, last_interaction_date, and total_entries count.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_contact_timeline","description":"Get a unified, chronological feed of ALL items related to a contact — entries, tasks, and notes — sorted by date (most recent first). Much more efficient than fetching entries, tasks, and notes separately.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_day","description":"Get a specific day by date: its intention or question of the day (field `note`, one short line) AND the notes linked to that day (field `notes`, via link_note_date / `dates`). Always 200 — `exists: false` means no intention is stored yet, the linked notes are returned regardless.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_note","description":"Get a single note by ID, including its tags, linked contacts, linked tasks, linked notes and the days it is linked to (`dates`). Use this when the user points you at one specific note (e.g. gives you its URL — the UUID is the last path segment) instead of listing everything.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_tag","description":"Get a single tag by ID with all its properties (name, description, color, icon, view mode, favorite status). Includes tasks_order, the manual ordering of the tag page's task list, where entries of the form \"h:<header_id>\" are section separators (see list_task_headers).","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_tag_items","description":"Get items linked to a tag. By default returns every type in full — on large tags that can be a huge response, so prefer types/status/summary to narrow it (e.g. types=['tasks'], status='pending', summary=true to review a project's open tasks). When tasks are included, the response also contains `sections`: the tag page's task sections with their task_ids (header_id null = tasks outside any section)","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_task_header","description":"Get a single task header by ID.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_tasks_overdue","description":"Get only overdue tasks (pending tasks with a due date before today). Sorted by date ascending (oldest first).","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_tasks_today","description":"Get all tasks for today: overdue tasks + tasks due today + ASAP tasks. Each task has a 'category' field ('overdue', 'today', or 'asap'). Includes counts per category.","write_action":false,"price_micros":0,"input_schema":null},{"name":"link_entry_contact","description":"Link an existing contact to an entry.","write_action":false,"price_micros":0,"input_schema":null},{"name":"link_note_contact","description":"Link an existing contact to a note.","write_action":false,"price_micros":0,"input_schema":null},{"name":"link_note_date","description":"Link a note to a calendar day. The note then surfaces in that day's view (Today / Day page) while staying in the notes list — the note is the same object, the date is just another way in. Use it for \"note for tomorrow\", \"what to bring Thursday\", meeting prep for a given date. Idempotent. A note can be linked to several days. This is NOT the day's intention (update_day) and NOT a task (create_task)","write_action":false,"price_micros":0,"input_schema":null},{"name":"link_notes","description":"Link two notes together (knowledge base, N-N, non-destructive). The link is symmetric: both notes list each other in their linked-notes section. Use this to connect related ideas — e.g. a note that made you think of another one. Notes can also be linked inline by writing [label](note:uuid) in a note's content.","write_action":false,"price_micros":0,"input_schema":null},{"name":"link_tag","description":"Link an entity (contact, entry, task, note, or company) to a tag.","write_action":false,"price_micros":0,"input_schema":null},{"name":"link_task_contact","description":"Link an existing contact to a task.","write_action":false,"price_micros":0,"input_schema":null},{"name":"link_task_note","description":"Link an existing note to a task (non-destructive, N-N). The note stays in the inbox/notes list and the task keeps a live link back to it — use this instead of deleting a note after creating a task from it. The note shows its linked tasks; the task shows the source note.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_companies","description":"List all companies/organizations in the user's Keepsake CRM. Supports pagination and sorting.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_contacts","description":"List all contacts in the user's Keepsake CRM. Supports pagination, sorting, and optional last_interaction_date enrichment.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_day_blocks","description":"List the time blocks of a day's timeline (Day view), in timeline order. A block is either an activity (type 'block') or a task bucket (type 'tasks' — groups the day's untimed tasks). The meta carries the day's raw timeline_order: \"b:<uuid>\" refs are blocks, bare uuids are tasks inside a bucket's run.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_days","description":"List days with their intention or question of the day (field `note`). Filter by date range.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_entries","description":"List interaction entries (calls, emails, meetings, events, etc.). Supports filtering by type, contact, and date range.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_note_comments","description":"List the marginalia attached to a note. A marginalia is working material the user keeps ALONGSIDE a note without it entering the text: an idea, a reference, a link, an excerpt pasted to rewrite a passage later. They are never published, and they are meant to be TEMPORARY — anything worth keeping becomes a note or a linked task. Each one is either attached to a specific passage (`quote` is set) or ","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_notes","description":"List notes. QuickNotes (inbox, not yet archived) and Notes (archived, permanent). Filter by pinned or archived status, or by the day(s) a note is linked to (`date`, or `date_from`/`date_to`) — e.g. \"what did I note for tomorrow?\". Each note carries `dates`, the days it is linked to.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_tags","description":"List tags (lightweight: the manual tasks_order arrays are omitted — use get_tag for a tag's full ordering). Tags organize contacts, entries, tasks, notes, and companies. Use q to find a tag by name.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_task_headers","description":"List all task headers (section separators used to group tasks on tag pages and day views).","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_tasks","description":"List tasks. Filter by status (pending/completed), date_type, or specific date.","write_action":false,"price_micros":0,"input_schema":null},{"name":"pin_note","description":"Pin a QuickNote or Note so it appears at the top of the Inbox.","write_action":false,"price_micros":0,"input_schema":null},{"name":"restore_note","description":"Restore a Note back to a QuickNote in the Inbox (unarchive), or restore a deleted note from trash.","write_action":false,"price_micros":0,"input_schema":null},{"name":"search","description":"Search across all Keepsake data — contacts, entries, tasks, notes, and companies. Search is accent-insensitive (e.g., 'berenice' finds 'Bérénice').","write_action":false,"price_micros":0,"input_schema":null},{"name":"search_companies","description":"Search companies by name, email, website, or address. Search is accent-insensitive.","write_action":false,"price_micros":0,"input_schema":null},{"name":"search_contacts","description":"Search contacts by name, email, company, etc. Search is accent-insensitive.","write_action":false,"price_micros":0,"input_schema":null},{"name":"snooze_task","description":"Reschedule a task to a new date.","write_action":false,"price_micros":0,"input_schema":null},{"name":"uncomplete_task","description":"Mark a completed task as pending again.","write_action":false,"price_micros":0,"input_schema":null},{"name":"unlink_entry_contact","description":"Remove the link between a contact and an entry.","write_action":true,"price_micros":0,"input_schema":null},{"name":"unlink_note_contact","description":"Remove the link between a contact and a note.","write_action":true,"price_micros":0,"input_schema":null},{"name":"unlink_note_date","description":"Remove a note from a calendar day (the note survives, untouched). To MOVE a note to another day, prefer update_note with the new `dates` array — one call instead of two. Idempotent.","write_action":true,"price_micros":0,"input_schema":null},{"name":"unlink_notes","description":"Remove the manual link between two notes (both notes survive). Links derived from inline [label](note:uuid) markdown in a note's content are preserved — edit the content to remove those.","write_action":true,"price_micros":0,"input_schema":null},{"name":"unlink_tag","description":"Remove the link between an entity and a tag.","write_action":true,"price_micros":0,"input_schema":null},{"name":"unlink_task_contact","description":"Remove the link between a contact and a task.","write_action":true,"price_micros":0,"input_schema":null},{"name":"unlink_task_note","description":"Remove the link between a note and a task. Both the task and the note survive.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_company","description":"Update an existing company. Only send the fields you want to change.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_contact","description":"Update an existing contact. Only send the fields you want to change.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_day","description":"Create or update a day's intention or question of the day (upsert on the date). The `note` field is the intention or question of the day — one short line at the top of the Today view (a mantra, an intention, a single priority, or a question to keep in mind). Not a journal: never write a summary of the day here. NOT for attaching a note to a day: this field is a single line and you would overwrite ","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_day_block","description":"Update a time block (title, duration, anchor, note, done). Only send fields you want to change. The block keeps its position in the timeline order.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_entry","description":"Update an existing entry. Only send fields you want to change.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_note","description":"Update an existing QuickNote or Note. `dates` REPLACES the full set of days the note is linked to — the way to move a note to another day (\"not done, push it to tomorrow\"). To add or remove a single day without touching the others, prefer link_note_date / unlink_note_date.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_note_comment","description":"Edit the content of a marginalia. There is no intermediate state: a marginalia exists, or it is deleted. A remark that should outlive the note's revision becomes a note or a linked task instead.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_tag","description":"Update an existing tag. Only send the fields you want to change. Supports name, description, color, icon, view mode, and favorite status.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_task","description":"Update an existing task. Only send fields you want to change.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_task_header","description":"Update a task header. Only send the fields you want to change.","write_action":true,"price_micros":0,"input_schema":null}],"scan":{"score":80,"grade":"B","scanned_at":"2026-09-20T05:07:36.494Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-20T05:07:36.453Z","components":{"code":{"score":25,"max":25,"notes":["3 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":6,"max":15,"notes":["static API keys via environment variables"]},"maintenance":{"score":15,"max":15,"notes":["last push 14 days ago"]},"identity":{"score":6,"max":10,"notes":["registry namespace matches repository owner"]}},"findings":[],"inputs":{"packages":[{"registryType":"npm","identifier":"keepsake-mcp","version":"1.10.0","found":true,"license":"MIT","hasInstallScripts":false,"dependencyCount":2,"publishedAt":"2026-09-06T10:15:09.148Z","weeklyDownloads":72}],"repo":{"found":true,"owner":"nicolascroce","repo":"keepsake-mcp","archived":false,"pushedAt":"2026-09-06T10:15:11Z","stars":1,"forks":2,"openIssues":1,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/253745541?v=4","ownerCreatedAt":"2026-01-08T15:01:48Z","license":"MIT"},"icon":{"url":"https://avatars.githubusercontent.com/u/253745541?v=4&s=128","source":"github"},"presence":{"stars":1,"forks":2,"downloadsWeek":72,"license":"MIT","lastPushAt":"2026-09-06T10:15:11.000Z","score":27}}}},"grade_history":[],"reviews":[]}