Skip to content

MCP tool reference

Corpus speaks the Model Context Protocol over one endpoint, authenticated with a personal access token. Every tool below is read out of the running server's registry, so this page cannot describe a tool the server does not have.

Endpoint

Add this to your MCP client configuration and replace the placeholder with a token from Settings.

{
  "mcpServers": {
    "corpus": {
      "url": "https://corpus.schupke.io/api/mcp",
      "headers": {
        "Authorization": "Bearer <YOUR_TOKEN>"
      }
    }
  }
}

Tools

33 tools — 11 available to a read token, 22 needing write scope.

list_tree

List vault treeread

List the vault as a tree of folders and notes. Omit `path` for the whole vault; pass a folder path to scope the tree to that subtree, and `depth` to limit how far down it goes.

NameTypeRequiredDescription
pathstringoptionalFolder to scope the tree to. Omit for the whole vault.
depthinteger1–10optionalHow many levels below `path` to include. Defaults to the whole subtree.

list_children

List folder childrenread

List the direct children of one folder (omit `path` for the vault root). Prefer this over list_tree when you only need one level — it never loads note bodies and never walks the whole vault. `depth` above 1 includes deeper descendants.

NameTypeRequiredDescription
pathstringoptionalFolder whose children are listed. Omit for the vault root.
depthinteger1–10optional1 lists direct children only; higher values include deeper descendants.
limitinteger1–5000optionalMaximum entries to return. The response sets `truncated` when the cap was reached.

stat

Inspect a pathread

Report whether a vault path is a note or a folder, with its id and canonical stored path. Use it instead of guessing a kind — note paths are stored without the `.md` extension. A note also reports a `docKind`: `canvas` means it holds a drawing, which the editing tools refuse to write text into.

NameTypeRequiredDescription
pathstringrequiredVault path to inspect. Note paths are stored without the `.md` extension.

get_document

Read a noteread

Read a note by vault-relative path. Returns id, path, kind, markdown content, and timestamps. A note whose kind is `canvas` holds a drawing rather than text, and its content is always empty.

NameTypeRequiredDescription
pathstringrequiredVault-relative path of the note to read.

get_document_by_id

Read a note by idread

Read a note by stable document UUID. Returns path, kind, markdown content, and timestamps. A note whose kind is `canvas` holds a drawing rather than text, and its content is always empty.

NameTypeRequiredDescription
documentIduuidrequiredStable document UUID, as returned by `stat` or any listing.

list_document_versions

List note versionsread

List saved version metadata for a note by vault-relative path.

NameTypeRequiredDescription
pathstringrequiredVault-relative path of the note whose versions are listed.

get_document_version

Read a note versionread

Read the archived markdown content for a saved note version by version UUID.

NameTypeRequiredDescription
versionIduuidrequiredVersion UUID, as returned by `list_document_versions`.

restore_document_version

Restore a note versionwrite

Restore a saved note version by version UUID. The restored content becomes current and archives the previous current content.

NameTypeRequiredDescription
versionIduuidrequiredVersion UUID to restore, as returned by `list_document_versions`.

create_document

Create a notewrite

Create a markdown note at the given vault-relative path, optionally with initial content. Missing parent folders are created. Fails when the path is taken unless `ifExists` is 'skip'.

NameTypeRequiredDescription
pathstringrequiredVault-relative path for the new note, without the `.md` extension.
contentstringoptionalInitial markdown body. The note starts empty when omitted.
ifExists"error" | "skip"optional'error' (the default) fails when the path is taken; 'skip' leaves the existing entry alone.

update_document

Overwrite a notewrite

Overwrite the markdown body of a note, creating it (and any missing parent folders) when it does not exist. A previous version is archived only when the content actually changed.

NameTypeRequiredDescription
pathstringrequiredVault-relative path of the note to overwrite. Created when it does not exist.
contentstringrequiredThe complete new markdown body. It replaces the note entirely.

append_document

Append to a notewrite

Append text to the end of an existing note, atomically. Prefer this over reading a note and writing it back: a concurrent edit cannot be lost. By default a newline is inserted first when the note does not already end with one. Empty text is a no-op and does not archive a version.

NameTypeRequiredDescription
pathstringrequiredVault-relative path of the note to append to.
textstringrequiredMarkdown added at the end of the note. Empty text is a no-op.
ensureLeadingNewlinebooleanoptionalInsert a newline first when the note does not already end with one. Defaults to true.

replace_in_document

Substitute text in a notewrite

Find and replace inside one note, server-side. `mode` 'literal' treats `find` as plain text; 'regex' matches each line separately, so `^` and `$` anchor per line and a pattern cannot span a newline. `dryRun` reports what would change without writing. A run that changes nothing leaves the note, and its modified time, untouched.

