mcp: project-plan — Trellis MCP — Tool Surface Followups
This commit is contained in:
parent
d65d95bd04
commit
1b5ee52b98
96
Sources/Homelab/trellis-mcp-tool-surface-followups.md
Normal file
96
Sources/Homelab/trellis-mcp-tool-surface-followups.md
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
---
|
||||||
|
created: '2026-05-23'
|
||||||
|
path: Sources/Homelab
|
||||||
|
project: trellis-mcp-tool-surface-followups
|
||||||
|
tags:
|
||||||
|
- mcp
|
||||||
|
- claude-code
|
||||||
|
- lovebug
|
||||||
|
type: project-plan
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Make the Trellis MCP tool surface more ergonomic for in-session use without changing the underlying data model. Two changes:
|
||||||
|
|
||||||
|
1. Rename `pause_thread` to `checkpoint_thread` so the verb matches the event it writes (and stops colliding with the `paused` status value).
|
||||||
|
2. Add optional `id` parameter to all tools that take `slug`, 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 `ps` vs `kill <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 `232` next week either. You'll discover the thread again via `list_threads`, see whatever ID it has now, and use that.
|
||||||
|
- **Rename via alias, not hard cutover.** Add `checkpoint_thread` as the new canonical name, leave `pause_thread` as 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 gains `id` keeps `slug`. If both are passed, prefer `id` and warn on mismatch. If neither, error. This preserves slug-first workflows and adds id as additive.
|
||||||
|
|
||||||
|
## Open Items
|
||||||
|
|
||||||
|
- [ ] Decide grace period for `pause_thread` alias before removal
|
||||||
|
- [ ] Confirm whether `parent_id` field in `list_threads` already returns the integer (it filters by it, but does it return it?) — affects whether `list_threads` needs response-shape changes
|
||||||
|
- [ ] Decide whether `start_thread` and `fork_thread` should return the new thread's ID in their response payload (probably yes — otherwise you have to immediately `get_thread` to learn the ID)
|
||||||
|
- [ ] Audit the database schema to confirm `threads.id` is the right field to expose (vs some other internal identifier)
|
||||||
|
|
||||||
|
## Phases
|
||||||
|
|
||||||
|
### Phase 1 — Rename pause_thread → checkpoint_thread
|
||||||
|
|
||||||
|
- [ ] Add `checkpoint_thread` tool that takes the same args as `pause_thread` (`slug`, `state`) and writes the same `checkpoint` event
|
||||||
|
- [ ] Leave `pause_thread` registered 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 `slug` optional 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_thread` response includes `id`
|
||||||
|
- [ ] `fork_thread` response includes `id` of new child
|
||||||
|
- [ ] `get_thread` response includes `id`
|
||||||
|
- [ ] `list_threads` response includes `id` per 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_thread` alias 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 `paused` status that means "this thread is on hold"
|
||||||
|
- A `pause_thread` action 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)
|
||||||
Loading…
Reference in New Issue
Block a user