MCP Tools Reference

This document describes every tool the ThinkForge MCP server exposes to connected AI clients. Each tool is called through JSON-RPC 2.0 via tools/call with a tool name and arguments object. Results are returned as JSON inside the MCP content envelope.

All tools that access project data accept an optional project parameter. When omitted, the tool operates against the currently active project in ThinkForge. When provided, it must match a project name returned by list_projects.

Tools that query indexed content require SK Memory. If it is not initialized, those tools return: { "error": "SK Memory is not initialized. Open a project in Fire first." } The list_projects and get_project_instructions tools do not require SK Memory.

If a named project is not found, tools return: { "error": "Project not found: 'name'. Call list_projects to see available projects." }

Recents Integration

Successful save_artifact and save_artifacts items, update_document writes, and set_project_instructions writes advance the shared recent-document history and record ThinkForge MCP as the last successful save source. The physical write is enough to qualify even when later SK indexing reports a failure, because the saved file is still available for navigation.

move_document remaps an existing recent row and preserves its prior position and save provenance; it does not make a never-used document recent. Search, read, tag, statistics, indexing, and reconciliation tools do not advance Recents.

AI Activity Integration

Successful save_artifact, save_artifacts, update_document, move_document, index_document, and set_project_instructions calls add completed-operation rows to the active project's AI Activity feed. Failed calls, reads, searches, tag queries, statistics, reconciliation, and Mind Map operations do not add rows. Activity records the operation, project-relative path, completion time, and document ID when one is returned; it does not copy document content or identify the calling MCP client.

Response Size

Search defaults are deliberately conservative because every result enters the calling model's context. Search tools return chunks rather than whole documents, and the client is expected to raise max_results when a first pass does not find what it needs. Full document content is available only through the explicit get_memory and get_document_by_path tools.

Tool result JSON is serialized without indentation. These limits are not user-configurable.

Active Mind Map Boundary

mindmap_get_context, mindmap_find_nodes, mindmap_search_nodes, and mindmap_apply_patch operate against the currently active Mind Map in the requested active project. The caller must provide the exact immutable Mind Map document ID. A closed or inactive map, project mismatch, or document-ID mismatch is refused. These tools do not discover maps or execute ThinkForge Tool Agents.

mindmap_get_context

Returns the selected node, ancestors, bounded descendants, relationships, privacy-filtered attachment descriptors, and the revision required for a later patch.

Parameters

  • document_id (required) — Exact Mind Map document ID supplied by the initiating ThinkForge surface
  • node_id (required) — Exact selected node ID
  • depth — Descendant depth from 0 through 4. Default: 2
  • project — Project name. Default: active project

The result includes resolved_attachments effective at the selected node. Local references and inherited Entire-branch references are included; Private notes and attachment bodies are excluded. Use normal document tools to retrieve a referenced file's content.

mindmap_find_nodes

Finds active-map nodes by case-insensitive title text. Exact-title matches come first, and duplicate titles remain separate results with exact node IDs and ancestry paths.

Parameters

  • document_id (required) — Exact Mind Map document ID
  • query (required) — Title text
  • limit — Maximum matches from 1 through 50. Default: 20
  • project — Project name. Default: active project

mindmap_search_nodes

Searches the active Mind Map by meaning using its node-aware SK Memory index. Use it for discovery, comparison, brainstorming, and planning when title search is too narrow.

Parameters

  • document_id (required) — Exact Mind Map document ID
  • query (required) — Natural-language question or concept
  • limit — Maximum matches from 1 through 50. Default: 10
  • project — Project name. Default: active project

Matches include the exact live node ID and current path, a bounded indexed excerpt, ranking score and mode, indexed revision, and staleness state. A missing or older-format index asks the user to save the map. Search is discovery evidence, not edit authority: call mindmap_get_context for the exact returned node before changing it.

mindmap_apply_patch

Applies one ordered batch of 1 through 50 operations to the active Mind Map as a single transaction.

Parameters

  • document_id (required) — Exact immutable Mind Map document ID
  • expected_revision (required) — Latest revision returned by mindmap_get_context
  • operations (required) — Ordered patch operations
  • project — Project name. Default: active project

Supported operations are add_child, add_sibling, duplicate_node, duplicate_branch, update_node, move_node, delete_node, delete_branch, add_semantic_link, and remove_semantic_link. Creation and duplication can define a request-local reference for later operations in the same batch; ThinkForge still allocates every persisted node ID.

The complete batch is validated on a detached snapshot. A stale revision, invalid operation, or unresolved target leaves the live map unchanged. Deletion batches pause for one ThinkForge-owned confirmation showing the affected paths and counts. A declined confirmation or a revision change while it is open also leaves the map unchanged. An accepted batch becomes one Undo unit and saves through the owning Mind Map rather than editing .mmdata directly.

