Reported issues for Longhand
Pod holds 11 of 11 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.
Back to Longhand.
Most discussed
MCP tool loading fails in Claude Code: outputSchema incompatibility
Problem
When longhand's MCP server is registered with Claude Code (CLI), the server connects successfully but tool loading fails with the following validation error:
Reconnected to longhand, but fetching tools failed: [
{
"code": "invalid_value",
"values": ["object"],
"path": ["tools", 0, "outputSchema", "type"],
"message": "Invalid input: expected \"object\""
},
... (same error for tools 1, 2, 4, 6, 11, 12, 14, 15, 16, 17, 18)
]
Root cause
Longhand uses…
Read the thread · 2026-05-22 · closed · external user · 2 comments
outputSchema with non-object top-level type breaks tool loading in Claude Code
Problem
12 of 19 MCP tools fail to load in Claude Code because their outputSchema declares a top-level "type": "array" or uses "oneOf" without a top-level "type". Claude Code's MCP client validator requires outputSchema.type to be "object".
This is the root cause of #9.
Analysis
I mapped every tool definition in mcp_server.py against the error output from #9:
| Index | Tool | outputSchema.type |
Loads? |
|---|---|---|---|
| 0 | search |
… |
Read the thread · 2026-05-22 · closed · external user · 1 comment
Redaction misses git commit messages
With redact.enabled, secrets are masked at parse time across an event's content, tool_output, error_snippet, old_content, new_content, and its raw JSON (_EVENT_TEXT_FIELDS in longhand/redaction.py). But git_commit_message is not in that list.
The parser extracts it from git output (parser.py, and codex.py for Codex exec commands), and store.py persists it as git_operations.commit_message. So a secret that appears in a commit message is stored unmasked at ingest,…
Read the thread · 2026-09-28 · open · 0 comments
mcp install writes the macOS Claude Desktop path on every OS
CLAUDE_DESKTOP_CONFIG_PATH is hardcoded to ~/Library/Application Support/Claude/claude_desktop_config.json (longhand/setup_commands.py). On Windows (the best-effort CI tier), Claude Desktop reads %APPDATA%\Claude\claude_desktop_config.json, so mcp install writes a file nothing reads and still reports success. On Linux there is no Claude Desktop.
Expected: a platform-specific path, or skip with a message where Desktop doesn't exist.
_Found and verified against the code during the…
Read the thread · 2026-09-28 · open · 0 comments
CLI session-prefix resolution only scans the 1,000 most recent sessions
timeline, replay, export, status --session, and search --session resolve a session-ID prefix by filtering store.sqlite.list_sessions(limit=1000) in Python (5 call sites in longhand/cli/_commands.py). cli/helpers._resolve_prefix already does this correctly with SQL LIKE over the whole table; its docstring records the same bug being fixed for the MCP path.
The maintainer's archive is at 792 sessions, so this will start failing silently at 1,001.
Expected: all five call…
Read the thread · 2026-09-28 · open · 0 comments
MCP output caps: six tools are uncapped, and max_chars <= 0 disables truncation
The README promised every tool is capped. In fact:
max_charsis accepted by 5 of 13 tools:search,get_session_timeline,recall,recall_project_status,find_commits.list_sessionsandlist_projectshave a fixed 16,000 cap, which doesn't apply in theirproject_id/matchmodes.- Uncapped:
get_file_history(every edit, no LIMIT),replay_file(the whole file),find_episodes(including the detail mode'sfile_state_after),list_plans,get_stats,reconcile. -…
Read the thread · 2026-09-28 · open · 0 comments
search auto-scope can't be overridden; its hint is a no-op
When a query names a project (score ≥ 0.8), search scopes to it and returns auto_scope_hint: "… Pass project_name=None to override." (longhand/mcp_server.py). JSON null can't be told apart from omitting the key, so that call auto-scopes again. There is no way to run an unscoped search whose text names a project.
That is the "remedy that cannot work" COMPATIBILITY.md Promise 5 rules out. Since 1.2.1, an explicit session_id turns auto-scope off, but that is not a general opt-out.…
Read the thread · 2026-09-28 · open · 0 comments
The update check runs on exit of shared-mcp, mcp serve, and demo
_UPDATE_CHECK_EXCLUDED (longhand/cli/_commands.py) lists only the hidden entry points: mcp-server, the hook commands, context, and backfill-episodes. The comment above it says an MCP server "may not gain network calls", but:
shared-mcpandmcp serveare MCP servers too, and they refresh the PyPI cache when they exit.demois documented as not touching~/.longhand, but its exit-time refresh writes~/.longhand/update-check.json, creating the directory (see the 0700…
Read the thread · 2026-09-28 · open · 0 comments
Most recent
doctor's "Claude Code MCP" row misses plugin-provided servers
doctor checks only the top-level mcpServers key of ~/.claude.json (longhand/setup_commands.py, "Claude Code MCP installed?"). A server provided by the Longhand plugin (.mcp.json) or registered at project scope shows as "not installed". Doctor then tells the user to run claude mcp add for a server they already have.
Expected: recognize plugin-provided and project-scoped registrations, or reword the row to "not found in ~/.claude.json".
_Found and verified against the code…
Read the thread · 2026-09-28 · open · 0 comments
~/.longhand can be created without 0700
LonghandStore creates the data dir with mode=0o700 (longhand/storage/store.py), but only if it gets there first. Two other paths create it with the default umask, typically 0755:
- the update-check cache:
target.parent.mkdir(parents=True, exist_ok=True)(longhand/update_check.py) config --set:config_path.parent.mkdir(parents=True, exist_ok=True)(longhand/cli/_commands.py)
longhand demo writes the update-check cache on exit. So the README's recommended first command can…
Read the thread · 2026-09-28 · open · 0 comments
config --set ignores a relocated store, and --edit does nothing
longhand config --set k=v always writes ~/.longhand/config.json: config() in longhand/cli/_commands.py builds config_path = Path.home() / ".longhand" / "config.json". It ignores both its own --data-dir option and LONGHAND_DATA_DIR.
The readers use the resolved data dir. Redaction reads resolve_data_dir() / "config.json" (longhand/redaction.py), and so does the prompt-hook config loader. With a relocated store, config --set writes a file nothing reads, and prints that…
Read the thread · 2026-09-28 · open · 0 comments
The remaining reports are on the project's issue tracker.