Adopting AI Without Adopting Tech Debt (September 2026)

Austin CTO Club Talk Jan 2026
This is a refreshed blog adaptation of a talk I gave at the Austin CTO Club in January 2026.
TL;DR: AI coding agents change the tech debt problem from typing speed to alignment speed. Give every change a small context contract, keep ownership narrow, isolate protocols behind tested boundaries, and require evidence from the real system before merging. For MCP Apps, ChatGPT Apps, and Claude Connectors, that evidence has to cover both the MCP contract and the host states users will see.
Hi, I’m Abe. I previously sold Trigo, where I was CTO building AI in property tech. I’ve since been building sunpeak, the open-source MCP App framework and MCP testing framework for building and testing MCP Apps across ChatGPT, Claude, and other MCP hosts.
My view has changed since the original talk. The question in early 2026 was how to let agents write more code without creating a cleanup backlog. Nine months later, the useful answer is more specific: treat context as a versioned dependency, concurrency as a budget, protocols as replaceable adapters, and validation evidence as part of the change.
AI Changes the Shape of Tech Debt
Classic tech debt came from schedule pressure, weak ownership, missing tests, and design shortcuts. AI adds a new failure mode. A team can now create a lot of plausible code before anyone notices that the assumptions behind it have drifted.
The code may look fine in isolation. The debt appears between changes:
- One agent follows an old API pattern while another follows the current one.
- A schema changes, but its examples, migration notes, docs, and fixtures do not.
- Two agents add different helpers for the same task because neither saw the other’s branch.
- An MCP App works in one display mode but clips controls in another.
- A tool returns valid JSON but leaks UI-only data into model-visible context.
- A fallback was described in a prompt but never exercised when the host omitted that capability.
These are alignment bugs. More output makes them arrive faster, but more review alone does not fix the source. Teams need a repeatable contract for what an agent may change and what proof it must return.
Give Every Change a Context Contract
A huge prompt is not a reliable context system. It mixes durable rules, one-off instructions, and facts that may already be stale.
Split context into three layers:
- Repository context covers architecture decisions, code style, ownership, security rules, validation commands, and known traps. Keep it beside the code in files such as
AGENTS.md,README.md, and short decision records. - Task context states the intended outcome, allowed files, interfaces that may change, acceptance checks, and anything explicitly out of scope.
- Live context comes from the current repository, running services, official docs, logs, and test output. Agents should inspect this rather than trust an old summary.
For each task, turn those layers into a short change contract:
| Contract field | Question it answers |
|---|---|
| Intent | What user or system outcome should change? |
| Scope | Which packages, files, and data may change? |
| Boundaries | Which APIs, schemas, or protocol revisions must remain compatible? |
| Evidence | Which tests, browser states, logs, or responses must pass? |
| Recovery | How can the team disable or reverse the change? |
The contract should be small enough to review before work starts. If it grows into a product spec, split the task.
Context also needs ownership. Put an owner and a review trigger on rules that agents will reuse. An architecture note should change when its interface changes. A host matrix should change when support changes. A validation command should fail loudly when it stops representing the release path.
For shared context that does not belong to one repository, Alignbase gives teams a place to manage common instructions, Skills, and working Memory. Its guide to shared AGENTS.md for teams explains how to split repository rules from team-wide rules. Keep product-specific examples and test fixtures near the code because that is where reviewers can verify them.
Set a Concurrency Budget
AI raises the number of changes one engineer can start. It does not raise the number of conflicting decisions a codebase can absorb.
Treat concurrent agent work like concurrent database writes. Parallel work is cheap when tasks touch separate ownership boundaries. It gets expensive when several tasks change the same schema, shared helper, auth path, or design system at once.
A simple concurrency budget helps:
- One active writer for a shared contract unless the work is coordinated in one branch.
- Separate tasks by package, service, or resource boundary when possible.
- Rebase and rerun boundary tests after a contract changes.
- Stop starting work when review and validation queues grow faster than they clear.
- Record abandoned approaches so the next agent does not repeat them.
This is also why smaller ownership groups work well. A small group with a clear service or package boundary makes fewer coordination decisions. Stable contracts let other groups use that work without copying its internal choices.
Treat MCP as Versioned Infrastructure
Model Context Protocol gives clients and servers a common contract for tools, resources, prompts, and optional extensions. That removes many custom integration seams, but it does not remove versioning work.
The MCP 2026-07-28 specification made the core protocol stateless. Requests are self-contained, and clients send their supported capabilities per request. Optional features such as Tasks, Skills over MCP, and MCP Apps remain extensions negotiated by the client and server. A server cannot assume that every client supports every extension.
That changes the engineering checklist:
- Record which core revision and extensions the server supports.
- Validate capabilities on every request instead of relying on a hidden session handshake.
- Return a useful non-UI result when an MCP client does not support MCP Apps.
- Keep tool annotations and other hints separate from authorization checks because clients may treat them as untrusted metadata.
- Put protocol parsing, discovery, auth, and extension handling behind a narrow adapter.
- Add contract tests before upgrading an SDK or protocol revision.
The adapter should own tool definitions, JSON Schema inputs, resource registration, output schemas, result fields, auth challenges, and capability checks. Product components should receive typed application data. They should not each invent their own reading of _meta or protocol revision rules.
That boundary makes an upgrade reviewable. You can see which wire contract changed, which product types depend on it, and which old behavior still needs a fallback.
Keep MCP Apps Portable at the Center
MCP Apps add interactive UI to an MCP tool. A tool points at a ui:// resource through _meta.ui.resourceUri, the host loads that resource in a sandboxed frame, and the app communicates with the host over the MCP Apps UI protocol.
The portable center of an MCP App should include:
- Tool input and output schemas.
- Model-readable
contentandstructuredContent. - UI-only result data in
_meta. ui://resource registration and MIME details.- App state and the smallest set of UI-to-host calls the feature needs.
- Content security policy and permission requests.
- A text path that remains useful when the client does not render the app.
Host-specific behavior belongs at the edge. OpenAI’s current guide to building ChatGPT UI with MCP Apps uses the same standard resource, tool, result, and ui/* message lanes, with host support and product workflow documented separately. Other hosts can support different display modes, bridge features, auth flows, and distribution rules.
Use capability checks for optional behavior. If a host cannot open fullscreen, render a useful inline state. If it cannot call an app-provided tool, offer a server-tool or message-based path where the product allows one. If the app depends on a feature with no fallback, state that support requirement instead of failing silently.
Require an Evidence Bundle
An AI-generated diff is a proposal. The finished change is the diff plus evidence that its contract holds.
For a normal application change, ask for an evidence bundle with:
- The changed contract, such as a schema, public type, route, or visible behavior.
- Focused automated tests for the new and failure paths.
- A production build or equivalent package validation.
- Browser evidence for every changed user path.
- Console, network, server, and boundary checks relevant to that path.
- Migration and rollback notes when stored data or public behavior changed.
This is more useful than a generic claim that tests pass. It ties each check to a risk.
For MCP Apps, the evidence bundle needs two layers. First, verify MCP behavior: discovery, schemas, valid and invalid tool calls, structured results, resource reads, auth errors, and capability fallbacks. Then verify the rendered app across the states users will hit:
| Dimension | Minimum useful coverage |
|---|---|
| Host | Each supported host plus an unsupported-capability fallback |
| Display | inline and every requested expanded mode |
| Theme | light, dark, and host tokens |
| Width | narrow mobile, tablet, and desktop |
| Data | loading, empty, success, partial, large, and error |
| Auth | signed out, expired, limited, and authorized |
| Tool call | success, validation error, server error, and cancellation |
The broad matrix should run locally with deterministic data. Keep live-host checks narrow because they cost more, change outside your control, and are harder to debug. A local replica cannot prove the current production connection and review path, so keep one real-host check before release.
sunpeak’s inspector supports this loop. It connects to any MCP server through npx sunpeak inspect --server URL, renders resources in ChatGPT and Claude-style runtimes, and lets you switch host, theme, display mode, width, locale, platform, safe area, and tool state. Simulation files pin tool input and output so Playwright checks are repeatable.
For an existing server, scaffold the test harness with:
npx sunpeak test init --server http://localhost:8000/mcp
That gives the team a path from local protocol tests to E2E tests, visual regression tests, focused live-host checks, and multi-model evals.
Measure the Cleanup Work
Code output is easy to count and usually tells you little. Measure where the system rejects or absorbs AI-written changes.
| Signal | What it can reveal |
|---|---|
| First-pass validation rate | Whether agents receive enough context to meet repository rules. |
| Repeated review comments | Rules that belong in code, tests, or shared context instead of another comment. |
| Change collision rate | Too much concurrent work inside one ownership boundary. |
| Duplicate implementations | Weak search, hidden code, or unclear shared ownership. |
| Escaped defects | Gaps between test evidence and production behavior. |
| Rollback time | Whether changes have small boundaries and a real recovery path. |
| Context staleness | Instructions that no longer match the code or release process. |
| Unsupported host states | Product claims that are wider than the tested host matrix. |
Review these by system boundary, not by individual developer. A low first-pass rate may mean the repository has vague rules or slow tests. Repeated comments may mean a convention should become a lint rule, type, fixture, or shared helper.
The goal is to turn repeated judgment into a visible contract. Delete duplicate code, narrow ownership, speed up tests, and update context where the evidence says the system is hard to change.
A Practical Rollout Plan
Before expanding agent use across a team, I would do this in order:
- Pick one service or package with a clear owner and a reliable build.
- Write its repository context and list the commands that prove a change works.
- Add a short change-contract template to issues or task prompts.
- Give shared interfaces one active writer at a time.
- Require focused tests and browser evidence for changed behavior.
- Track first-pass validation, repeated review comments, and escaped defects for a month.
- Turn recurring failures into types, tests, fixtures, or rules before expanding the scope.
- Add more parallel agent work only when the review and validation queues stay healthy.
For MCP Apps, start with one tool and one UI resource. Test the text-only fallback, the interactive resource, error states, and one real target host. Add more tools and host features after the portable contract is stable.
When instructions start spanning repositories, manage context instead of code: keep shared operating knowledge in one reviewed place, then route only the relevant parts to each task. Avoid copying a growing prompt into every repository because copies drift.
Where sunpeak Fits
sunpeak is the layer I wanted while building MCP Apps with agents: an MCP App framework plus a testing framework that understands MCP and host runtime behavior.
Use it when you want to:
- Build one portable MCP App codebase with small host adapters.
- Inspect an existing HTTP or stdio MCP server locally.
- Save deterministic tool and UI states as simulations.
- Test resources, themes, display modes, safe areas, widths, and capability fallbacks in CI.
- Separate fast protocol and browser tests from focused live-host checks and evals.
- Keep protocol details inside a framework boundary instead of spreading them through product code.
For an existing server, start with:
npx sunpeak inspect --server http://localhost:8000/mcp
For a new app:
npx sunpeak new
The current docs start at sunpeak.ai/docs, and the testing overview explains how the protocol, unit, browser, visual, live, and eval layers fit together.
AI can make a small team much faster. That speed pays off when each change has fresh context, a clear owner, a narrow boundary, and evidence that the system still works. Without those checks, the code arrives sooner and the cleanup bill arrives later.
Get Started
npx sunpeak newFurther Reading
Frequently Asked Questions
What causes tech debt when teams use AI coding agents?
The main cause is assumption drift. Agents can write code quickly, but they only follow the context and repository state they can see. If two agents get different architecture rules, stale product requirements, or incomplete test instructions, they create conflicting code faster than a team can review it. Treat context as a versioned dependency, keep ownership boundaries clear, and require evidence from the system each change affects.
How should teams manage context for AI coding agents?
Separate durable repository rules from task-specific instructions and live facts. Keep architecture decisions, validation commands, style rules, and known traps close to the code. Give each task a small change contract that states the goal, allowed scope, affected interfaces, required checks, and rollback path. Give every context file an owner and review it when the code or workflow changes.
Do AI coding agents change how engineering teams should be structured?
They make ownership and coordination limits more important. Higher code output creates more decisions, reviews, and possible collisions. Small groups with clear package or service ownership can move faster because fewer people and agents need to agree on each local choice. Stable contracts between groups keep those choices from spreading through the system.
How does MCP reduce AI adoption tech debt?
MCP gives clients and servers a shared contract for tools, resources, prompts, and extensions. The 2026-07-28 core specification uses self-contained requests and per-request capability negotiation, which reduces hidden session state. Teams still need to isolate protocol code, version the revisions and extensions they support, validate schemas, and test fallback behavior when a client does not offer an optional capability.
What are MCP Apps, ChatGPT Apps, and Claude Connectors?
MCP Apps add interactive UI to MCP tools through a ui:// resource and a sandboxed host frame. ChatGPT Apps are MCP-backed apps that run in ChatGPT, while Claude Connectors connect Claude to external tools and data. Each host has its own supported features and review path, so portable MCP behavior should stay separate from small host-specific adapters.
How do you avoid tech debt when an MCP App supports multiple hosts?
Keep tool schemas, structuredContent, output schemas, UI resources, and app state in a portable layer. Put host metadata, display behavior, auth details, and optional features behind narrow adapters and capability checks. Test the same fixtures across every supported host, theme, width, display mode, data state, and auth state, then keep one focused real-host check for production behavior that a local replica cannot prove.
How does sunpeak help teams test MCP Apps without paid host accounts?
sunpeak includes a local inspector that connects to any MCP server and replicates ChatGPT and Claude-style runtimes. Teams can save deterministic simulations, switch hosts, themes, display modes, device widths, locale, platform, safe areas, and tool states, then run protocol, Playwright E2E, visual regression, live host, and multi-model eval tests as separate layers.
What should CTOs track before scaling AI development?
Track first-pass validation rate, review latency, change collisions, repeated review comments, duplicate implementations, escaped defects, rollback time, stale context, and unsupported host states. These measures show whether agents shorten delivery time or move work into review, QA, security, and support.