← Changelog

Every Wiki Gets a Name Worth Sharing — and the Aggregating MCP Finally Has a Spec

Paste an Outline share link now and it stays on lossless.at instead of flipping to a Railway hostname mid-click. Alongside it: a spec for the one-connector-per-client MCP, and a working prototype of its Skills plane built with no new infrastructure.

· Michael Staton · with Claude Code on Claude Opus 5

Why Care?

A share link is the one URL that leaves the building. It goes to a founder, an LP, someone who has never heard of us — and until today, clicking one flipped the address bar to outline-production-3d8d.up.railway.app. The pretty path worked, right up until the moment it mattered.

Now every wiki lives at a name we own and generates clean links itself:

wiki.palmer-ai.lossless.at
wiki.reach-edu.lossless.at
wiki.the-water-foundation.lossless.at

Not rewritten after the fact — born correct, because each Outline's URL env var points at its own host.

What's New?

  • Three custom-domain cutovers — Railway domain + Vercel DNS (CNAME + _railway-verify TXT) + URL env var + CONFIG_EPOCH bump, per client. Certs issued in minutes; verified by curl -v showing subject: CN=wiki.<client>.lossless.at.

  • [[Homebase-MCP-One-Connector-Per-Client]] — the spec for the aggregating MCP. One connector per client fronting CRM, wiki, data room, and post planner, with our agent-skills served as prompts.

  • [[vc-firm-profile-ingest]] — an agent-skill that takes "create a profile for Kalos Ventures" and produces a Twenty company record, an attached research note, and a cross-linked Outline page, with no copy-paste between systems.

  • [[Which-Domain-Hosts-What-lossless-at-vs-didi-sh]] — filed as an issue, not a decision, because nothing was decided.

The thing a redirect can never do

Worth stating plainly, because it has now bitten twice in two different shapes.

A redirect points at a host. It cannot hide one. lossless.at/<client>/wiki 307s to wherever the app lives, and the browser lands there — address bar and all. That is fine for a dashboard you log into and useless for a link you send to someone else.

Masking it under the path was not available either: Outline assumes it lives at a host root and requests /static and /api as absolute paths. Proxied under /palmer-ai/wiki/, those resolve against lossless.at and belong to no client. Same family as Postiz's cookie-domain constraint — some apps will not live under a subpath, and no amount of URL cleverness changes that.

So the fix had to be at the source: give the app a real host, and tell the app that is its address. The portal path stays the memorable front door and redirects there; each Railway domain stays attached, so every link already sent still resolves.

The spec, and the gate that turned out to cover half of it

[[Per-Client-Stack-Deployment-Spec-Twenty-First]] Phase 6 has blocked homebase on the id-didi-sh spec absorbing "one-service-or-two, workspace scoping, BYO-key custody." All three are secrets-and-identity questions. An aggregator that federates tools a client already pays us to run, and serves our own skills, answers none of them. Two things were fused under one word and the gate froze both.

The load-bearing proposal is H2: use each client's own Twenty as the OAuth authorization server. Every client user already has a Twenty account, and Twenty already ships a working authorization server. That buys per-user identity and per-client scoping with zero new identity infrastructure — and makes homebase a consumer of the id-didi-sh decision rather than an input to it. It is also the riskiest assumption in the document, so Phase 0 does nothing but try to kill it across all four harnesses before anything real gets built.

The Skills plane already works, crudely

Before building anything, the Skills plane was proven end-to-end with no new service: vc-firm-profile-ingest was published into Palmer AI's Outline as an Agent Playbooks document, then enumerated and read back over MCP from a different client.

That experiment settled a real design question. Outline exposes both list_templates (returns every body inline) and list_collection_documents (titles and ids, then fetch per doc). Templates look like the closer analogue to MCP prompts, but they invert the cost model — at ten playbooks, asking "what's available here?" would load ten full bodies. So homebase's prompts/list must return names and descriptions only, with bodies materialized on prompts/get.

It also exposed the obvious flaw in the interim: publishing forks the source. The Outline copy is what agents load, the git copy is what we edit, nothing reconciles them. Until homebase serves context-v/agent-skills/ directly the discipline is edit in git, re-publish to Outline — and it argues the spec's open question #4 toward fetch-at-runtime over bake-at-build.

Gotchas

  1. The Vercel CLI defaults to the wrong scope. vercel dns add returned permission_denied for lossless.at because the CLI was scoped to mpstatons-projects; the zone lives under colearn-labs. Pass --scope colearn-labs or nothing works, with an error that sounds like an access problem rather than a scope one.

  2. Batched vercel dns add calls silently drop. Four records issued in one shell produced one record. Issued individually, all four landed. Verify with vercel dns ls rather than trusting the exit path.

  3. Changing Outline's URL forces a fresh sign-in — the session cookie is host-scoped. Harmless now that magic links work (2026-08-08); it would have been a lockout a day earlier.

  4. Outline's frontmatter renders badly in Outline. Publishing a SKILL.md verbatim leaves a mangled ## name: … description: … heading, since Outline stores the title separately. Strip the YAML; keep the trigger phrasing as a blockquote.

Left open, deliberately

The CRMs and the data room are still on Railway hostnames. Different situation from the wikis: Twenty's SERVER_URL is also its OAuth issuer, baked into the MCP connector's discovery documents, so changing it forces every connected Claude Desktop to re-authenticate. Nobody passes links out of those the way they do from a wiki — share links were the actual problem, and share links are fixed.

Reach's Postiz stays on postiz.reach-edu.didi.sh. It is the only working Postiz in the stack, and it works because of the cookie host a move would change.

Files changed

  • context-v/specs/Homebase-MCP-One-Connector-Per-Client.md
  • context-v/agent-skills/vc-firm-profile-ingest/SKILL.md
  • context-v/issues/Which-Domain-Hosts-What-lossless-at-vs-didi-sh.md
  • context-v/issues/Normalize-Paths-Everywhere.md
  • context-v/handoffs/2026-08-08-Where-Things-Stand.md
  • hubs/lossless-at/src/config/clients.ts
  • client-stacks/{palmer-ai,reach-edu,the-water-foundation}/outline/.env (gitignored)