v0.4.3: agent-friendly MCP tool descriptions with step-by-step workflow

This commit is contained in:
emil
2026-05-16 18:47:09 +03:00
parent 974aba45eb
commit 3d0e087ebd
3 changed files with 34 additions and 24 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
"""memwalk — ask AI about any codebase via cached SSM state.""" """memwalk — ask AI about any codebase via cached SSM state."""
__version__ = "0.4.2" __version__ = "0.4.3"
+32 -22
View File
@@ -40,10 +40,11 @@ async def list_tools() -> list[Tool]:
description=( description=(
"Read all source files under the given directory and build a " "Read all source files under the given directory and build a "
"cached SSM state that can be queried in subsequent ask() calls. " "cached SSM state that can be queried in subsequent ask() calls. "
"Slow first time (5-30s for medium repos, longer for big ones); " "Use this for small-to-medium repos that fit in a single context "
"window (default ~120K chars). For large repos that exceed the "
"context limit, use digest_split instead. Slow first time (5-30s); "
"cache is reused on subsequent calls until source files change. " "cache is reused on subsequent calls until source files change. "
"Use before ask() to control when ingestion happens, or just call " "You can also call ask() directly which auto-digests as needed."
"ask() directly which will auto-digest as needed."
), ),
inputSchema={ inputSchema={
"type": "object", "type": "object",
@@ -68,13 +69,15 @@ async def list_tools() -> list[Tool]:
Tool( Tool(
name="ask", name="ask",
description=( description=(
"Query a codebase using its cached SSM state. Returns the " "Step 3 in the multi-corpus workflow. Query a codebase using its "
"model's answer based on the previously digested source. " "cached SSM state. Returns the model's answer based on the previously "
"Auto-digests if no fresh cache exists (first call may be " "digested source. For large repos that were split-digested, you must "
"slow). Subsequent calls on the same codebase are fast " "pass the specific subdirectory path in 'path' that is most relevant "
"(<1s typical). Best for descriptive questions: 'what does " "to the question — not the repo root. For example: "
"module X do', 'where is concept Y used', 'list all CLI " "ask('/repo/src/auth', 'how does login work?') or "
"commands', 'how would I add feature Z'." "ask('/repo/backend/db', 'what migrations exist?'). "
"Auto-digests if no fresh cache exists (first call may be slow). "
"Subsequent calls on the same codebase are fast (<1s typical)."
), ),
inputSchema={ inputSchema={
"type": "object", "type": "object",
@@ -117,16 +120,19 @@ async def list_tools() -> list[Tool]:
Tool( Tool(
name="list_subdirs", name="list_subdirs",
description=( description=(
"List subdirectories of a codebase root with file counts, " "Step 1 in the multi-corpus workflow. Lists subdirectories of a "
"estimated char sizes, depth, and cache status. Use this before " "codebase root with file counts, estimated char sizes, recursion "
"digest_split to see which subdirectories are available. " "depth, and cache status. For large repos, this shows you what leaf "
"Cheap — does not load the model." "directories are available so you can pick the right ones to digest. "
"Directories that are too large for the current n_ctx budget are "
"shown with their depth; you can use max_depth to control how deep "
"the recursion goes. Cheap — does not load the model."
), ),
inputSchema={ inputSchema={
"type": "object", "type": "object",
"properties": { "properties": {
"path": {"type": "string", "description": "Codebase root to inspect."}, "path": {"type": "string", "description": "Codebase root to inspect."},
"max_depth": {"type": "integer", "description": "Max recursion depth (default: unlimited)."}, "max_depth": {"type": "integer", "description": "Max recursion depth (default: unlimited). Use 1 for immediate children only."},
}, },
"required": ["path"], "required": ["path"],
}, },
@@ -134,19 +140,23 @@ async def list_tools() -> list[Tool]:
Tool( Tool(
name="digest_split", name="digest_split",
description=( description=(
"Discover subdirectories under the given path and digest each " "Step 2 in the multi-corpus workflow. Discovers subdirectories under "
"independently into its own cached SSM state. Each subdirectory gets " "the given path and digests each independently into its own cached "
"a separate cache, so subsequent ask() calls can target specific " "SSM state. Each subdirectory gets a separate cache keyed by its "
"sub-caches. Use list_subdirs first to see what will be digested. " "absolute path, so subsequent ask() calls can target specific "
"Slow first time; cache is reused on subsequent calls." "sub-caches (e.g. ask '/repo/src/auth' 'how does login work?'). "
"Use list_subdirs first to see what will be digested. Slow first "
"time (5-30s per subdirectory); cache is reused on subsequent calls. "
"Large subdirectories that exceed the n_ctx budget are skipped with "
"an error unless you increase max_depth to split them further."
), ),
inputSchema={ inputSchema={
"type": "object", "type": "object",
"properties": { "properties": {
"path": {"type": "string", "description": "Codebase root to split-digest."}, "path": {"type": "string", "description": "Codebase root to split-digest."},
"force": {"type": "boolean", "description": "Re-ingest even if cache is fresh.", "default": False}, "force": {"type": "boolean", "description": "Re-ingest even if cache is fresh.", "default": False},
"n_ctx": {"type": "integer", "description": "Override config n_ctx for this digest."}, "n_ctx": {"type": "integer", "description": "Override config n_ctx for this digest (default: auto-detected from free VRAM)."},
"max_depth": {"type": "integer", "description": "Max recursion depth (default: unlimited)."}, "max_depth": {"type": "integer", "description": "Max recursion depth (default: unlimited). Use 1 for immediate children only."},
}, },
"required": ["path"], "required": ["path"],
}, },
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "memwalk" name = "memwalk"
version = "0.4.2" version = "0.4.3"
description = "Ask AI about any codebase — local, cached, SSM-state-backed exploration via memba + Nemotron" description = "Ask AI about any codebase — local, cached, SSM-state-backed exploration via memba + Nemotron"
readme = "README.md" readme = "README.md"
license = { text = "MIT" } license = { text = "MIT" }