Most people who do client work buy the system. They pay for a CRM, a project tool, a proposal app, a scheduling thing, and then spend a chunk of every week keeping those five tools agreeing with each other. I went the other direction. The thing that runs my practice is something I built, and it lives on the same domain you're reading this on right now. Same brand, same database, same code. One screen I open in the morning that tells me what needs me today.
This is a walk through that system. What it is, why I built it instead of buying it, and the part that's mostly just for fun.
The reason I can talk about it openly is that the build itself is the point. The people who can concept the brand and write the React and design the schema and wire the AI orchestration are pretty rare. I'm one of them. The command center is the clearest evidence of the thing I'm actually selling, so I'd rather show it than hide it.

What the command center actually is

It's an admin cockpit sitting on top of a real CRM. The CRM has the normal stuff: companies, contacts, deals, activities, tasks. The cockpit is the layer on top that I open first thing and that answers one question before I've had coffee, which is what needs me today.
The top panel is a ranked list. Overdue tasks first, then what's due today, then deals that have gone quiet. A deal counts as quiet when nothing's happened on it in fourteen days, and once it crosses that line it surfaces in the list on its own so I don't have to remember to go looking. The list is capped at seven items on purpose. I have ADHD and an unbounded task list is how I lose a whole morning to deciding what to do instead of doing it. Seven things, ranked, then I close the panel and work.
Under that is a kanban board, but the lanes aren't deal stages. The lanes are the areas of my actual work: site, SEO, the cold-outreach funnel, LinkedIn, the freelance channel, client projects, admin. Every task lands in one of those lanes. If a task doesn't have a lane set, the system derives one from the task type, so nothing ends up orphaned in a column called "other." The board reads like my week reads, which is the only reason I look at it.
Why I built it instead of buying it
I get why building your own CRM sounds like a bad idea. It's the classic trap, the thing every engineer wants to do and shouldn't. Yeah, that's fair. I'd push back on it too if a client pitched it to me cold.
It works in this specific case for one reason. The off-the-shelf tools are all built around the assumption that different people do different jobs. Sales lives in one tool, the work lives in another, the brand lives in a third, and the seams between them are where the integrations and the Zapier glue and the weekly reconciliation live. I don't have those seams. It's just me. The brand, the code, the data, the outreach, all of it is one person, so the tool that fits is one tool that holds all of it in one schema.
When the deal and the deliverable and the proposal and the personalized page a prospect saw are all rows in the same database, a lot of work disappears. Nothing to sync, nothing to reconcile between apps. A deal detail page can show me the full proposal record right there, the channel it came through, the bid, the questions I answered, the link to the page I sent them, because it's all one record and I wrote the page that renders it.

The other reason is honest: I like building it. The mornings I spend extending the cockpit aren't a tax, they're the thing I'd be doing anyway. A bought tool I'd tolerate. A tool I built I actually open.
The deal pipeline
A deal in my system is a row with the usual fields, plus one I care about a lot, which is a JSON blob that holds the full proposal record. Most CRMs treat a proposal as an attachment or a link off to some other app. Mine treats it as structured data living on the deal: the channel, the job title and URL, when I submitted, the current status, the bid, a summary of what they asked for, the actual text I sent, the screening questions and my answers, and a link to whatever personalized page I pointed them at.
That last field is the one that ties the whole system together, so let me come back to it in a second.
The pipeline view rolls those deals up into a small stat strip. Open count, total value, and a probability-weighted value, which is just each deal's amount times its win probability summed across the pipeline. The weighted number is the honest one. Total pipeline value is a vanity figure because half of it won't close. Weighted value is roughly what I should actually expect, and watching that number is how I know whether I need to be doing more outreach this week or whether I can put my head down and build for the clients I already have.
“Total pipeline value is the number that makes you feel good. Weighted value is the number that tells you whether to panic.
”
The outreach funnel feeds it, and one channel is freelance
There's a cold-outreach funnel feeding the top of the pipeline. The cockpit shows me a rollup of it: how many contacts, how many active sequences, the open task load, what's due today, and a breakdown by lifecycle stage from lead all the way through to customer. It links out to the full workspace when I need the detail, but the rollup is usually enough to tell me whether the top of the funnel is healthy.
One of the channels that feeds the pipeline is freelance work through Upwork. It gets its own slice in the cockpit because the rhythm is different from cold outreach, but it's the same idea: proposals become deals, deals get a weighted value, the work flows into the same board as everything else.
The outreach itself is hand-written. Every proposal and every first message is something I actually wrote, looking at the actual job and the actual person. The system holds the record of it, ranks my follow-ups, and keeps me from dropping a thread. It doesn't write the message and it doesn't blast anything out. A prospect is a person I'm talking to, not a row getting processed. The tooling is there so the personal part has room to stay personal, because the part that wins the work is the part a script can't fake.

