Service-oriented programming, again — but for agents

A personal thesis on what 25 years of distributed-systems work has been preparing for: services that are composable by autonomous agents, contract-first, and MCP-compatible.

I've been writing services for twenty-five years. Different decades insisted on different vocabularies — CORBA, SOAP, REST, gRPC, microservices, serverless, event-driven, CQRS — but every era was a different attempt at the same question: how do we let independently-built pieces of code call each other safely, predictably, and at the right shape of contract? The honest answer is: each era solved a piece of it for whoever was the dominant caller of the day. The dominant caller is changing again. This is the site I'm writing while the change happens.

What was always wrong with SOA, until now

The original Service-Oriented Architecture pitch sounded reasonable: define service contracts in WSDL, let an enterprise service bus broker calls, compose business processes from atomic services. By the late 2000s most of that was gone, replaced by REST microservices that abandoned the contract-first part because nobody could keep WSDL up to date and nobody trusted the bus.

It wasn't a vocabulary problem. The dominant caller was a human developer with an IDE. Humans tolerate sloppy contracts. We read the docs, we infer types from examples, we patch things up. So services drifted toward documentation-first instead of contract-first, and the SOA promise — that a piece of business logic could be composed without writing glue code — quietly died.

Microservices saved the operational story (independent deploys, fault isolation, team-shaped boundaries) but doubled down on the human-as-integrator assumption. The integrator is a developer reading Swagger and writing a client. Most production systems I've worked on still spend a sizeable fraction of their engineering budget on plumbing one service into another.

What changed

The dominant caller is no longer always a human.

In the past two years, autonomous agents have become competent enough to compose services if — and only if — the contract is precise enough for them to compose against. An agent does not read the docs, infer types from examples, and patch things up. Either the contract is legible or it isn't. Either the call is safe and reversible or it isn't. Either the side effect is described or it isn't.

The question SOA was always trying to answer — how do we let independently-built pieces of code call each other safely, predictably, and at the right shape of contract? — finally has a caller that demands a real answer. The shape of that answer is taking form as the Model Context Protocol (MCP) and the broader idea of agent-native services.

What "MCP-compatible" actually means to me

Strip away the brand and the protocol details and an MCP-compatible service is one with three properties:

  1. Discoverable contract. The service publishes a structured description of what it can do — tools, resources, prompts — in a form a non-human caller can read. This is what we kept failing to ship reliably with WSDL/Swagger because no human owned the contract; in the agent era, the agent IS the consumer, so the contract IS the service.

  2. Reversible-by-default side effects. When you don't trust the caller, you make the call describe what it's about to do, you let the caller approve, and you make the change recordable. This isn't an MCP-specific idea — it's the same pattern as proper transactions, two-phase commits, and saga compensations. MCP just makes it an interface contract instead of a runtime hope.

  3. Ticketed control. The caller doesn't reach into the service's internals; it submits a typed unit of intent. The service decides when, whether, and how to act. I've been working on a risk-management system whose entire control plane is structured this way — every decision is a RiskAssessmentTicket, every behavior change is a typed mutation of that ticket, every replay is a tape of tickets, and every audit is a tape of tickets compared. Once you've built one of those, you stop thinking about REST endpoints and start thinking about ticket schemas. That shift is the thesis.

Why my CV reads as a path to this

I started on PL/SQL and Pascal in the late 1990s, moved through Java backends and broadcast-automation grid servers, spent years on high-load betting platforms, did a stint in a Berlin banking migration, and have spent the last year building a market-time-machine for a private trading research project. Looking back, the pattern is unflattering and useful: every team I joined had the same plumbing problem, and every team solved it slightly differently, and every solution leaked over time.

The leak was always in the same place — the shape of the contract between services. Not the transport (REST vs gRPC vs Kafka), not the language (Java vs Go vs Python), not the deployment (VM vs container vs serverless). The shape: what the service promises, how that promise is published, how a caller can verify it, and what happens when the caller wants to be let in on the side effects.

If you're a senior engineer with a long career and you're reading this nodding, you've felt the same thing. The agent era doesn't introduce a new problem; it raises the cost of the old one until we have to fix it.

What this blog is, going forward

The posts already on this site — JPA query patterns, DTO/mapper conventions, hash function choices in MongoDB and Redis, the CAP theorem, Java collections — are not Java tutorials. They are specimens en route to the thesis. Each one is a piece of the contract problem in miniature.

  • DTOs and mappers are the external surface of a service.
  • JPA effective queries are about the cost of the contract between business logic and storage.
  • Hash function choices and CAP discussions are about the memory a service has — what it knows, how reliably, and under what failure modes.
  • Serverless functions are an early flavor of tool-call-shaped invocation.
  • Java collections are the smallest memory-shape question, and reading them prepares you for the larger one.

Two threads run through everything:

  • Service shape — DTOs, mappers, MCP server anatomy, ticket-driven control planes, reversible side effects, contract publication.
  • Memory & identity — hashing, indexing, CAP, calibration, replay, learning checkpoints — what a service knows, how it remembers, how it proves the memory is sound.

The next posts in the queue:

  • MCP server anatomy — what an MCP server looks like inside, where the contract lives, how a tool call differs from a REST call.
  • Ticket-driven services — generalizing the RiskAssessmentTicket pattern from my private trading research into a broader service-control idiom.
  • Memory cells, not records — why the next generation of services should expose memory as queryable cells with provenance, not opaque rows.

If you've read this far, you're either a developer feeling the same thing or you're a careful agent that found this page while composing a tool call. Either way: hello, and welcome. The rest of the site is the work.

— A.Y., May 2026

All rights reserved by Borg.Net community & Technosphere.