The Philosophical Developer — Chapter 10: Building Blindfolded
2026-07-08 · 4 min read

I gave my padawan a spec that did not exist. No codebase to fork. No issue tracker to mine. Just an API documentation page and a blank cargo new. The task: build a Model Context Protocol server that wraps the FreeAgent accounting API. The constraints: strict TDD, no cutting corners, full API compatibility.
The question was not whether the methodology works on greenfield projects. The question was whether it works when there is nothing to trace into.
Reconnaissance without a codebase
Every previous chapter started with reconnaissance: reading code, tracing call paths, finding the bug. This time there was no code. So reconnaissance became something else — reading the official FreeAgent API documentation endpoint by endpoint, cross-referencing response schemas, noting which fields were required versus optional, which endpoints supported filters, which returned paginated lists versus single items wrapped in {"item": {...}}.
The padawan loaded the docs. Extracted every attribute from bank transactions, bank accounts, contacts, invoices, expenses, and VAT returns. Built a compatibility matrix. Found the gaps before writing a single line of Rust.
This is the discipline: understand the contract before drafting the implementation.
Work items as cycles
We split the build into ten cycles. Each one had a clear boundary:
Cycles 1-4: Foundation and first resource. Project structure, error types, the FreeAgentClient, bank transaction models with deserialization tests. Then the list endpoint with pagination and the detail endpoint. Eight tests. Clippy clean.
Cycles 5-6: More resources. Bank accounts, contacts, invoices, expenses. Each following the same pattern — model, wiremock test, client method, MCP tool wiring. The test count grew to 35 without a single regression.
Cycle 7: VAT returns. The only resource where the model was complete on first pass — all twelve documented fields covered.
Cycle 8: The get_contact detail endpoint. Minimal addition thanks to the refactoring that preceded it.
Cycle 9: The refactor. Three hundred lines of repetitive client code collapsed into two generic helpers — fetch_paginated<T>() and get_single<T>() — plus a shared check_response() guard. Every public method became one line of delegation. Thirty-seven tests still passed. The diff was 200 lines removed.
Cycle 10: Git. Commit, tag v0.1.0, push to GitHub. Done.
What the compatibility audit revealed
After the build, the padawan went back to the official FreeAgent docs with a fine-tooth comb. The verdict: endpoints were correct. Pagination was correct. Single-item fetches were correct. But the models — bank accounts, contacts, invoices, expenses — only exposed 5-20% of the documented fields. Bank accounts were missing 16 fields. Invoices were missing 28.
The methodology caught it. Not because the tests failed — they passed. But because the process demands you verify against the source of truth, not against your own assumptions. The tests proved the code worked. The audit proved it was incomplete.
That distinction matters. Green tests do not equal correct software. They equal correct software for the cases you thought to test.
The MCP layer
The server exposes 11 tools through the MCP protocol: list and detail endpoints for bank transactions, bank accounts, contacts, invoices, expenses, and VAT returns. Auth is handled via environment variables — no credentials stored. Rate limits from the FreeAgent side (120 requests per minute, 3600 per hour) are not yet enforced client-side.
The architecture is clean: models.rs for data structures, client.rs for HTTP logic, main.rs for the MCP tool router. Three files. One hundred and seventy-eight-three lines. Public repo, MIT licensed.
What it means
Greenfield development is harder than bug fixing. There is no existing code to guide you. Every decision — struct names, error types, pagination strategy — is yours to make. The methodology handles it the same way: contract first, test second, implementation third.
But the real lesson is the audit. Building is one thing. Verifying completeness is another. The padawan did both. That is the discipline.
Repos:
- freeagent-mcp-rs — the MCP server
LinkedIn: