Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
CTXNEST_DB_PATHNoPath to the SQLite database. Defaults to $CTXNEST_DATA_DIR/ctxnest.db
CTXNEST_DATA_DIRYesPrimary storage for Knowledge Base and Backups. Must be set explicitly and point to the same directory the web UI uses.

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}
resources
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
create_fileA

Create a new markdown file in the knowledge base or project. This operation writes a new file to disk and adds it to the local SQLite FTS5 index. Destination can be 'knowledge' (global KB), 'project' (reference file inside a project repo), or 'ctxnest' (internal CtxNest schema file). If destination is 'project' or 'ctxnest', project_id is strictly required. No external auth required. Rate limits do not apply (local operation). Returns the created file metadata including its new ID, path, and estimated tokens. If the destination directory does not exist, it will be created automatically. Use this tool to instantiate new contextual documents or notes. To modify an existing file, use 'update_file' instead. Parameters: 'destination' dictates required fields; if 'project' or 'ctxnest', 'project_id' must be a valid integer. 'tags' and 'folder' are optional.

read_fileA

Read one file's full body and metadata by ID. Read-only; no side effects, auth, or rate limits. Returns title, path, content, tags, est_tokens (so you can budget context before opening more files), and timestamps. Throws if the ID is unknown. Use for a single known file. Prefer describe_file to inspect without paying body tokens; read_files for batches; read_file_lines/read_section for partial reads; read_file_by_path when you only have the absolute path.

read_filesA

Batch read up to 200 files by ID in one call. Returns per-file annotated records, an aggregate total_est_tokens, and an isolated errors[] (one bad ID does NOT abort the batch). Read-only; no side effects, auth, or rate limits. Use instead of looping read_file to halve round-trips and get the combined token cost upfront. For >200 IDs, page yourself.

describe_fileA

Return everything ABOUT a file without pulling its content (no token cost from the body). Tags, size, est_tokens, history depth, related-file ids, backlinks, project, folder, last edited. Operates locally with no auth or rate limits. Use this when you'd otherwise chain read_file + list_tags + get_history + find_related just to decide whether to actually read the file. Parameters: 'id' must be a valid integer file ID.

read_file_linesA

Return a 1-indexed inclusive line slice of a file. Out-of-range bounds clamp silently to the file's actual length; to < from throws. Read-only; no side effects, auth, or rate limits. Returns the snippet plus its size_bytes and est_tokens. Use to inspect a stack-trace region or a chunk of a large file without pulling the whole body. Prefer read_section if you know the heading, grep_in_file if you know a pattern but not the line number.

grep_in_fileA

Match a JS regex against one file's lines and return matched lines with line numbers (capped: default 100, max 500). Catches what FTS misses: URLs, hyphenated terms, code identifiers. Read-only; no side effects, auth, or rate limits. Invalid regex throws invalid regex. Returns {matches, match_count, truncated}. Use after read_file_outline when you know the file but need a specific reference; for cross-file regex use regex_search; for keyword/concept search use search.

regex_searchA

Match a JS regex against the body of every file in scope (project, KB, or all) and return per-file hits with line numbers. Slower than FTS search because it reads each file's content; use only when FTS misses substrings, URLs, or code identifiers. Read-only; no side effects, auth, or rate limits. Capped at 500 files / 10 hits per file by default; the response reports files_truncated and per-file truncation so the agent can re-scope. project_id: null = KB only; omit = everywhere. Invalid regex throws.

update_fileA

Update the entire content of an existing file by its ID. This replaces the file's content on disk and triggers an FTS5 re-index. Returns the updated file metadata including new estimated token counts. Operates locally with no external auth or rate limits. If you only need to modify a single section without replacing the entire file, use 'update_file_section' instead to save context budget. Parameters: 'id' must be a valid integer file ID. 'content' is the complete markdown string that will replace the file.

delete_fileA

DESTRUCTIVE. Permanently delete one file by ID. KB files are unlinked from disk AND removed from the FTS5 index; project reference files only have their index entry removed (the file on disk is left alone so the watcher does not fight your editor). Not idempotent — deleting an unknown ID throws. No external auth or rate limits. Returns {success: true}. Use only when the file is truly obsolete; to deprioritise without losing data, untag (remove_tags) or unfavorite (set_favorite) instead. Bulk variant: delete_files.

list_filesA

