About This Article

familiar’s orchestration currently runs on 9 MCP tools. All Rust, all stdio JSON-RPC 2.0. Built at a pace of roughly 1-2 per day, with plenty discarded along the way. This article covers the 9 that survived and are running in production.

Zed MCP server list -- all 9 servers green
Zed MCP settings -- all servers connected. 41 tools total

The Full Picture

The homelab where all these tools run:

Homelab 4-node architecture -- edge, storage, desktop, compute
Homelab architecture. edge (RouterOS), storage (Ubuntu 24/7), desktop (macOS), compute (EPYC + Blackwell x2). MCP servers run on desktop, connecting to compute's LLM backends and storage's data platform
MCP ServerToolsSummary
voracle4Obsidian vault semantic search + web research
argus1Cross-repository code intelligence
ctree8Code tree structure analysis + checkpoints
dgs17secret
memento2secret
okitegami1Discord leave-a-letter
smng2Homelab secret management
sqlimit-15Read-only DB exploration

resolve-inference (path resolution engine) is now integrated into familiar itself and no longer runs as a standalone MCP, but the design history is worth recording.


voracle – External Memory

Covered in detail in a separate article, so just the highlights. Semantic search + web research MCP for Obsidian vaults. Runs ONNX embedding + ColBERT reranking locally. The research command auto-accumulates web knowledge into the vault via the Brave Search API.

Tools: search, read, research, related


argus – Cross-Repository Code Intelligence

An MCP that indexes all repositories from Gitea and provides cross-repository symbol search. Extracts symbols with tree-sitter and reranks with ColBERT MaxSim.

  CLI (index + embed)           MCP Server (query)
     |                              |
     v                              v
[Gitea API: repos/search]    [CWD auto-index on startup]
     |                              |
     v                              v
[git clone/fetch]             [argus.see tool]
     |                              |
     v                              v
[tree-sitter: symbols]        [adaptive lexical filter -> ColBERT rerank]
     |                              |
     v                              v
[ColBERT embed (batch)]       [Gemini summarize]
     |                              |
     v                              v
[redb: symbols+embeddings]    [hit tracking + NATS pulse]
  

Three-tier embedding:

  1. Batch: argus embed pre-computes all symbol embeddings at index time
  2. Hot-hit: symbols accessed 3+ times re-embed at query time to stay fresh
  3. On-demand: uncached symbols embed at query time and persist

Tools: see (specify expected symbols, modules, or specs for cross-repo search)


ctree – Code Tree Structure Analysis

An MCP for codebase symbol structure, dependency analysis, and revision management. Define scope with .ctree.toml, analyze structure with check, record work milestones with checkpoint.

Tools: check, checkpoint, get_affected, get_depends, get_symbol, get_text, get_revs, get_baseline

In familiar’s development workflow, calling checkpoint after every code change to leave a revision, then checking impact with get_affected before starting implementation has become standard practice. The agent’s work logs in Obsidian show ctree__check and ctree__get_symbol calls everywhere.

The call volume is high, but most replies are around 5 tokens – just symbol names and hashes, no actual code. The agent first grasps the structure via hashes, then injects only the code it actually needs into context on-demand with get_text. This keeps context window consumption minimal while maintaining visibility across the entire codebase’s dependency graph. Once this stabilized, Serena became unnecessary. I had been using Serena cooperatively before, but after setting up my own Gitea and distribution registry, argus handles IaC and understands my codebase’s architecture, design philosophy, and patterns well enough to code effectively.

Obsidian work log searching for ctree__check -- agent calls ctree tools in sequence right after thinking
Agent work log. Right after thinking, it calls ctree__get_symbol, ctree__get_affected, ctree__check, ctree__get_depends, ctree__get_text in sequence

dgs – 17 tools (non-public)

The largest tool count among the 9 MCPs. Design and implementation details are non-public.


memento – 2 tools (non-public)

An MCP related to AI agent management. Design and implementation details are non-public.


okitegami – Discord Leave-a-Letter

An MCP for LLM agents to post notifications to Discord at work milestones. Just one tool.

