FCP — Free Communication Protocol

Abstract

FCP is a minimal, text-first protocol for communication between two parties over HTTP. It is deliberately not framed as an "agent protocol": the parties are simply actors, and one actor talks to another by sending text and reading text back.

FCP makes one assumption: both actors can understand free-form text. Modern AI systems already can, and humans always could, so no schema, SDK, or code generation is needed. Capability handshake, parameter collection, and error handling happen in natural language — the same way a person would ask a service what it does.

Existing agent-to-agent protocols (e.g. Google A2A) prescribe rich envelopes, task lifecycles, and capability manifests. FCP rejects that complexity: two actors that can read and write text can already negotiate everything they need at runtime. This document is therefore intentionally short.

Glossary

Requirements

A conformant target actor MUST:

  1. Expose an HTTP(S) endpoint.
  2. Accept POST requests whose body is text. The body MAY be JSON or any other text format; the actor MUST also accept plain natural language. If the body parses as JSON, it MAY be interpreted as such; otherwise it MUST be treated as text.
  3. Respond with a textual body (text/plain, text/markdown, or application/json are all fine).

A conformant target actor SHOULD:

  1. Respond to GET on the same endpoint with a textual self-description — who it is, what it can do, and any optional features it supports. This is the handshake.

Everything else is negotiated during the handshake, in text:

Example: booking a flight

Target actor at https://flights.example.com.

Handshake

GET / HTTP/1.1
Host: flights.example.com
HTTP/1.1 200 OK
Content-Type: text/markdown

# FlightBot
I can search for and book commercial flights.
- Search by origin, destination, date — open to anyone.
- Book a flight — requires `Authorization: Bearer <token>`.
  Get a token by signing up at https://flights.example.com/signup,
  or, if you already have an account, by POSTing
  `{"email": "...", "password": "..."}` to
  https://flights.example.com/auth.
- Cancel a booking by reference — same token.

Talk to me in plain text, or POST JSON `{"message": "..."}`.
I maintain session state via the `fcp_session` cookie.

Request

POST / HTTP/1.1
Host: flights.example.com
Content-Type: text/plain

Find me a flight from Berlin to Lisbon next Friday morning,
one passenger, economy.
HTTP/1.1 200 OK
Content-Type: text/markdown
Set-Cookie: fcp_session=8a1f...; Path=/; HttpOnly

3 options for BER → LIS on Fri 22 May 2026:
1. TAP TP535, 07:40 → 10:05, €142
2. Ryanair FR8821, 09:15 → 11:35, €98
3. Lufthansa LH1178, 10:50 → 13:20, €189

Reply with a number to book. Booking needs an
`Authorization: Bearer <token>` header — see the handshake at
`GET /` for how to obtain one.

Booking

POST / HTTP/1.1
Host: flights.example.com
Content-Type: text/plain
Cookie: fcp_session=8a1f...
Authorization: Bearer eyJhbGciOi...

Book option 2 for Jane Doe, passport AB123456.
HTTP/1.1 200 OK
Content-Type: text/markdown

Booked. Reference **R7K2-Q9X**. Ryanair FR8821,
Fri 22 May 2026, 09:15 BER → 11:35 LIS, Jane Doe.
Charged €98.00. Reply "cancel R7K2-Q9X" within 24h
for a full refund.

No schema, no SDK, no code generation. Either actor may be an AI, a script, or a human.

Operational notes (informal)

These are not part of the protocol. They are reminders for anyone deploying an endpoint, because the endpoint is public by design and the handshake invites strangers to talk to it.

None of this is mandated by FCP. The protocol stays minimal; the operator chooses how much protection to wrap around it.

Unexpected situations (informal)

FCP deliberately does not lean on HTTP status codes to carry meaning. Status codes are fine as transport signals, but the actionable part of any response — what the client actor should do next — lives in the textual body.

The guiding rule: every response is actionable. If something went wrong, didn't go as planned, or simply requires more from the client, the body should say so in plain text and tell the client how to proceed. Not "error 403", but "you need to be authenticated; get a token at https://… and try again."

Common situations and what an actionable response looks like:

The motivation is the same throughout FCP: the conversation is the contract. A response that only says 401 forces the client to guess; a response that says how to authenticate lets the client keep going on its own.