List file metadata with optional filters (project_id, tag, favorite, folder, untagged) and pagination. Read-only; no side effects, auth, or rate limits. Each row is annotated with tags, est_tokens, and size_bytes; the response includes total_est_tokens so you can budget before reading bodies. project_id: null returns ONLY Knowledge Base files; omit the field to span everything. Use to browse known structure; for keyword/content lookup use search; for a denser whole-vault dump use project_map.

searchA

Full-text (SQLite FTS5) keyword search across files. Returns ranked matches with inline match_excerpt and title_highlight (no follow-up read_file needed for snippets) plus tags, est_tokens, size_bytes, and aggregate total_est_tokens. Read-only; no side effects, auth, or rate limits. FTS is tokenised: it WILL miss URLs, hyphenated terms, and partial substrings — fall back to regex_search for those. project_id: null searches only the KB; omit the field to span everything; tags[] requires ALL listed tags to match. For prompt-ready bundled bodies use bundle_search.

bundle_searchA

Run an FTS search and concatenate matched bodies into a single prompt-ready bundle (XML <document> blocks or markdown headers + fences) capped at max_tokens. Files are added in rank order until the next would exceed the budget; the rest go to skipped[]. Read-only; no side effects, auth, or rate limits. Use instead of search + N×read_file when you need several related files as one context blob. Defaults: format=xml, max_tokens=50000. project_id: null = KB only; tags[] requires ALL to match.

add_tagsA

Append tags to ONE file. Additive — existing tags are preserved; re-adding an existing tag is a no-op (idempotent per tag). New tag names auto-create rows in the global tags table. Persists to local SQLite. No external auth or rate limits. Returns {success: true}; throws if file_id is unknown. Use to label a single file. To tag every file matching a query in one call use tag_search_results; to remove tags use remove_tags.

remove_tagsA

Detach one or more tag IDs from ONE file. Destructive on the link only — does NOT delete the file or the global tag definition (orphan tags survive in list_tags). Idempotent: removing an already-absent tag is a no-op. No external auth or rate limits. Returns {success: true}. Note: takes tag IDs (integers), not names — fetch them via list_tags. To remove ALL tags from many files via a query, see tag_search_results (additive only) — there is no bulk-untag-by-query tool.

set_favoriteA

Set or clear the favorite flag on one file (idempotent — re-setting the same value is a no-op; not a toggle, you pass the desired state). Persists to local SQLite. No external auth or rate limits. Returns {success: true}. Use to curate quick-access pins; list_files/search/bundle_search accept favorite: true to filter to the pinned set.

list_tagsA

List every tag in the global SQLite database with id, name, and applied count. Read-only; no side effects, auth, or rate limits. Returns the entire taxonomy (not paginated). Use to discover existing labels before tagging (so you reuse rather than fork) or to find tag IDs to feed into remove_tags. For tags on a specific file, use describe_file.

list_projectsA

List every registered project with id, name, absolute path, and a derived has_hands flag (true when the path exists on disk AND contains a ctxnest.json). Read-only; no side effects, auth, or rate limits. Use to find the project_id to pass to scoped tools (search, list_files, commit_backup, refresh_index, etc.). To register a new project use register_project; to inspect its Hands tools use list_hands.

register_projectA

Register a new project and link it to the CtxNest knowledge system.

SIDE EFFECTS: Writes project metadata to disk (persisted in the CtxNest data directory). Scans the project root recursively to discover and index all markdown files into the local database. Registers any ctxnest.json-declared Hands tools found in the project root. This operation is idempotent — re-registering an existing project updates its metadata without data loss.

AUTH / RATE LIMITS: None. Operates entirely on the local file system.

PARAMETERS:

  • name: Human-readable project name.

  • path: Absolute path to the project root. Required. If the user does not specify, use the current working directory. Fails with a descriptive error if the path does not exist or is inaccessible.

  • description: Optional free-text description stored with the project metadata.

RETURNS: A JSON object containing:

  • project: { id, name, path, description, created_at }

  • discovered_files_count: number of markdown files indexed

  • discovered_files: array of { path, est_tokens, size_bytes } for each file

  • total_est_tokens: estimated total token cost of all discovered files

  • hands: { found, tools_registered, tools_disabled, warnings }

  • warnings: array of non-fatal issues (e.g. scan failures, token budget exceeded)

