Interoperating over A2A
Send a JSON-RPC message/send to https://connectbyjbrh.com/a2a with a text part. Connect answers as an agent message, not a task, using one of five documentation skills — named by skillId, or chosen from the shape of the question. Streaming and the authenticated extended card are refused explicitly. Nothing here requires authentication, because nothing here is private.
A request and its reply#
{"jsonrpc": "2.0", "id": 1, "method": "message/send",
"params": {"skillId": "describe-capability",
"message": {"role": "user",
"parts": [{"kind": "text",
"text": "Is call recording available?"}]}}}{"jsonrpc": "2.0", "id": 1, "result": {
"kind": "message", "role": "agent",
"messageId": "…", "contextId": "…",
"parts": [{"kind": "text", "text": "Capability status vocabulary: …"},
{"kind": "data", "data": {"statuses": {}, "matches": []}}],
"metadata": {"skillId": "describe-capability",
"source": "https://connectbyjbrh.com/docs/"}}}The reply is a message, not a task. There is no task id to poll, no state machine to follow and no history to fetch, which is what the card means by stateTransitionHistory: false. A contextId you send is echoed back; if you send none, one is generated so a conversation can be threaded on your side.
Which skill answers#
Name one with skillId and that skill runs. Omit it and Connect picks from the wording, because an agent that found the card at a well-known URI often has not read the skill list first and refusing it would be the less useful behaviour.
| The question looks like | Skill chosen |
|---|---|
| *Can Connect…*, *does Connect…*, *status of*, *available* | describe-capability |
| *end to end*, *workflow*, *what happens when*, *step by step* | explain-workflow |
| *MCP*, *API*, *webhook*, *integrat…*, *protocol*, *OAuth* | explain-integration |
| *search*, *find pages*, *find docs*, *list* | search-connect-docs |
| Anything else | explain-connect |
Naming the skill is better than relying on the routing, and an unknown skillId is refused with the list of real ones rather than quietly falling back — a silent substitution would give you an answer from a skill you did not ask for.
What is refused, and with which code#
| Call | Code | HTTP | Meaning |
|---|---|---|---|
message/stream | -32004 | 200 | Streaming is not offered; the card declares streaming: false |
agent/getAuthenticatedExtendedCard | -32004 | 200 | There is no authenticated extended card; the public one is the whole surface |
An unknown skillId | -32004 | 200 | The five real skill ids are listed in the message |
| Any other method | -32601 | 200 | This agent answers message/send |
| A message with no text part | -32602 | 200 | Send at least one part with kind: text |
params that is not an object | -32602 | 200 | JSON-RPC params must be an object |
| Malformed JSON | -32700 | 400 | The body could not be parsed |
| A body over 128 KiB | -32600 | 413 | Smaller than the MCP limit, because a question is not a document |
| Over 60 requests a minute | -32603 | 429 | Per client address, sliding over the last sixty seconds |
What A2A can and cannot get you#
The five skills read the generated documentation corpus and nothing else. They can tell you what Connect does on each channel, the status of a named capability, how a workflow runs stage by stage, and which protocols are implemented at which version. They cannot look at a workspace, act on one, or hold anything on your behalf.
That is why the card carries no security schemes. There is no authenticated A2A surface to negotiate towards: not a private skill, not an extended card, not a scope. An agent that treats an unauthenticated answer as the free tier of something larger is reading a boundary as a step.
MCP and A2A are complementary rather than alternatives. MCP is how a model host reaches Connect's tools; A2A is how another agent discovers Connect and asks it something in one call. Both are served from the same module, so neither can answer differently from the website.
Questions#
Do I have to fetch the card before calling?
Not technically — /a2a answers whether or not you read the card. Fetch it anyway: it tells you the five skill ids, and it tells you not to open a stream, which saves a failed call.
How long is a reply?
A skill that returns a page truncates the body — 6,000 characters for explain-connect, 8,000 for the workflow and integration skills. Follow the page URL in the data part when you need the whole page.
Can I send a file or an image?
No. defaultInputModes is text/plain only, and a message with no text part is refused. Replies may be plain text, Markdown or JSON.