The personalization layer
Now the fun part. The proposal record holds a link to a personalized page, and that link is a real feature of the site, not a mockup.
If you land on the site with a ?to= on the URL, the page knows who you are. At the simplest level it greets you by name in the hero. Underneath that there's a quieter mechanism: a ?to= can carry a short codename instead of a literal name, and the codename resolves through an API to a fuller record, a real display name plus a couple of hooks into the parts of the site that are mostly built for delight.
The way it's wired matters, so a quick note on the engineering. The server never blocks render on the lookup. The HTML that ships is generic, the same for everybody and safe to cache, and the personalization resolves on the client after the page is interactive. A personalized URL also tells search engines not to index that variant, because a page addressed to one person has no business showing up in results. The lookups cache per session so a refresh doesn't re-hit the API. None of that is visible to the person it's for. It just feels like the site knew they were coming.
The part that's mostly for fun
Tied to that personalization layer is a chaotic-evil 1997 Furby that lives on the site, runs a fictional backend, and will greet some visitors by name. There's a tiny TV room you can wander into. There's a hidden game. Most visitors never trip any of it, which is correct. The people who do are usually the ones who'd appreciate that a practice built around making delightful things put some delight in its own front door.
I'll be honest about why this is in an article about a deal pipeline. The easter eggs are not a feature anyone's paying for. They're a tell. A site that has a working Furby with its own voice lines and a hidden game and a per-visitor greeting was built by someone who can do the brand work and the front-end and the little bit of mischief that makes a thing memorable, all on the same afternoon. The command center proves I can build the boring systems. The Furby proves I'd enjoy building yours.

How it actually gets built
The whole thing runs on a Claude Code multi-agent setup. I work across several terminal sessions, each one a different piece of the build, and I orchestrate them the way you'd orchestrate a small team if the team never needed a meeting. One session extends the cockpit, another writes an article, another renders images on a separate machine. The work that used to need a brand person and a developer and a data person happens in parallel because the typing is parallelized, and the judgment stays in one head. Mine.
I've written about the morning sequence that feeds this in the studio routine I run before the first meeting, and the council-of-agents pattern I use for harder decisions in the agent council post. The two-machine render pipeline that made the images on this page lives in the batch orchestration write-up. The command center is where all of that lands, the surface the agents are building toward.
The documents and cadences underneath the cockpit, the intake template and the SOW skeleton and the rest, I covered separately in the practice operating system post. That post is the documents layer, the stuff you write down once. This one is the tooling that sits on top and reads those documents back to you every morning.

What this is evidence of
I didn't build the command center to sell command centers. I built it because I run a practice and I needed one, and buying five tools that half-fit was more annoying than writing one that fit exactly. But the thing it ended up proving is the thing that's hard to prove any other way.
A retainer is a bet that one person can hold the whole picture. The brand, the build, the tracking, the data, the follow-up, without dropping the threads between them. The command center is me holding my own whole picture in one screen. If I can do that for my own practice, with my own brand and my own database and my own outreach all in one place, that's a pretty direct preview of what holding yours looks like.

Frequently asked questions
Why build your own CRM instead of using a normal one?
Off-the-shelf CRMs assume different people do different jobs, so they split sales, work, brand, and data across tools that you then have to keep in sync. I'm one person doing all of it, so the tool that fits is one schema that holds all of it. When the deal, the deliverable, and the proposal are rows in the same database, the syncing and reconciliation work just disappears. I'm not recommending most people build their own. It fits my specific situation because there are no seams between roles to integrate across.
Is the outreach automated?
No. Every proposal and first message is something I wrote looking at the actual job and the actual person. The system holds the record, ranks my follow-ups, and keeps me from dropping a thread, but it doesn't write the message and it doesn't send anything in bulk. The part that wins the work is the part a script can't fake, so I keep that part by hand and let the tooling carry the bookkeeping.
What is the `?to=` personalization actually doing?
A ?to= on the URL lets a page greet a specific visitor and, with a codename, turn on a couple of small delight features tuned to them. The server never blocks render on the lookup, so the shipped HTML stays generic and cacheable and the personalization resolves on the client after the page is interactive. Personalized variants are flagged not to be indexed, since a page addressed to one person shouldn't show up in search.
Why is there a Furby in a portfolio site?
Because a site that runs a Furby with its own voice lines, a hidden game, and a per-visitor greeting was clearly built by someone who can do the brand, the front-end, and the playful bit on the same afternoon. The command center proves I can build the boring systems. The easter eggs prove I'd enjoy building yours. Most visitors never trip any of it, which is the right amount.
How does the multi-agent setup work day to day?
I run several Claude Code sessions at once, each on a different piece of the build, and I orchestrate them like a small team that never needs a meeting. One session extends the cockpit, one writes, one renders images on a separate machine. The typing parallelizes; the judgment stays in one head. I've written more about the daily sequence in the studio routine post.
Sources and specifics
- The cockpit is read-mostly composition over existing CRM helpers, added with no new tables or migrations.
- The "what needs me today" list is capped at seven items and ranks overdue tasks, then due-today tasks, then deals with no activity in fourteen days.
- The kanban board's lanes are work areas (site, SEO, outreach funnel, LinkedIn, freelance channel, projects, admin), not deal stages.
- Deal records store a structured proposal blob: channel, job title and URL, submission time, status, bid, request summary, sent text, screening questions and answers, and a personalized-page link.
- Pipeline value is shown three ways: open count, total value, and probability-weighted value (amount times win probability summed across open deals).
- The personalization provider never blocks server render on the codename lookup, marks personalized variants no-index, and caches lookups per session.
- The packaged version of the documents underneath this tooling is the Operator's Stack. If you want to talk about a build, availability is here.