{"slug": "i-made-my-website-callable-by-another-ai-agent-here-s-the-actual-json-rpc", "title": "I made my website callable by another AI agent — here's the actual JSON-RPC", "summary": "A developer has integrated the Agent2Agent (A2A) protocol into their llms.txt validator service, enabling other AI agents to discover and call it directly over HTTP without human intervention. The implementation uses a JSON-RPC 2.0 endpoint and a machine-readable agent card, demonstrating a practical example of agent-to-agent communication. The developer emphasizes that advertised skills must resolve to real, working behavior to maintain trust.", "body_md": "Most \"AI integration\" still means a human reads your docs and writes a client. A2A flips that: another *agent* reads a small machine description of what your service does and calls it directly — no browser, no scraping, no human in the loop. I wired it up on a small tool I run (a free llms.txt validator) and it's simpler than the acronyms suggest. Here's the whole thing, with the real requests.\n\n**A2A (Agent2Agent)** is an open protocol — now under the Linux Foundation — that lets AI agents *discover and call each other* over plain HTTP. Think of it as the agent-to-agent counterpart of a public API: instead of publishing OpenAPI docs for humans, you publish a machine description another agent can consume and invoke.\n\nIt has exactly two moving parts:\n\nThat's it. You can ship a useful A2A surface with one skill and a single method.\n\nYou serve a JSON file at `/.well-known/agent-card.json`\n\ndescribing who you are and what you can do. The required fields are `name`\n\n, `description`\n\n, `version`\n\n, `url`\n\n(your endpoint) and at least one `skill`\n\n:\n\n```\n{\n  \"protocolVersion\": \"0.3.0\",\n  \"name\": \"llms.txt Validator\",\n  \"description\": \"Validate a website's llms.txt and return a score with findings.\",\n  \"url\": \"https://llms-txt-validator.dev/a2a\",\n  \"skills\": [{\n    \"id\": \"validate_llms_txt\",\n    \"name\": \"Validate llms.txt\",\n    \"description\": \"Given a domain or URL, fetch and validate its llms.txt.\"\n  }]\n}\n```\n\nThe card is a **contract**, not a meta tag. An agent fetches it, sees a `validate_llms_txt`\n\nskill, and knows both what you offer and where to call.\n\nThe card's `url`\n\npoints at a **JSON-RPC 2.0** endpoint. An agent invokes the `message/send`\n\nmethod with a message; you do the work and return a `Task`\n\n. Here's a real call to my agent:\n\n```\nPOST /a2a\n{ \"jsonrpc\": \"2.0\", \"id\": \"1\", \"method\": \"message/send\",\n  \"params\": { \"message\": { \"role\": \"user\",\n    \"parts\": [{ \"kind\": \"text\", \"text\": \"validate llmstxt.org\" }] } } }\n```\n\n…and the reply — a completed task carrying a human-readable summary *and* structured data the calling agent can use directly:\n\n```\n{ \"result\": { \"kind\": \"task\", \"status\": { \"state\": \"completed\" },\n  \"artifacts\": [{ \"parts\": [\n    { \"kind\": \"text\", \"text\": \"Validated llmstxt.org: score 100/100...\" },\n    { \"kind\": \"data\", \"data\": { \"ok\": true, \"report\": { \"scores\": { \"overall\": 100 } } } }\n  ] }] } }\n```\n\nNo HTML, no parsing, no guessing. The agent asked a question in natural language and got back exactly the data it needed. You can `curl`\n\nthis yourself.\n\nYou don't need the whole spec to start. Pick *one* real thing your service does and:\n\n`/.well-known/agent-card.json`\n\nwith one skill.`message/send`\n\nmethod wrapping that capability.`Task`\n\nwith the result as an artifact.Streaming, task history, and push notifications are all optional — set `capabilities.streaming`\n\nto `false`\n\nand add them only when you actually need them.\n\nThey stack rather than compete: A2A reaches networked agents, WebMCP reaches in-browser ones, MCP wires tools into one model.\n\nIt's tempting to drop an agent card to look modern and leave the endpoint returning `501`\n\n. Don't. An agent that fetches your card and calls a dead `url`\n\ntrusts you *less* afterward — you've spent its call for nothing. Every skill you advertise should resolve to real, working behavior. (That's why the [validator](https://llms-txt-validator.dev/) I built reports an A2A signal as \"present\" only when a live endpoint actually answers `message/send`\n\n.)\n\nIf you ship one, drop your agent card in the comments — I'd like to call it.", "url": "https://wpnews.pro/news/i-made-my-website-callable-by-another-ai-agent-here-s-the-actual-json-rpc", "canonical_source": "https://dev.to/andriy_pyvovarchuk/i-made-my-website-callable-by-another-ai-agent-heres-the-actual-json-rpc-42m", "published_at": "2026-08-04 06:01:22+00:00", "updated_at": "2026-08-04 06:15:08.182268+00:00", "lang": "en", "topics": ["ai-agents", "ai-infrastructure", "developer-tools"], "entities": ["Linux Foundation", "llms.txt Validator", "A2A", "WebMCP", "MCP"], "alternates": {"html": "https://wpnews.pro/news/i-made-my-website-callable-by-another-ai-agent-here-s-the-actual-json-rpc", "markdown": "https://wpnews.pro/news/i-made-my-website-callable-by-another-ai-agent-here-s-the-actual-json-rpc.md", "text": "https://wpnews.pro/news/i-made-my-website-callable-by-another-ai-agent-here-s-the-actual-json-rpc.txt", "jsonld": "https://wpnews.pro/news/i-made-my-website-callable-by-another-ai-agent-here-s-the-actual-json-rpc.jsonld"}}