org-lsp

MCP

org-lsp mcp is a Model Context Protocol server: it gives an AI assistant (Claude Code, Claude Desktop, Cursor and others) your agenda as Org builds it, so it can answer "what is due this week" or "what is tagged work" from your Org files rather than from searching their text, and reads an entry whole, the clock report, org-roam's notes and org-journal's entries. It only reads, unless you let it change TODO states, dates, tags, properties and notes, capture, refile, archive and delete (Changing files). Its prompts ask the assistant to plan your day, review your week or go through your inbox, with the data that takes (Prompts).

Setting it up#

The agenda files and options are those of the shared configuration file (~/.config/org-lsp/config.toml, see Configuration): set org_agenda_files there, and org-lsp config shows what is read. They are read again at each call. With no org_agenda_files, the agenda is built from the Org files under the directory the server runs in.

org_agenda_files = ["~/org"]

The assistant runs org-lsp mcp over standard input and output. In Claude Code:

claude mcp add org-lsp -- org-lsp mcp

In Claude Desktop, Cursor and the like, in their MCP settings:

{
  "mcpServers": {
    "org-lsp": { "command": "org-lsp", "args": ["mcp"] }
  }
}

Give the full path of org-lsp when it is not on the PATH the assistant starts it with (where the editor plugins downloaded it, for example).

Tools#

Each view answers its text, as org-lsp agenda prints it and Org's agenda shows it, and each entry's line ends with where its headline is: its file and line, from 1.

Global list of TODO items of type: ALL
  tasks:      TODO Write the report                                    :work:  [tasks.org:12]

The file goes by its name when no other agenda file has the same, else by its path. It is what set_todo_state, refile and the other tools that change an entry take.