ERROR CONDITIONS: Returns isError=true if path is missing or unresolvable. Scan failures are non-fatal and reported in warnings rather than as errors.

commit_backupA

SIDE-EFFECTFUL — TOUCHES THE NETWORK. Sync the project's KB data into its git backup directory, create a commit, and git push to origin. AUTH: relies on the local user's git credentials (SSH agent, credential helper, etc.) — there is no in-server auth. CtxNest does not rate-limit, but the remote may. Idempotent in steady state: a no-op commit is skipped, but the push still runs. Throws if the project has no configured backup repo or if push fails (network, auth, conflict). Returns {success, copied_files_count, copied_paths}. Use after a batch of KB writes to get changes off-machine.

clip_urlA

SIDE-EFFECTFUL — fetches an EXTERNAL URL and writes a NEW KB file. Downloads the page, extracts the main article via Readability, converts to markdown, and saves it as a new clipping. NOT idempotent / no de-dup — re-clipping the same URL creates a second file. AUTH: anonymous by default; pass headers (e.g. {Cookie: 'session=...'} or {Authorization: 'Bearer ...'}) to clip behind logins. CtxNest does not rate-limit but the upstream may throttle. On auth-required pages returns isError with code: AUTH_REQUIRED, optional login_url, and a hint to retry with headers. Returns {file_id, path, title, source}. Use to ingest external docs into the KB.

get_historyA

Return the git commit history for one file (newest first), each entry with hash, message, date, and author. Reads the file's owning repo: the project's git repo for project files, the KB backup repo for KB files. Read-only; no side effects, auth, or rate limits. Returns {file_id, path, history}; an empty array means the file has not been committed yet. Use to understand a file's evolution before editing or restoring. Pair with get_diff to see exact line changes; use restore_file to roll back.

get_diffA

Return the unified diff of one file between two commit hashes (typically obtained from get_history for the same file). Read-only; no side effects, auth, or rate limits. Order matters — commit_a is treated as the earlier side; reversing the args inverts the diff. Throws if either hash is unknown to the file's repo. Use after get_history to see WHAT changed, not just THAT it changed.

restore_fileA

DESTRUCTIVE. Overwrite a file's current on-disk content with the version recorded at a specific git commit, then re-index FTS. The hash MUST come from get_history for THIS file (foreign hashes throw). The current uncommitted content is lost unless it was already committed elsewhere. The file watcher may also pick up the change before this returns. No external auth or rate limits. Returns {file_id, path, hash, success, message}. Use only to undo accidental edits or recover a known-good version.

read_file_outlineA

Return a flat list of markdown headings for one file (level, text, line, byteStart, byteEnd). Read-only; no side effects, auth, or rate limits. Use as a cheap probe before read_section or update_file_section so you don't spend tokens on the full body just to learn what sections exist. Empty outline means the file has no markdown headings (it may still have content — fall back to read_file or read_file_lines).

read_sectionA

Return the body of ONE heading (the heading line itself is excluded) plus level, line, size_bytes, and est_tokens. Heading match is case-insensitive but exact-string after trim — fuzzy / partial matches do NOT resolve. Returns isError if the heading is absent. Read-only; no side effects, auth, or rate limits. Pair with read_file_outline when you are unsure which headings exist; for non-heading line ranges use read_file_lines.

update_file_sectionA

Surgical write — replace the body of ONE heading without touching siblings. The heading line itself is preserved verbatim; only its body is rewritten. Persists via the same path as update_file (writes to disk → FTS reindex → git commit). Throws if the heading does not exist (this tool will NOT create a new section — append the section text via update_file first). Heading match is case-insensitive exact-string. No external auth or rate limits. Returns the updated file metadata. Use to make targeted edits without re-sending the whole body; for full-file replacement use update_file.

list_foldersA

List folder paths under a project root (or the Knowledge Base when project_id is null/omitted). Returns {folders: string[], base_path} where folders are RELATIVE to base_path. Read-only; no side effects, auth, or rate limits. Throws if project_id references an unknown project. Use to discover where to drop a new file via create_file's folder argument or to navigate vault structure; to actually create one use create_folder.

create_folderA

Create a folder under a project root or the KB. Idempotent — creating an existing folder succeeds. Nested paths like notes/inbox create intermediates. REJECTS: empty names, null bytes, leading path separators, and any segment equal to .. (the call returns isError, no folder is touched). Side effect: a directory is mkdir'd on disk; no DB rows are written until a file lands inside. No external auth or rate limits. Returns {path, base_path}.