NameTypeRequiredDescription
pathstringrequiredVault-relative path of the note to edit.
findstringmax 1000 charsrequiredThe text or regular expression to search for, per `mode`.
replacestringrequiredWhat each match becomes. Empty string deletes the match.
mode"literal" | "regex"optional'literal' (the default) treats `find` as plain text; 'regex' matches line by line.
ignoreCasebooleanoptionalMatch without regard to case. Defaults to false.
allbooleanoptionalReplace every match rather than only the first. Defaults to false.
maxReplacementsinteger1–9007199254740991optionalStop after this many replacements.
dryRunbooleanoptionalReport what would change without writing anything.

delete_document

Delete a notewritedestructive

Delete a note at the given vault path.

NameTypeRequiredDescription
pathstringrequiredVault-relative path of the note to delete.

create_spreadsheet

Create a spreadsheetwrite

Create a spreadsheet at the given vault-relative path, optionally with initial cells. Missing parent folders are created. Fails when the path is taken unless `ifExists` is 'skip'.

NameTypeRequiredDescription
pathstringrequiredVault-relative path for the new spreadsheet.
cellsobject[]optionalInitial cells. The sheet starts empty when omitted.
ifExists"error" | "skip"optional'error' (the default) fails when the path is taken; 'skip' leaves the existing entry alone.

get_spreadsheet

Read a spreadsheetread

Read a spreadsheet. Returns `tsv`, a tab-separated rendering with one line per row, and `cells`, the raw text of every filled cell keyed by A1 reference. Formulas are returned as written, not as their results.

NameTypeRequiredDescription
pathstringrequiredVault-relative path of the spreadsheet to read.

set_cells

Write cells in a spreadsheetwrite

Write individual cells, leaving every other cell as it is. Send an empty string to clear a cell. The sheet grows to cover any cell written past its current extent. Formatting already on a cell is kept.

NameTypeRequiredDescription
pathstringrequiredVault-relative path of the spreadsheet.
cellsobject[]requiredCells to write. Anything not listed is left as it is.
snapshotbooleanoptionalArchive the sheet as it was before this write, so the change can be reverted.

replace_spreadsheet

Replace a spreadsheet's cellswritedestructive

Replace every cell in a spreadsheet with the given set, discarding anything not listed. Use `set_cells` to change part of a sheet; this is for rewriting one wholesale. Cell formatting is discarded with the old cells.

NameTypeRequiredDescription
pathstringrequiredVault-relative path of the spreadsheet.
cellsobject[]requiredThe complete new set of cells. Anything omitted is cleared.
snapshotbooleanoptionalArchive the sheet as it was before this write, so the change can be reverted.

create_folder

Create a folderwrite

Create a folder at the given vault path, creating any missing parents. Fails when the path is taken unless `ifExists` is 'skip'.

NameTypeRequiredDescription
pathstringrequiredVault path for the new folder. Missing parents are created.
ifExists"error" | "skip"optional'error' (the default) fails when the path is taken; 'skip' leaves the existing folder alone.

move_entry

Move or renamewrite

Move a note or folder to an explicit destination path — re-parent, rename, or both in one call. When `to` names an existing folder the entry moves into it keeping its own name (as `mv` does). Missing parent folders are created. `kind` is inferred unless given.

NameTypeRequiredDescription
fromstringrequiredCurrent vault path of the note or folder to move.
tostringrequiredDestination path. Naming an existing folder moves the entry into it under its own name.
kind"file" | "dir"optionalWhether the path is a note ('file') or a folder ('dir'). Inferred when omitted.

rename

Rename in placewrite

Rename a note or folder, keeping its parent. `kind` is inferred when omitted. Prefer move_entry, which can rename and re-parent in one call.

NameTypeRequiredDescription
pathstringrequiredVault path of the note or folder to rename.
newNamestringrequiredThe new name, without any slashes. The parent is unchanged.
kind"file" | "dir"optionalWhether the path is a note ('file') or a folder ('dir'). Inferred when omitted.

move

Move under a parentwrite

Move a note or folder under a new parent folder, keeping its name. Omit `toParent` for the vault root. Prefer move_entry, which takes a full destination path.

NameTypeRequiredDescription
fromstringrequiredCurrent vault path of the note or folder to move.
toParentstringoptionalFolder to move it under, keeping its name. Omit for the vault root.

delete_path

Delete a note or folderwritedestructive

Delete a note or folder at the given vault path, with everything under it. `kind` is inferred when omitted; a path claimed by both a note and a folder is refused rather than guessed. `recursive` defaults to true; pass false to refuse a folder instead, which lets a client enforce an `rm -r` style guard without a separate lookup.