Combined semantic and keyword search. The recommended default for most queries. Falls back to keyword-only search if embeddings are unavailable for the target project.

Parameters

  • query (required) — Natural language search query
  • max_results — Maximum results to return. Default: 5
  • file_type — Filter by document type: conversation, markdown, code, csv, json, mindmap, or omit for all types
  • project — Project name. Default: active project

Response

{
  "results": [
    {
      "chunk_id": "string",
      "document_id": "string",
      "content": "string",
      "document_title": "string",
      "relative_path": "string",
      "absolute_path": "string",
      "file_type": "string",
      "similarity": 0.85,
      "search_type": "hybrid"
    }
  ],
  "embeddings_enabled": true,
  "result_count": 5
}

The embeddings_enabled field indicates whether semantic search was available. When false, results come from keyword matching only.

Pure vector similarity search using local embeddings. Returns results ranked by similarity. Requires embeddings to be available.

Parameters

  • query (required) — Natural language search query
  • max_results — Maximum results to return. Default: 5
  • file_type — Filter by document type
  • min_similarity — Minimum cosine similarity threshold, 0.0–1.0. Default: 0.5
  • project — Project name. Default: active project

Response

Same structure as hybrid_search. The search_type field reads "semantic". If embeddings are disabled, the tool returns an error rather than falling back to keyword search.

search_all_projects

Searches across every project on the machine at once. Each project is queried individually, results are merged and ranked by similarity score, and each result is tagged with its source project.

Parameters

  • query (required) — Natural language search query
  • max_results — Maximum total results after merging. Default: 10
  • results_per_project — Maximum results pulled from each project before merging. Default: 5
  • file_type — Filter by document type
  • search_mode"hybrid" (default) or "semantic". If a project has embeddings disabled, semantic mode falls back to hybrid for that project only

Response

{
  "results": [
    {
      "project": "Project Name",
      "chunk_id": "string",
      "document_id": "string",
      "content": "string",
      "document_title": "string",
      "relative_path": "string",
      "absolute_path": "string",
      "file_type": "string",
      "similarity": 0.82,
      "search_type": "hybrid"
    }
  ],
  "result_count": 12,
  "projects_searched": ["Project A", "Project B"],
  "projects_skipped": ["Project C (error: ...)"],
  "search_mode": "hybrid"
}

Results are sorted by similarity descending and capped at max_results. The projects_skipped array shows projects that could not be searched and why.

This tool opens every project's SK Memory database in turn, so it costs more time than a single-project search. Prefer hybrid_search with a known project when the target project is known.

Searches by document tags. Supports AND logic (all required tags must be present) and OR logic (any matching tag qualifies). Both can be combined in a single query.

Parameters

  • required_tags — Array of tag names. All must be present on a document for it to match (AND logic)
  • any_tags — Array of tag names. At least one must be present (OR logic)
  • max_results — Maximum results. Default: 20
  • project — Project name. Default: active project

Response

{
  "results": [
    {
      "document_id": "string",
      "title": "string",
      "file_type": "string",
      "tags": ["tag1", "tag2"],
      "created_at": "string",
      "content_preview": "First 200 characters of content..."
    }
  ],
  "result_count": 3
}

The content_preview is truncated to 200 characters with "..." appended.

get_memory

Retrieves a full document by ID. Optionally includes all indexed chunks for reading the complete content of a file.

Parameters

  • id (required) — Document ID (from search results or known IDs)
  • include_chunks — Include all chunks for this document. Default: false
  • context_window — Reserved. Any positive value currently behaves exactly like include_chunks: true. Default: 0
  • project — Project name. Default: active project

Response

{
  "document": {
    "id": "string",
    "title": "string",
    "file_type": "string",
    "mime_type": "string",
    "content": "string",
    "file_size": 4096,
    "is_indexed": true,
    "created_at": "string",
    "updated_at": "string",
    "tags": ["tag1", "tag2"]
  },
  "chunks": [
    {
      "id": "string",
      "content": "string",
      "chunk_index": 0,
      "token_count": 512
    }
  ]
}

The chunks array is null when neither include_chunks nor context_window is specified. If the document ID is not found, the tool returns: { "error": "Document not found: {id}" }

Two known limitations apply. When chunks are requested the response carries the document's full text in document.content and the same text again as chunks, so the content is returned twice. And context_window does not narrow the result to a window of surrounding chunks; there is no anchor chunk parameter, and every chunk for the document is returned regardless of the value supplied. Callers that want a small amount of context should leave both parameters off and rely on search excerpts.