agenda
the agenda of some days (org-agenda-list); span (day, week, the default, fortnight, month, year or a number of days), start (a day it includes, YYYY-MM-DD), log (what was closed and clocked).
todo_list
the TODO entries not done (org-todo-list), or those of keywords (NEXT|WAIT).
tags_search
the entries a match string selects (org-tags-view), only those with a TODO keyword with todo_only.
text_search
the entries whose text has the words of query (org-search-view), only those with a TODO keyword not done with todo_only.
custom_agenda
a command of org_agenda_custom_commands, by its key.
agenda_files
the files the agenda is built from.
capture_templates
the capture templates (org_capture_templates): each one's key, description, type, target and template, and the questions it asks.
refile_targets
the places an entry can be refiled to, as org-refile finds them (org_refile_targets, by default the top-level headlines of the entry's file) and names them in its prompt (org_refile_use_outline_path), each followed by where it is: Projects/Garden/ [projects.org:4], or [projects.org] for the top level of a file. file is the file of the entry to refile: the targets of the current file are its headlines, and its own are named without their file, as org-refile offers them there; without it, those are the agenda files' headlines, and every target names its file, as from the agenda. filter keeps the targets whose name has its text. It is there with mcp_edits off too.
entry
the whole text of an entry: file and line are the [file:line] of a view, and headline, as for set_todo_state, text the headline has. It answers where the entry is, its outline path, category, TODO keyword, SCHEDULED, DEADLINE and CLOSED, its tags and those it inherits (org_use_tag_inheritance, org_tags_exclude_from_inheritance), its properties and those it inherits (org_use_property_inheritance, marked (inherited)), the time clocked in its subtree and in the entry itself, and a clock running in it; then its subtree, or with subtree false the entry alone, up to its first child. It reads the agenda files, and org-journal's and org-roam's files when they are on.
clock_report
the clock table org-clock-report writes for the agenda files (:scope agenda), with org_clock_clocktable_default_properties, org_clocktable_defaults and the other clock table options: what is between its #+BEGIN: and #+END: lines, the caption and the table. span is its :block (today, yesterday, thisweek, lastweek, thismonth, lastmonth, thisyear, lastyear, or a period such as 2026-10, 2026-W42 or 2026-10-21); or start and end are days, end included (:tstart, and :tend the day after); with none of them, all the time clocked. file makes the table of one agenda file, as org-clock-report in it (:scope file); maxlevel is its :maxlevel.
roam_find
org-roam's nodes as org-roam-node-find offers them, a line for each title and alias formatted with org_roam_node_display_template, the files changed last first; then, for an alias, the node's title, its tags, its ID and where it is. query keeps the lines that have all its words, in any case.
roam_node
an org-roam node, by its title, an alias or its ID (node): where it is, its aliases, tags and references, its text (the file for a file's node, else its subtree), then the sections of the org-roam buffer that org_roam_mode_sections lists, as it shows them: Backlinks and Reflinks, each place with the outline path to it, where it is and the text around it, and Unlinked References, also with unlinked, each line that names the node.
journal_entries
org-journal's entries of the day date (by default today), or of the days from start to end, each as org-journal-read-entry finds it, with its day and where it is: the headline of its date and its subtree, or the whole file of the day when org_journal_date_prefix makes no headline.

roam_find and roam_node say that org-roam is not enabled unless org_roam_enabled is on, and journal_entries the same of org-journal and org_journal_enabled. They read the files on disk again at each call, as org-roam-db-sync would, and keep no database.

What differs from the editor's agenda#

The tools build the agenda with the settings the server builds it with (TODO keywords, priorities, tags, habits, the clock report, custom commands, org-journal's files), but start no Emacs: a diary sexp that calls other Lisp (%%(my-function)) shows nothing, and a %(…) in org_agenda_prefix_format is left empty. Settings given only in the editor (its own options rather than the configuration file) are not seen. clock_report does not know the editor's clock, so the time of a clock running counts only once it is stopped (org_clock_report_include_clocking_task has nothing to count).

Changing files#

With mcp_edits on in the configuration file, the assistant also gets tools that change files. They go through the code the editor's commands go through, with the same settings, and say what Emacs says.

mcp_edits = true
set_todo_state
change the TODO state of an entry, as org-todo does. file and line are the [file:line] of a view (a path works too); state is a keyword, or "" for none; note is the note of a state that asks for one (@ in org_todo_keywords, or org_log_done "note"); headline is text the headline has, such as its title, and when the line no longer has it the file has changed and nothing is done. It logs as org_log_done, org_log_into_drawer and the keywords' ! and @ say; a repeating entry gets its next date and stays not done; with org_enforce_todo_dependencies, a blocked entry is refused with Org's message. It answers Org's message, if there is one, and the new headline.
capture
file a new entry with one of the capture templates, as org-capture does with :immediate-finish. template is its key; text is what %i puts in, or, in a template without %i, what goes where %? is, as if typed in the capture buffer; answers answers the template's questions (%^{Prompt}, %^t, %^g, %^{NAME}p, and Date for tree entry with time_prompt), as an object from each prompt to its answer or a list in the order they are asked; link and description are the link of %a and %l. A question left without an answer is refused, with the list of the questions, for the assistant to ask you. The target file is made when it is not there. It answers the file, the line and the text filed.
refile
move an entry and its subtree under another headline, as org-refile does: its levels change to fit there, and it goes last among the target's children, or first with org_reverse_note_order. file, line and headline are as for set_todo_state; target is a name refile_targets gives (from the entry's file or without one), the [file:line] of a target, or a file alone for its top level when the files are targets (org_refile_use_outline_path "file", "title" or "full-file-path"). With copy the entry stays where it is too (org-refile-copy). It logs as org_log_refile says: with "note", the note is note, and without one it is refused. With org_refile_allow_creating_parent_nodes, a target, a / and a new headline make that headline under the target first ("confirm" wants create too). An entry refiled into itself or its own subtree is refused with Org's message. It answers Org's message (Refile to "Garden/" in file /home/me/org/projects.org: done) and where the entry is now: its file, line and headline.
schedule, deadline
set the entry's SCHEDULED or DEADLINE date, as org-schedule and org-deadline do. date is read as Org's date prompt reads what you type (org-read-date, with org_read_date_prefer_future and the other org_read_date options): 2026-11-03, 2026-11-03 10:00, +2d, fri, 10am, from the date the entry has. The old date's repeater is kept; a date written as a timestamp brings its own (<2026-11-03 +1w>), as org-schedule called with a time string does. remove takes the date out (C-u C-c C-s). A date the entry had is logged as org_log_reschedule and org_log_redeadline say (or #+STARTUP: logreschedule); when they ask for a note, it is note, and without one the change is refused. It answers Org's message (Scheduled to <2026-11-03 Tue>).
set_tags
replace the entry's tags with tags, a list or a string of tags separated by colons, as org-set-tags-command sets what you type; [] removes them. They are aligned at org_tags_column.
set_property
set the property name to value in the entry's property drawer, as org-set-property does (org_property_format). When the property has allowed values (NAME_ALL, org_global_properties), only one of them will do; an empty value keeps the value it has, as Org's prompt does. TODO, PRIORITY, SCHEDULED and DEADLINE change the keyword, the priority and the dates as Org does (the last two as schedule and deadline, an empty value taking the date out); note is the note a TODO change asks for.
delete_property
delete the property name of the entry, and its drawer when it is left empty (org-delete-property). A name the entry does not have is refused, as Org's prompt takes only the entry's.
set_priority
set the entry's priority as org-priority does: priority is a letter or a number in the range of org_priority_highest and org_priority_lowest (or the file's #+PRIORITIES), or "" to remove it. Out of range, it is refused with Org's message.
set_effort
set the entry's Effort property, as org-set-effort does: value is a duration (0:30, 2h, 1d, the units of org_duration_units), one of the allowed values (Effort_ALL) when there are some.
add_note
add the note note to the entry, as org-add-note does: with its heading of org_log_note_headings, in the drawer of org_log_into_drawer or under the headline, first or last as org_log_states_order_reversed says.
archive
archive the entry and its subtree. method subtree, the default, moves it to its archive file as org-archive-subtree does: where org_archive_location, the file's #+ARCHIVE or an ARCHIVE property says, with what org_archive_save_context_info keeps and as the other org_archive options say; the archive file is made when it is not there. to_sibling moves it under its parent's Archive sibling (org-archive-to-archive-sibling, org_archive_sibling_heading), and toggle_tag sets or takes out its ARCHIVE tag (org-toggle-archive-tag). It archives only from an agenda file. It answers Org's message (Subtree archived in file: /home/me/org/tasks.org_archive) and where the entry is now.
delete_entry
delete the entry and its subtree, as org-cut-subtree takes it out: from its headline to the next headline of its level or above, with the blank lines before that one. headline is required here, so that the entry deleted is the one meant. It deletes only in an agenda file. It answers Org's message (Cut: Subtree(s) with 51 characters) and the text deleted, which put back at the entry's line restores it.

These tools take the entry as set_todo_state does: file, line and headline. They answer Org's message, if there is one, and the entry's headline as it is now.

All of them take dry_run: they answer the change as a diff of each file it changes, and write nothing.

They change only the agenda files and the targets of the capture templates, refile the files of org_refile_targets too, archive only the agenda files and their archive files (that of org_archive_location, and those an agenda file names with #+ARCHIVE or an ARCHIVE property when they are in the directory of an agenda file or below), and delete_entry only the agenda files. What needs Emacs or the editor is refused: a template with %(…) or a function target, a clock target or clock_in, as there is no clock, and refiling while org_refile_target_verify_function is set (both refile_targets and refile refuse then). org_capture_templates_contexts is not looked at: every template can be used. Stopping the clock of an entry that is done (org_clock_out_when_done) is left to the editor.

The files are written directly, each at once (into a file beside it, which then takes its place), and read again at each call. A refile to another file writes two: the target first, then the file the entry came from, so that if the second write fails the entry is in both files, never in none; refiling within a file is one write. Archiving to an archive file writes it first in the same way, then the file the entry came from. A file that is read-only is not written (Buffer is read-only: #<buffer tasks.org>), nor one that has changed since the tool read it, as when an editor saved it meanwhile: nothing is written then, and the tool says so. No editor is asked: one that has the file open with unsaved changes may save over the change, or ask which to keep. Save your files before an assistant changes them, and use dry_run to see a change first.

Prompts#

The server also has prompts: messages you send the assistant, which bring the data of a task, read from your files at that moment as the tools read them, and say what to do with it. Claude Code shows them as slash commands, /mcp__org-lsp__plan_my_day and so on, their arguments after them (/mcp__org-lsp__plan_my_day 2026-10-23); other assistants list them in their own way. Dates are YYYY-MM-DD.

plan_my_day
the agenda of the day date (by default today), the TODO entries with a deadline in the next 14 days or past, and those in progress (the keywords not done that start no sequence and say no waiting, such as NEXT; the whole TODO list when there are none). It asks for a plan of the day in time blocks, its conflicts, and to schedule what the plan gives a time.
weekly_review
the agenda of the week of week (a day of it; by default this week) in log mode, what was closed and clocked, the clock report of the week, the stuck projects (org_stuck_projects) and the agenda of the next week. It asks for a review: what got done, what slipped, what is stuck, the priorities of the next week, and changes.
process_inbox
the entries of the inbox, each with its [file:line] and text, the refile targets from the inbox's file, the tags in use (org_tag_alist and the agenda files') and the TODO keywords. The inbox is the headline headline (a title, or an outline path A/B) of file, or its top level without headline; by default the target of the first capture template (a file, or a headline or outline path in it), else the first Inbox headline of the agenda files. It asks for a refile target, tags, a TODO state and a date for each entry.
daily_standup
the agenda of the day before date (by default today) in log mode and its clock report, the agenda of date, and the TODO entries whose keyword says they wait (WAITING, HOLD, BLOCKED, DELEGATED and the like). It asks for a short standup: yesterday, today, blockers.
find_stale_tasks
the open TODO entries of the agenda files with no date in the last days days (30 by default) nor one ahead: no SCHEDULED or DEADLINE, clock, logged note or other timestamp in the entry since then; the oldest first. It asks what to do with each: reschedule, close, archive, delete or keep.

The prompts that may lead to changes (all but daily_standup) tell the assistant to propose them first, show each with dry_run, ask you to confirm, and only then make them with the edit tools, which are there with mcp_edits on; without it, to tell you what to change.