NameTypeRequiredDescription
pathstringrequiredVault path of the note or folder to delete.
kind"file" | "dir"optionalWhether the path is a note ('file') or a folder ('dir'). Inferred when omitted.
recursivebooleanoptionalDefaults to true. Pass false to refuse the call when the path is a folder.

list_tags

List tagsread

List the tag library with how many notes and folders carry each tag. A tag with zero uses is normal: tags outlive their assignments and are only removed by delete_tag.

Takes no parameters.

get_tags

Get an entry's tagsread

Read the tags on one note or folder, by vault path.

NameTypeRequiredDescription
pathstringrequiredVault path of the note or folder.
kind"file" | "dir"optionalWhether the path is a note ('file') or a folder ('dir'). Inferred when omitted.

create_tag

Create a tagwrite

Create a tag in the library without attaching it to anything. Only needed to pick a colour up front — set_tags and add_tags create missing tags on their own. Fails when the name is taken, ignoring case.

NameTypeRequiredDescription
namestringmax 64 charsrequiredTag name. Stored with this casing; matched ignoring case.
colorstring | nulloptionalHex colour, '#rgb' or '#rrggbb'. Omit or pass null for no colour.

update_tag

Rename or recolour a tagwrite

Rename a tag, change its colour, or both. Renaming keeps every assignment. Pass color: null to clear the colour; omit the field to leave it alone.

NameTypeRequiredDescription
idstringrequiredTag id, from list_tags.
namestringmax 64 charsoptionalNew name. Omit to keep the current one.
colorstring | nulloptionalNew hex colour, or null to clear it. Omit to leave the colour unchanged.

delete_tag

Delete a tagwritedestructive

Remove a tag from the library. Allowed while it is in use: every note and folder carrying it loses it. This is the only thing that removes a tag — nothing prunes unused ones.

NameTypeRequiredDescription
idstringrequiredTag id, from list_tags.

set_tags

Replace an entry's tagswrite

Replace the whole tag set on one note or folder. Pass an empty array to clear it. Prefer add_tags or remove_tags when changing one tag, since those cannot clobber a concurrent edit to another.

NameTypeRequiredDescription
pathstringrequiredVault path of the note or folder.
tagsstring[]0–50 itemsrequiredTag names. Any name that does not exist yet is created, so there is no separate create step. Matching ignores case: 'Work' finds an existing 'work'.
kind"file" | "dir"optionalWhether the path is a note ('file') or a folder ('dir'). Inferred when omitted.

add_tags

Add tags to an entrywrite

Add tags to a note or folder, leaving the ones already on it alone. Names that do not exist yet are created.

NameTypeRequiredDescription
pathstringrequiredVault path of the note or folder.
tagsstring[]0–50 itemsrequiredTag names. Any name that does not exist yet is created, so there is no separate create step. Matching ignores case: 'Work' finds an existing 'work'.
kind"file" | "dir"optionalWhether the path is a note ('file') or a folder ('dir'). Inferred when omitted.

remove_tags

Remove tags from an entrywrite

Take tags off a note or folder. The tags stay in the library; only the assignments go. Names not on the entry are ignored.

NameTypeRequiredDescription
pathstringrequiredVault path of the note or folder.
tagsstring[]0–50 itemsrequiredTag names. Any name that does not exist yet is created, so there is no separate create step. Matching ignores case: 'Work' finds an existing 'work'.
kind"file" | "dir"optionalWhether the path is a note ('file') or a folder ('dir'). Inferred when omitted.

bulk_move

Move many entries at oncewrite

Move or rename up to 100 notes and folders in a single transaction — either all of them move or none do. Each entry gives its own destination, so one call can re-parent some entries and rename others. When a `to` names an existing folder the entry moves into it keeping its own name. Prefer this over repeating move_entry: it is atomic, and it counts as one request against the rate limit.

NameTypeRequiredDescription
entriesobject[]1–100 itemsrequiredThe moves to apply, up to 100. All of them succeed or none do.

bulk_delete

Delete many entries at oncewritedestructive

Delete up to 100 notes and folders in a single transaction — either all of them go or none do. A folder takes everything under it. Naming both a folder and something inside it is fine: the inner path is covered by the folder and is not reported separately. A path claimed by both a note and a folder is refused rather than guessed. `recursive` defaults to true and applies to the whole batch; pass false to refuse the batch if any entry is a folder.

NameTypeRequiredDescription
pathsstring[]1–100 itemsrequiredVault paths to delete, up to 100. All of them go or none do.
recursivebooleanoptionalDefaults to true, and applies to the whole batch. False refuses a batch containing a folder.