delete_folderA

DESTRUCTIVE — recursively delete a folder under the KB AND every file inside it (disk + FTS rows). REFUSES (returns isError) when project_id is supplied: deleting inside a registered project would race the file watcher and re-ingest the contents — remove project content via your editor instead. Same name validation as create_folder. Not recoverable from CtxNest after the call (only the git backup, if configured, retains it). No external auth or rate limits. Returns {success: true}.

move_fileA

Move/rename a file. Destination 'new_path' must be absolute and resolve INSIDE the file's owning project or global knowledge directory. Cross-project moves are rejected. Operates locally with no auth or limits. Parameters: 'file_id' is a valid file ID. 'new_path' is an absolute path.

find_relatedA

Find other files sharing tags with the given file, ranked by shared_tag_count descending. Read-only; no side effects, auth, or rate limits. Returns annotated file rows with shared_tag_count and shared_tags. Empty result means the file has no tags or no other file shares them — try search/regex_search for content-based discovery, or suggest_tags to bootstrap labels first. Default limit 10.

create_filesA

Batch variant of create_file — create up to 200 markdown files in one call. Each item follows the same rules (project_id required if destination is project or ctxnest). SIDE EFFECTS: writes new files to disk and inserts FTS5 rows; missing folders are mkdir'd. Per-item failures are isolated to errors[] and the rest of the batch still commits — partial success is the norm, always inspect error_count. No external auth or rate limits. Returns {created_count, error_count, created, errors}. Use for bulk ingestion; for >200 items, page yourself.

delete_filesA

DESTRUCTIVE batch — delete up to 500 files by ID in one call. Same physical-deletion rules as delete_file (KB files unlinked from disk; project reference files only de-indexed). Per-ID failures isolated to errors[]; the batch keeps going — partial success is the norm. Not idempotent — unknown IDs surface as per-item errors. No external auth or rate limits. Returns {deleted_count, error_count, deleted, errors}. To preview the set before deleting, run list_files with the same filter and confirm the IDs.

tag_search_resultsA

Bulk-tag — run an FTS search and append add_tags to every matching file in one call. Side effect: each match gets addTags applied (additive, idempotent per tag); the matched files themselves are NOT modified beyond their tag links. Per-file failures isolated to errors[]. No external auth or rate limits. There is NO dry-run flag, so ALWAYS run search with the same query first to verify the match set before tagging. The tags[] filter requires existing tags to ALL match (it scopes the search; it does not control which tags get added). Returns {matched_count, tagged_count, tags_applied, tagged_ids, errors}.

read_file_by_pathA

Look up a file by its absolute on-disk path and return the same shape as read_file. The path must EXACTLY match what CtxNest indexed — no symlink resolution, no path normalisation beyond what the OS does, no trailing-slash tolerance. Returns isError if no row matches (the file may exist on disk but not be indexed — try refresh_index). Read-only; no side effects, auth, or rate limits. Use when an agent has a path from its working directory but no file ID; if you have the ID, prefer read_file.

statsA

Aggregate counts for a scope: file_count, untagged_count, favorite_count, top_tags. With project_id omitted (everything), also returns by_project breakdown. include_token_total: true stat()s every matching file on disk to compute a body-size estimate — measurably slower on large vaults; default false. project_id: null = KB only; omit = all. Read-only; no side effects, auth, or rate limits. Use as a cheap dashboard or to spot untagged content for cleanup; for live disk-vs-index drift use diff_against_disk.

suggest_tagsA

Propose tags for a file by mining the existing tag corpus via FTS — picks distinctive terms from the file (≥4 chars, stopword-filtered) and returns tags applied to other files that score high on those terms. No LLM, no network. Already-applied tags are excluded so the suggestions are net-new. Read-only; no side effects, auth, or rate limits. Returns {file_id, path, existing_tags, suggestions: [{tag, score, sources}]}. Empty suggestions = no distinctive terms or no overlap with the existing taxonomy yet — bootstrap with add_tags first. Default limit 10, max 50. Suggestions are NOT auto-applied.

diff_against_diskA

