5.4 KiB
| created | path | project | tags | type | |||
|---|---|---|---|---|---|---|---|
| 2026-05-23 | Sources/Homelab | trellis-mcp-tool-surface-followups |
|
project-plan |
Goal
Make the Trellis MCP tool surface more ergonomic for in-session use without changing the underlying data model. Two changes:
- Rename
pause_threadtocheckpoint_threadso the verb matches the event it writes (and stops colliding with thepausedstatus value). - Add optional
idparameter to all tools that takeslug, so threads can be addressed by their integer ID during a session. Slug remains canonical; ID is a convenience handle.
Both changes are small, scoped server-side edits. No data migrations, no breaking changes if done with aliases.
Locked Decisions
- Slug stays canonical. Names are durable, meaningful, survive migrations. IDs are database-implementation artifacts. The model is: slug for discovery and persistence, ID for session-scoped operation. Same pattern as
psvskill <pid>. - ID stability is explicitly not a goal. IDs may not survive a restore or migration. That's fine — you're not going to remember
232next week either. You'll discover the thread again vialist_threads, see whatever ID it has now, and use that. - Rename via alias, not hard cutover. Add
checkpoint_threadas the new canonical name, leavepause_threadas a deprecated alias that calls through. Drop the alias after a grace period (TBD — could be one trellis release, could be a calendar deadline). - No
id-only tools. Every tool that gainsidkeepsslug. If both are passed, preferidand warn on mismatch. If neither, error. This preserves slug-first workflows and adds id as additive.
Open Items
- Decide grace period for
pause_threadalias before removal - Confirm whether
parent_idfield inlist_threadsalready returns the integer (it filters by it, but does it return it?) — affects whetherlist_threadsneeds response-shape changes - Decide whether
start_threadandfork_threadshould return the new thread's ID in their response payload (probably yes — otherwise you have to immediatelyget_threadto learn the ID) - Audit the database schema to confirm
threads.idis the right field to expose (vs some other internal identifier)
Phases
Phase 1 — Rename pause_thread → checkpoint_thread
- Add
checkpoint_threadtool that takes the same args aspause_thread(slug,state) and writes the samecheckpointevent - Leave
pause_threadregistered as a deprecated alias — same handler, optionally logs a deprecation warning - Update tool descriptions to reflect the rename
- Update any internal documentation / README references
Phase 2 — Add id parameter to read/write tools
Tools to modify:
get_thread(slug, include_events)→get_thread(slug?, id?, include_events)checkpoint_thread(slug, state)→checkpoint_thread(slug?, id?, state)resume_thread(slug)→resume_thread(slug?, id?)update_thread(slug, ...)→update_thread(slug?, id?, ...)fork_thread(parent_slug, new_slug, ...)→fork_thread(parent_slug?, parent_id?, new_slug, ...)
For each:
- Make
slugoptional in the schema - Add optional
id(integer) - Server-side: branch on which was provided; error if neither; warn if both disagree
- Update tool descriptions
Phase 3 — Expose id in responses
start_threadresponse includesidfork_threadresponse includesidof new childget_threadresponse includesidlist_threadsresponse includesidper row (confirm whether already true)
Phase 4 — Verification
- In-session test: address a thread by integer ID end-to-end (start → checkpoint → resume) without typing the slug
- In-session test: cross-chat handoff using ID ("can you pull thread 232")
- Confirm
pause_threadalias still works for any prior tooling that calls it
Notes
Naming context — why pause is wrong for the action:
The existing pause_thread tool writes a checkpoint event, not a status change. Per its own docstring: "the thread row is not changed except for updated_at." So the verb doesn't describe what's happening — checkpointing is happening; pausing is not.
Worse, there's a paused value in the status enum (active | paused | done | abandoned). So you have:
- A
pausedstatus that means "this thread is on hold" - A
pause_threadaction that does not set that status
checkpoint_thread resolves the collision. Pausing-the-status remains a separate decision via update_thread(slug, status='paused').
ID lookup context — why this matters ergonomically:
In session usage, slugs are friction: long, must be re-typed or re-quoted, easy to mistype. Integers are zero-friction: pull thread 232, checkpoint 232, resume 232. The slug stays useful for first-discovery ("which thread was the traefik debugging one?") but once you're operating on it, the integer wins.
Pattern parallel: Linux processes. ps shows names for discovery; kill 4729 for operation. Names for finding, numbers for doing.
What's explicitly out of scope:
- Changing slug semantics (still required at creation, still kebab-case, still the URL-safe identifier)
- Migrating existing data
- Changing the event log structure
- Adding any new event types
- The three other trellis follow-ups already tracked (retry/cleanup on embedding failure, semantic dedup before insert, revisit enricher pause-during-reflector)