A local MCP door onto your Tinhead thought tree. Holds your key on your machine; the server never gets one it can use.
Strong tool definitions with comprehensive descriptions (avg 250+ chars) and explicit JSON schemas. All 13 tools have clear verb-noun naming and detailed parameter documentation. Tool annotations (readOnlyHint, destructiveHint) are present. Key strengths: descriptions explain limitations (pagination, truncation, scope rules), parameter types are declared, and output structures are documented in prose. Weaknesses: output schemas are described in text rather than formal JSON Schema; some parameter descriptions could be more concise; error handling guidance is minimal in tool definitions themselves.
Compile a branch into one document. Pass the id of the root thought of the branch you want, and it returns the whole thing as markdown — titles as headings, details as body text, the structure as nesting. Useful for reading a whole project or area at once, or for gathering context to send to another tool. The output is capped at 40,000 characters; if a branch is longer, the deepest parts are truncated and the output says so.
Tick a thought off, or un-tick it. Tick only what is done and VERIFIED — a task blocked on something outside your reach stays open and says what it waits on. When you finish real work, pass "note": a short record of what you did, saved as a new thought INSIDE the ticked one in the same act — first line its title (put the date in it), anything after a blank line its detail. That is the house form: progress lives in CHILDREN, never swelled into the parent's own detail. If only part of a task landed, the parent SHRINKS to what is still outstanding and the finished half becomes a child — see the note on update_thought. Ticking a thought that was never a task makes it a completed task — deliberate, but it means you cannot un-tick your way back to an ordinary thought.
Put a new thought inside another one. The parent must be inside a branch this grant was given (get_root lists them). THE SHAPE OF A GOOD ONE: the title is the CLAIM, one line that stays true when read alone in a search result ("The throttle counts calls before it checks the credential", never "Throttle"). The detail is at most two short fields — a LIST joined by blank lines, "one\n\ntwo" — and anything past that wants to be a CHILD thought instead: offered a longer detail or another level, take the level, because one idea per thought is what lets the person zoom instead of reading walls. Prose belongs in many small thoughts, not one big one. Never number titles for ordering (the level owns its order) and never put status words or severity prefixes in them — doneness is the box: set task:true to make it something to tick off, and only when it is genuinely work. You cannot create a PRIVATE detail field: only the person can cover something, and text shaped like a covered field is dropped rather than saved.
Output schemas documented in prose only, not as formal JSON Schema. Tools return structured data but LLMs cannot parse response structure from descriptions alone.
Error handling guidance absent from tool definitions. Tools reference ScopeError and validation failures but do not document recovery paths (e.g., 'If scope error, call get_root first').
Destructive tool (delete_thought) lacks confirmation/dry-run pattern. Description warns of permanence but tool accepts no confirmation parameter.
Parameter descriptions reference domain concepts ('covered field', 'grant', 'branch') without sufficient explanation for LLMs unfamiliar with Tinhead's mental model.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
Delete a thought and everything inside it. This is permanent and cannot be undone — the person's only recourse is a restore from backup. Use it only when you are certain, and only for thoughts the person explicitly asked you to delete. If a thought is part of a task that is not done, say so and ask before you delete it.
List tasks matching a filter. Pass state:"open" for tasks the person has not ticked off, state:"done" for ones they have, or neither to see both. Pass when:"today" to see tasks due today, when:"overdue" for ones past their due date, when:"upcoming" for ones coming up, or neither to see all. The results are in the person's own order and limited to 100.
List the thoughts directly inside another thought, in the person's own order. Paginated; pass page:0 for the first page, page:1 for the next, and so on. The response says how many pages there are.
The breadcrumb from the root down to a thought — the chain of titles that leads to it. Useful for understanding where a search result lives, or for showing the person where you are working. The thought itself is not included; the path ends at its parent.
START HERE. Returns this grant: which thoughts it is rooted at (there may be several, or none yet), what it may read and write, and the ids you need for every other tool. Every other tool takes an id, and this is the only one that does not — call it first. It also hands back the FIRST LEVEL inside each root with its counts, so you can usually pick where to go next without a second call. If "roots" is empty the person has not given this connection a branch yet; say so and stop, because nothing can be changed until they do. CONVENTION: treat each root thought as the index of everything beneath it, the way you would treat a MEMORY.md — keep it current and you will find your own work later.
Read one thought in full. Pass with_children:true to also get its direct children (the first level inside it), which is usually what you want when you land on a thought from search or from another tool. The children arrive in the person's own order, with their counts but not their own children — call get_level to page through a long list, or get_thought again on one of them to descend.
Search the readable tree for thoughts matching a query. The results are ranked by relevance and limited to 25. Searches the title and detail of every thought you can read, and returns the best matches with their breadcrumbs so you can see where they live. A search result is a thought like any other — pass its id to get_thought to read it in full.
Designate a thought as a task, or remove the designation. A task is something to tick off — pass task:true to make it one, task:false to make it an ordinary thought. Ticking a thought that was never a task makes it a completed task; un-ticking a completed task makes it an ordinary thought. This tool only changes the designation; use complete_thought to tick it off.
Give a thought a date, or remove one. A date makes it show up in the calendar surface. Pass day (YYYY-MM-DD), optionally time (HH:MM in 24-hour format), and optionally repeat ("daily", "weekly", "monthly", "yearly"). Omit all three to remove the date. The thought IS the event; there is no separate event object.
Change a thought's words — its title, its detail, or both. Only what you pass changes. NEVER REWRITE THE PERSON'S OWN WORDS in place — their detail often carries decisions nothing else records; add a child beside instead. Rewriting is right in two cases: words you yourself wrote, and SHRINKING a partly-done task so its title and detail name only what is still outstanding (the finished half becomes a child — see complete_thought's note). The detail is a LIST of fields joined by blank lines, exactly as get_thought returned it; send the whole detail back, not just your addition. PRIVATE FIELDS ARE CARRIED THROUGH AUTOMATICALLY: a thought may hold detail you cannot read, and it is put back where it was — never try to preserve or recreate it yourself. This changes words only; use complete_thought, set_task and set_when for the rest.
STDIO transport only, server is not remotely accessible and cannot be used by hosted MCP clients. Limits deployment scenarios.