The design philosophy is “letter,” not “message.” I don’t want a conversation. Just leave a letter. I’ll leave one too if something comes up – and if there’s one waiting when you leave yours, read it. That’s the distance this was built for.

  1. Leave a letter about current work results on Discord
2. While you're at it, check if past letters have replies
3. If no replies, do nothing
  

The trigger is “leave a new letter,” not “go check for replies.” No polling loops.

okitegami Discord thread -- tegami APP letter with ksh3 reply
A letter thread from tegami. summary, worked, result, concerns, tests are structured. ksh3 replied a few hours later

In practice: the agent creates threads in the #tegami channel during development and leaves progress notes. I glance at them occasionally, and if something comes to mind, I leave a reply. Replying a month later is fine. The next time the agent calls tegami, it picks up: “About that thing you implemented a month ago – ksh3 mentioned something about it, what should we do?” Or it just fixes it on its own.

It’s an asynchronous feedback loop, but it’s not chat. It moves on the timeline of letters. No urgency expected, no reply required for normal operation. This distance meshes long-running autonomous work with human life rhythms nicely.

Tools: tegami


smng – Secret Management

An MCP for managing homelab service credentials, endpoints, and connection details. Securely retrieves auth information for services within the *.home.arpa network.

Tools: list_services, get_secret


sqlimit-1 – Read-Only DB Exploration

A context-safe MCP targeting familiar’s main DB only, with query results limited to exactly one row. The core principle: don’t trust the LLM to write LIMIT 1. The tool wraps unconditionally:

  SELECT * FROM (<user_sql>) AS _q LIMIT 1
  

Read-only is guaranteed at the connection level. Connects with a dedicated PostgreSQL user configured with default_transaction_read_only = on, so no filtering needed on the tool side. Non-SELECT statements are rejected outright.

Connection details could come from smng (secret management), but sqlimit-1’s job isn’t just DB access. It also handles schema versioning. dump_schema retrieves the schema, and if there are changes, it creates a schema version. Quickly understanding data structure with minimal context, leaving a version record on the side – that’s the specialized use case.

I prefer tools that do one thing well over tools that do everything. smng returns credentials. sqlimit-1 understands schemas. Clear responsibilities for each means they’re less likely to break when combined.

Tools: tables, describe, sample, query1, dump_schema


resolve-inference – ENOENT Path Resolution Engine (now integrated into familiar)

Built to solve the problem of LLMs guessing file paths and hitting ENOENT errors. Returns the correct path using a filesystem index with lexical scoring + ColBERT MaxSim.

The accuracy breakthrough wasn’t the model – it was query history. A ring buffer of the last 5 resolved paths, with a two-tier boost via directory affinity and package affinity:

  Go monorepo (106 files, client.go exists in 4-11 locations):
  With history:    85.0% (17/20)
  Without history: 35.0% (7/20)
  Delta:           +50.0pp
  

I also built a framework to evaluate 3 ColBERT models as an ensemble, but all three scored identically (87.3%) while latency went up 3.7x. The accuracy bottleneck was in the lexical algorithm, not the model. Discarding the ensemble and focusing on query history correlation was the right call.


Retired Tools

Behind the 9 running tools, several have been retired. But “retired” is more accurate than “discarded” – most were integrated into current tools or had their functionality borrowed and reborn. resolve-inference being absorbed into familiar is one example; the ideas from the early shelpa (filesystem MCP) were distributed across ctree and dgs.

Above all, building them is just really fun. Writing an MCP server in Rust takes shape in a day, and the stdio JSON-RPC 2.0 protocol is simple enough that an idea turns into a working tool by the next day. Try it, discard if it’s mediocre, polish if it’s good. As long as this cycle keeps turning, the tools keep growing.


Shared Design Principles

What all tools have in common:

  • Rust + stdio JSON-RPC 2.0: fast process startup, small memory footprint
  • Single responsibility: one tool solves one problem. No feature creep
  • Born from real agent work: built by working backwards from “this is where I got stuck”
  • Graceful degradation: if one tool goes down, others keep running. familiar’s main flow doesn’t stop

41 tools across 9 processes, total memory usage in the tens of MB. Rust’s small binary size and runtime overhead pay off in architectures like this where many small processes run in parallel.