Diagnose drift between one file's disk content and its FTS index. Status is one of in_sync, diverged, disk_unreadable, or no_index_row. On divergence returns sizes, line counts, the first divergent line number, and the disk vs index sample for that line — NOT a full diff (use get_diff for full diffs between commits). Read-only; no side effects, auth, or rate limits. Use when search results look stale; if status is diverged or no_index_row, run refresh_index to fix.

refresh_indexA

Reconcile the FTS index against disk. For a project (project_id set), re-runs discoverFiles. For the KB (project_id null/omitted), walks knowledge/, ingests new .md files, reindexes any whose content hash drifted, and PRUNES rows for files no longer on disk. SIDE-EFFECTFUL: writes/updates/deletes file and FTS rows (the prune is destructive on stale index rows but never deletes files from disk). Idempotent — running twice is a near no-op. Skips files >5MB and standard junk dirs (node_modules, .git, dist, build, etc.). No external auth or rate limits. Returns {scope, newly_indexed, refreshed, pruned}. Use after editing files outside CtxNest, or when diff_against_disk reports drift.

journal_appendA

Append a timestamped entry to today's (or date's) journal markdown at knowledge/journal/YYYY-MM-DD.md. Creates the file on first use of a date with a # Journal — DATE header; subsequent calls APPEND a new ## HH:MM:SS section without rewriting prior entries. Concurrent calls for the same date are serialised by an internal lock so entries are not lost. SIDE EFFECTS: writes the file (FTS reindex + git commit via the same path as update_file/create_file); on first use, creates with default tag ['journal'] (overridable). date must match YYYY-MM-DD or throws. No external auth or rate limits. Returns {file_id, path, date, time, appended_chars, est_tokens}.

whats_newA

List files created or modified since a checkpoint. since accepts ISO-8601 (2025-01-15T00:00:00Z) or relative durations (1h, 7d, 2w); invalid formats throw. Read-only; no side effects, auth, or rate limits. Returns annotated rows plus aggregate total_est_tokens so you can decide what to read next. CAVEAT: hard-deleted files are NOT surfaced — only mtime-driven changes. Defaults: include_tags=true, limit=200. project_id: null = KB only; omit = everything. Use at session start to catch up.

project_mapA

Return a compact indented outline of folders, file titles, tags, and IDs in a single dense block — substantially fewer tokens than the equivalent list_files JSON for the same scope. Read-only; no side effects, auth, or rate limits. Capped at max_lines (default 5000); the response reports est_tokens and emits a warning field if it exceeds CTXNEST_PROJECT_TOKEN_WARN. project_id: null = KB only; omit = everything. Defaults: include_tags=true, show_titles=true. Use to orient yourself in an unfamiliar vault or project; for keyword lookup use search.

list_handsA

List every Hands command tool currently registered, with project scope, tool name, danger level, confirmation flag, and description. Hands tools come from per-project ctxnest.json files loaded at register time. Read-only; no side effects, auth, or rate limits. Use to discover what side-effectful project commands the agent is permitted to run; for the ctxnest.json schema see describe_hands_schema; reload after editing one with reload_hands.

reload_handsA

Re-scan every registered project's ctxnest.json and rebuild the live Hands tool registry — newly-declared tools become callable immediately, removed tools disappear from tools/list. SIDE EFFECT is on the running MCP session's tool inventory only (no disk writes). Idempotent. No external auth or rate limits. Takes no parameters. Returns per-project load results (counts of registered/disabled tools and any validation warnings). Use after editing a ctxnest.json mid-session; for the schema see describe_hands_schema.

confirm_handA

Approve and EXECUTE a previously-issued Hands invocation by its single-use approval token. The token is returned by any confirm-required Hands tool; tokens expire after 60 seconds and CANNOT be reused. Side effect equals whatever the underlying Hand does — this can be highly destructive (running arbitrary shell commands, modifying files, etc.), so only call when the user has authorised the pending action. The token IS the auth (no external auth, no rate limits). Invalid, expired, or already-consumed tokens return an inert text response, NOT an error.

describe_hands_schemaA

Return the complete authoring reference for ctxnest.json: JSON schema, validation rules, security guarantees, limitations, and an annotated example. Static document — does not read any project file or DB row. Read-only; no side effects, auth, or rate limits. Takes no parameters. Use when helping a user write or fix a ctxnest.json; to see the loaded tools themselves use list_hands; to apply edits use reload_hands.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription
All ProjectsList of all registered projects

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/safiyu/ctxnest'

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