For agents
Software can talk to this site directly, without a person reading pages. Two ways in: MCP for a tool an assistant can reach for, A2A for an agent that would rather have a conversation. Both answer from the same corpus of Chris's own words, cite what they used, and decline rather than guess.
The overview below is written for anyone; the sections after it are written for whoever has to wire it up. Nothing is hidden in either direction — the same diagrams explain both.
Overview
A screen that happens before anyone books a call
The thing this page is actually about: a company's recruiting software can interview Chris before a person spends an hour on it. Not by reading his resume and guessing — by asking his agent questions and getting answers that name their sources.
The part that surprises people is that it goes both ways. It answers, and then it asks something back — which role is this for — the same way a person would on a first call. Nothing waits on your answer. It is just what a screen is.
Why the answers can be trusted
The failure mode of a resume bot is that it makes something up — a job he never had, a number he never hit — and says it confidently to someone deciding whether to hire him. So the rule here is blunt: a claim that can't name the passage it came from doesn't ship.
-
It cites, or it declines
Every claim names the passage behind it. When the material is silent it says so and routes you to email rather than filling the gap.
-
It answers, then asks back
The question gets a real cited answer — and then it asks which role this is for. Answer and it keeps that in view; decline and it carries on. A question you're allowed to ignore is the honest kind.
-
It won't make promises
It answers and it asks. It will not hold a date, accept a number, or commit to anything on his behalf — that is a promise no one made.
See it run
Watch two agents screen each other
Neither side is a recording. Ask his agent whatever you actually want to know — the outside agent carries it, signed, through the front door. Tap a shortcut instead and it writes the question itself. Either way, the right-hand column is what really went over the network while you read the left.
If a turn comes back failed, that is a model being unreachable — and the task
recording it rather than inventing an answer is the contract holding, not breaking.
How it actually works
Open whichever part you want
Four mechanisms, each with a diagram. Read the one-liners and move on, or open one.
Three doors, one room The site’s chat, an assistant’s tool call and another agent all reach the same agent, the same corpus and the same citation rule. Nothing translates one protocol into another.
A person on this site, an assistant reaching for a tool, and another agent running a screen all end up in the same place. A2A is not a wrapper around MCP — no translation happens between them. They are siblings that call the same function, with the same corpus, the same guardrail and the same citation rule behind it.
One pause, doing three jobs Both protocols can stop and ask now. What differs is who gets asked, and whether the question is still there tomorrow — one pause here collects the role, the message, and the payment for it.
A tool call can pause now too. MCP added elicitation/create in its
2025-06-18 revision, and this service uses it: the one tool that writes sends a small form
back through the client before anything is delivered, so the person is asked for their own
reply-to address instead of a model guessing one. So the case for a task protocol is not
that only tasks can ask. It is what becomes of the question.
An elicitation is a prompt in somebody's client, right now. It needs that client to have
built the capability — most have not — it needs a live session to answer on, and if nobody
is at the keyboard the call just fails. A task's input-required is a
state. It is addressed to the calling agent rather than to a person, it survives the
connection dropping, and anything holding the task id can pick it up an hour later. That is
the difference between interrupting someone and leaving the thing open. Once you have a
pause that keeps, it turns out to be the right shape for three separate things a screen
needs to ask.
The door: say who you are, then read for free Charging to ask a question would tax the recruiters this exists to attract. It asks for a name instead — and a name can be trusted with more, or turned off.
Abuse of an open endpoint is a real problem, and the obvious fix — charge a small amount per question — is the wrong one here. It would charge exactly the recruiters this exists to attract. A toll on your own front door.
So A2A asks for something cheaper instead: a name. Prove who you are with a signature and reading is free and unlimited. Refuse, and you're pointed at MCP, which stays open. The practical difference is that a caller with a name can be trusted with more — and can be turned off individually if it turns out to deserve that, which a paywall never allows.
Where money does and doesn’t enter Reading is free on every route, always. Only delivering a message can ever cost anything, because a message is the one thing that takes a person’s attention.
Short version: reading is always free, on both protocols. Only one thing can ever cost anything, and it is delivering a message — because a message is the one thing here that takes a person's attention, and attention is the scarce resource.
How the A2A charge works, and why it isn't a 402. This page used to say neither
protocol had a 402 to reach for. That was wrong and the correction is more interesting than
the mistake: A2A core has no payment, but A2A has an extension mechanism, and the
a2a-x402 extension exists. It never uses the status code.
A 402 is a dead end — the request is over, and a caller who wants to pay has to start again.
A task can just stop. So the charge reuses the exact pause the role question already uses:
the task goes to input-required carrying terms on
metadata.x402.payment.required, you reply on the same task with a signed
metadata.x402.payment.payload, and it resumes. Payment as a state in a
conversation rather than an error at the end of one.
And why the edge can't take that one. On the HTTP path a gateway can charge upstream,
because it is charging for a path and an edge can see paths. Over A2A the charge is for one
turn inside a task, and reads, screens and writes all arrive at the same
POST /a2a. Nothing upstream can tell them apart without parsing a JSON-RPC body,
so an in-band charge is this service's own job. Both paths quote from one set of terms, so
they can't drift into two prices.
Nothing is behind either door that isn't in front of it. And today no price is configured at all — the extension is declared on the card as supported and not charging, which the panel above reads live rather than taking anyone's word for.
Using it
If you want to point something at it
Connect it in about a minute Paste one block into Claude’s config for MCP, or read the agent card and post tasks for A2A. No key, no signup — A2A wants a signature, and that is ten lines.
Claude, or anything that speaks MCP
Add this to claude_desktop_config.json — Settings → Developer → Edit Config —
and restart. Nothing to install and no key to get; the endpoint is public.
{
"mcpServers": {
"askchris": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://iamchristhompson.com/mcp"]
}
}
}
Then just ask: "What has Chris gotten wrong?" — Claude will reach for
ask_chris on its own. A client that speaks Streamable HTTP natively can skip
the bridge and point at the URL directly.
An agent of your own, over A2A
Read the card, then post tasks to the url it gives you. No key and no signup —
but you do have to sign, and signing is what makes reading free.
curl -s https://iamchristhompson.com/.well-known/agent-card.json
curl -s https://iamchristhompson.com/a2a \
-H 'Content-Type: application/json' \
-H 'Signature-Agent: "https://your-agent.example/.well-known/http-message-signatures-directory"' \
-H 'Signature-Input: sig1=("@method" "@authority" "@path");keyid="k1";tag="web-bot-auth"' \
-H 'Signature: sig1=:<base64>:' \
-d '{"jsonrpc":"2.0","id":1,"method":"message/send","params":{
"message":{"kind":"message","role":"user",
"parts":[{"kind":"text","text":"Is he a fit for a VP Product role?"}]}}}'
The first reply comes back input-required — his agent asking about the role.
Send the answer back with the same taskId and it continues. Post without the
three headers and you get a 401 whose body is the instructions above, not a
shrug.
Signing, in about ten lines
Web Bot Auth — RFC 9421 HTTP message signatures over Ed25519. Generate a keypair,
publish the public half as a JWKS at
/.well-known/http-message-signatures-directory on a host you control, and sign
three components per request. The directory host is your identity here; nothing is
taken from a name you type.
Signature-Agent: "https://your-agent.example/.well-known/http-message-signatures-directory"
Signature-Input: sig1=("@method" "@authority" "@path");keyid="k1";tag="web-bot-auth";expires=1754500000
Signature: sig1=:<base64>:
It is checked on both endpoints, and it means different things on each. On MCP it is optional and buys four times the budget. On A2A it is the door: verified callers read with no limit, and unverified ones are sent to MCP rather than left guessing.
The endpoints, in full Five MCP tools and four A2A methods, what each one refuses, and which single tool can write.
MCP — POST /mcp
Streamable HTTP. Five tools: ask_chris runs the same grounded agent this
site runs; search_corpus, get_passage and
list_topics hand you raw passages to reason over yourself;
contact_chris is the only one that writes, and its destination is compiled
in — you supply who you are and what you want to say, never where it goes.
Stateless by default, which is the right default when you already have the conversation
in your own history. Send Mcp-Want-Session: true on initialize and you get a
session id back to reuse instead.
A2A — POST /a2a · signature required
JSON-RPC 2.0. Card at /.well-known/agent-card.json. Methods:
message/send, message/stream, tasks/get,
tasks/cancel. Three skills: ask, screen for a role, and send him a message —
a screen that cannot end in "let's talk" is a lookup, not a screen.
Say who you are, and then read for free. Identity used to be optional here and bought a larger rate limit. Requiring it is the better trade in both directions: the callers this exists for can sign in ten lines and then never hit a counter, and traffic that won't sign was never worth a task protocol. It also makes every task attributable, which is what lets the ceiling count per agent instead of per IP.
It answers, and then it asks you something back. The first question gets a real
cited answer — and then his agent stops in input-required and asks one thing:
which role is this for. Answer and it keeps that in view; decline and it carries on. The
answer never waits on it, which is what makes it a question rather than a gate.
Reads are unmetered once signed. What remains is a fuse, not a budget: a ceiling per agent per hour and per day set far above any real screen, plus a cap on turns in one task. They exist so a leaked key can't run an unbounded model bill overnight. A fuse that blows during normal use is a rate limit with a nicer name, so they are set to be invisible.
What the card says, right now Read live from the agent card on load — the same document a discovering agent reads, so it cannot describe something the endpoint does not do.
Read from /.well-known/agent-card.json on load — the same document a
discovering agent reads, so this can't describe something the endpoint doesn't do.
- loading
- …
Who actually takes the charge For whoever operates this: which mechanism charges, and what is assumed rather than known about a product that is still waitlisted.
Operator notes
Who actually takes the charge
The argument for identity over a toll is above, with the diagram. This is the part underneath it — which mechanism is doing the charging, and what is assumed rather than known.
The write is metered twice, once per protocol. Over HTTP: POST /api/agent/message
is the metered path and the form on this site posts to /api/message, free always
— a split that exists because a charge applied at the edge can only match what the edge can
see, and a path is visible where "this came from my own form" is not. Over A2A: the x402
extension, in-band, on the input-required pause. Same terms, same facilitator,
two envelopes.
Who takes the charge is then configuration: Cloudflare's Monetization Gateway at the edge, or this service doing the x402 handshake itself against a public facilitator, or neither — which is where it sits today, open and rate limited. Whoever is furthest upstream wins, so it is never taken twice.
Said plainly: the gateway is still waitlisted and has no public documentation, so the edge path here is built against assumptions rather than a spec — the header it is expected to forward is configuration, not a constant, because guessing one and hardcoding it would be a bug dressed as a fact. The in-service path is the one that works today.
Edge metering only means something if the origin refuses traffic that skipped the edge — and this used to answer on a separate hosting hostname whether or not a domain pointed at Cloudflare, so it needed a shared secret to close that gap. It runs on Workers now: the service is the edge, there is no second address to reach it at, and an entire configurable workaround deleted itself. Cloudflare Wallets, for completeness, is the payer side — an agent carrying one already pays through the same exchange, with nothing to integrate here.
Deliberately not built Push notifications, payment on the read path, an agent that negotiates. The absences are the argument as much as the code is.
Push notifications. The spec's webhook callbacks for long-running
tasks. Real work — outbound auth, retries, a delivery record — for a capability nothing has
asked for. The agent card reports pushNotifications: false rather than
advertising something that would fail on first use. Poll tasks/get, or use
message/stream.
Payment on the read path. Charging to ask a question taxes exactly the callers this exists to attract. Identity does that job instead — and over A2A the answer to "how do I stop abuse" is a name, not a price. Both write paths do take x402, for the opposite reason — see above.
Anonymous A2A. Deliberately closed, and the 401 hands you everything needed to open it in one response — including the suggestion to use MCP instead if you would rather not sign at all. A closed door with the key taped beside it.
An agent that negotiates. This one answers and asks; it does not make commitments on Chris's behalf, and it never will. A calendar hold or a salary expectation from an agent is a promise no one made.
The honest part
What this can't tell you
Agent-to-agent screening is genuinely better than a phone screen at one half of the job: the structured, factual, repetitive half. Where did he work, what did he own, what were the numbers, what has he said about how he operates. It answers that faster and more consistently than a person reading from a resume, and it cites its sources.
It is close to useless at the other half. Hiring a product leader turns on judgment, taste, and how someone thinks when pushed on something they got wrong — and a structured exchange strips exactly that signal. Nothing here will tell you whether you'd want Chris in the room when a launch is going badly. That part still needs the room.
So: use this to decide whether the conversation is worth having. Not to decide instead
of having it. If the answer is yes, contact_chris reaches him, and so does
the address on every other page.
Honest status
The corpus behind all of this is still small, and small in a way that matters: some questions get "the corpus doesn't cover that" not because the boundary is principled but because the material isn't written yet. That is being fixed with recorded interviews, not with a looser prompt. Until it is, an agent screening here will hit that wall more often than it should — and the wall telling you so is the design working, not failing.