list_projects

Lists all Fire projects on the machine, including external projects linked via .fire-link files.

Parameters

None.

Response

{
  "projects": [
    {
      "name": "Project Name",
      "path": "C:/path/to/project",
      "has_memory": true,
      "is_external": false
    }
  ],
  "project_count": 5,
  "projects_root": "C:/path/to/projects"
}

Projects are sorted by name. The has_memory field indicates whether SK Memory has been initialized for the project. External projects (linked via .fire-link files) have is_external: true.

get_project_instructions

Returns the persistent ThinkForge Project Instructions from THINKFORGE.md in a project's physical root. Clients should call this once before using other ThinkForge tools for that project.

Parameters

  • project — Project name. Default: active project

Response

{
  "project": "Think Forge Docs",
  "status": "loaded",
  "has_instructions": true,
  "file_name": "THINKFORGE.md",
  "content": "# ThinkForge Project Instructions\n...",
  "content_hash": "sha256-value",
  "reload_policy": "restart_thinkforge",
  "error": null
}

status is loaded, empty, not_found, or error. Missing and empty files are normal results. ThinkForge caches the first result for each project, including missing files and failures, until the application restarts. The file must be valid UTF-8 and no larger than 64 KB.

set_project_instructions

Creates or replaces the reserved root THINKFORGE.md. When the file already exists, expected_content_hash is required and must match the latest hash returned by get_project_instructions. This prevents an MCP client from overwriting a newer version.

Parameters

  • content (required) — Complete replacement content, up to 64 KB of UTF-8 text
  • expected_content_hash — Required when replacing an existing file; omit only when creating it
  • project — Project name. Default: active project

The write is atomic, the physical file is indexed after saving, the file is recorded in Recents with ThinkForge MCP save provenance, and the response includes reload_required: true. The current process continues using the instructions it previously cached; restart ThinkForge to load the new version.

get_document_by_path

Reads a physical project text document by project-relative path. Unlike get_memory, this reads the current file on disk and returns content_hash, which is required for safe updates and moves.

Parameters

  • path (required) — Project-relative document path
  • project — Project name. Default: active project

The response includes the complete UTF-8 content, current hash, size, modified time, and whether the file currently has an SK Memory record. The reserved THINKFORGE.md must be read through get_project_instructions so its read-once policy cannot be bypassed.

Inline read limit: Because this content goes directly into the calling model's context, documents larger than 200 KB are refused rather than returned. The refusal carries success: false, too_large: true, the path, the actual bytes, and limit_bytes:

{
  "success": false,
  "too_large": true,
  "project": "Project Name",
  "path": "Folder/Large Document.md",
  "bytes": 731904,
  "limit_bytes": 204800,
  "error": "The document is 714 KB, above the 200 KB inline read limit. ..."
}

No content and no content_hash are returned in this case. That is deliberate: pairing truncated content with a valid hash would allow a caller to write the truncation back through update_document and destroy the remainder of the document. A document over the limit therefore cannot be updated or moved through MCP until it is split into smaller documents. Use hybrid_search to locate the relevant sections of an oversized document.

The 200 KB ceiling applies only to this read tool. update_document and move_document still read up to 4 MB internally for hash comparison, so documents between 200 KB and 4 MB remain writable by any caller that already holds a valid hash.

update_document

Replaces an existing physical text document and then re-indexes it. It never creates a new filename and cannot update THINKFORGE.md.

Parameters

  • path (required) — Project-relative document path
  • content (required) — Complete replacement content
  • expected_content_hash (required) — Hash from the latest get_document_by_path result
  • project — Project name. Default: active project

The tool refuses stale hashes and documents currently open in ThinkForge. Paths must remain inside project content and cannot pass through hidden folders, system folders, symbolic links, or reparse points. A successful physical update advances the document in Recents and records ThinkForge MCP as the save source.

There is no partial-update or append operation. Every revision requires sending the complete replacement content, so editing one line of a large document costs a full read and a full write.

move_document

Moves or renames one existing text document inside the same project. The destination must not exist, so the tool never overwrites another document.

Parameters

  • source_path (required) — Current project-relative path
  • destination_path (required) — New project-relative path
  • expected_content_hash (required) — Hash from the latest get_document_by_path result
  • project — Project name. Default: active project

The tool refuses open or stale documents and does not move THINKFORGE.md. After the disk move, it updates the indexed record's location and repoints graph relationships, pins, recents, and document shortcuts that referred to the old path. The document keeps its existing ID, so document links to it continue to resolve.

index_document

Indexes or re-indexes one existing project file and waits for the operation to finish.

Parameters

  • path (required) — Project-relative document path
  • project — Project name. Default: active project

The response reports whether the file is indexable, its document ID, and any indexing error.

reconcile_project

Runs a complete disk-versus-SK comparison and waits for completion. It repairs files created, edited, moved, or deleted outside ThinkForge, stale absolute paths, and indexed documents that lost their chunks.

Parameters

  • project — Project name. Default: active project

The response reports counts for indexed, updated, moved, deleted, path-repaired, re-chunked, and failed items.

list_tags

Returns all unique tags across all documents in a project's SK Memory. Useful for discovering what tags exist before using tag_search.

Parameters

  • project — Project name. Default: active project

Response

{
  "tags": ["architecture", "design", "meeting-notes"],
  "tag_count": 3
}

Tags are sorted alphabetically with case-insensitive deduplication.

get_statistics

Returns database statistics for a project's SK Memory index. Useful for understanding the size and state of the index.

Parameters

  • project — Project name. Default: active project

Response

{
  "total_documents": 72,
  "conversation_count": 5,
  "document_count": 67,
  "total_chunks": 340,
  "indexed_count": 72,
  "embedded_chunks": 340,
  "embeddings_enabled": true,
  "embedding_progress": 1.0,
  "total_size_bytes": 2457600
}

The embedding_progress field ranges from 0.0 to 1.0 and indicates how much of the index has been embedded. A value less than 1.0 means embedding is in progress.

save_artifact

Saves one generated artifact as a physical file in a project, then indexes supported text formats in SK Memory. This is the primary mechanism for AI clients to persist generated content back into a project.

Parameters

  • title (required) — Artifact title, used to derive the physical filename
  • content — Text content to save
  • content_base64 — Base64-encoded binary content. Use instead of content for images, PDFs, and other binary files
  • file_type — File extension: markdown, cs, json, png, pdf, etc. Default: markdown for text content, bin for base64
  • folder — Project-relative destination folder. Default: _captured
  • tags — Array of tags to apply to the saved content after indexing
  • project — Project name. Default: active project

File naming: The filename is derived from the title, sanitized for the filesystem. File collisions are resolved with numeric suffixes: Name.md, Name (2).md, Name (3).md.

Folder validation: The destination folder must be a project-relative path that stays inside the project root. Dot-directories, symlinks, and reparse points are rejected. Subfolders under _captured are not allowed. The folder is created if it does not exist.

Write process: Content is written to a temporary file first, then atomically moved to the final path. After the file is saved it is indexed, tags are applied once indexing succeeds, and the artifact is added to Recents with ThinkForge MCP as its save source.

Response

{
  "success": true,
  "project": "Project Name",
  "relative_path": "Desktop App/Folder Tree.md",
  "absolute_path": "C:/path/to/project/Desktop App/Folder Tree.md",
  "document_id": "doc_a66be01ba7202fd7",
  "indexing_status": "completed",
  "bytes_written": 18336,
  "error": null
}

The indexing_status field can be "completed" (text indexed and searchable), "failed" (file saved but indexing failed — the error field explains why), "saved_not_indexable" (binary file saved, not a text format SK Memory can index), or "not_started" (file saved but indexing was not attempted).

On failure, success is false and error describes the problem: missing title, missing content, invalid base64, folder validation failure, or write error.

save_artifacts

Batch version of save_artifact. Saves multiple files in a single call. Each artifact is processed independently and receives its own result.

Parameters

  • artifacts (required) — Array of artifact objects, each with the same fields as save_artifact

Response

{
  "success": true,
  "saved_count": 3,
  "failed_count": 0,
  "results": [
    { "success": true, "relative_path": "...", ... },
    { "success": true, "relative_path": "...", ... },
    { "success": true, "relative_path": "...", ... }
  ]
}

The top-level success is true only if all artifacts saved successfully.

Common Usage Patterns

Most AI clients should begin with get_project_instructions, then use hybrid_search for finding relevant context and get_memory with include_chunks: true for reading indexed content. Use save_artifact for new generated output. Use get_document_by_path followed by update_document when intentionally revising an existing canonical file.

For Mind Map work, begin with mindmap_get_context. Use mindmap_search_nodes for broad semantic discovery, then read the exact returned node before editing. Apply one coherent mindmap_apply_patch using the current revision. If a revision conflict is reported, read fresh context and reconsider the patch.

For any update or move, pass the latest returned content_hash. If a conflict is reported, read the document again and reconsider the change rather than retrying with an old hash.

The list_projects tool is useful at the start of a session to understand what projects are available. The project parameter on every tool allows cross-project access without switching the active project in ThinkForge.

For discovering a project's content structure, call list_tags to see what topics exist, then use tag_search or hybrid_search to explore specific areas.