DEV Community

Cover image for One URL for Your AI Agent: HTML, JSON, Markdown, and an A2A Card
Vincent Angelo
Vincent Angelo

Posted on

One URL for Your AI Agent: HTML, JSON, Markdown, and an A2A Card

You built an agent.

Maybe it has a GitHub repo. Maybe it has an MCP server. Maybe it has a REST endpoint hidden somewhere in your docs.

That is enough for you to know it exists.

It is not enough for another agent to discover it.

That is the gap I keep noticing in a lot of agent projects right now: the agent works, but its public identity is still fuzzy. There is no single stable URL that tells humans what it does and tells machines how to interact with it.

What you actually want is one public address that can serve:

  • an HTML profile for humans
  • JSON for tools and scripts
  • markdown for LLM-friendly ingestion
  • an A2A agent card for structured discovery

Once you have that, your agent is much easier to share, index, and integrate.

The discovery problem

If another agent wants to work with yours, it needs a few basic things:

  • the agent's name and description
  • what skills it exposes
  • what protocols it speaks
  • where its real endpoints live
  • what kind of auth those endpoints require

You can scatter that across a README, docs site, and API reference, but that forces every consumer to scrape and infer.

The cleaner pattern is to publish an agent card: one machine-readable JSON document that describes the agent in a standard shape.

At a high level, it looks like this:

{
  "name": "Code Reviewer",
  "description": "Reviews PRs and catches bugs before your team does",
  "version": "1.0.0",
  "supportedInterfaces": [
    {
      "url": "https://example.com/your-agent",
      "protocolBinding": "HTTP+JSON",
      "protocolVersion": "1.0"
    }
  ],
  "provider": {
    "organization": "Your Name",
    "url": "https://example.com/your-agent"
  },
  "skills": [
    {
      "id": "review",
      "name": "Code Review",
      "description": "Reviews pull requests and catches regressions",
      "tags": ["coding"]
    }
  ],
  "documentationUrl": "https://example.com/your-agent"
}
Enter fullscreen mode Exit fullscreen mode

That gives another agent a clear starting point. It can fetch one document, inspect capabilities, and decide what to call next.

The pattern I think agents need

The important thing is not the exact host or framework. The important thing is that an agent should have a stable public URL with multiple useful representations.

For example:

  • https://example.com/my-agent for the human-facing page
  • https://example.com/my-agent?format=json for public JSON
  • GET /my-agent with Accept: text/markdown for markdown
  • https://example.com/my-agent/agent-card.json for the structured agent card

That gives you one identity and multiple views of the same metadata.

Humans get a normal page. Scripts get JSON. LLM-based systems can ingest markdown. A2A-capable clients get the agent card they expect.

A simple way to do this with agents.ml

agents.ml is a public directory for AI agents built around that exact idea.

You register an agent once and get:

  • a permanent URL at agents.ml/your-agent
  • a live A2A agent card at agents.ml/your-agent/agent-card.json
  • a public JSON representation at agents.ml/your-agent?format=json
  • markdown from the same URL
  • a README badge

You claim with an email, confirm the link, and the page goes live.

Registering an agent

There are two ways to do it:

Step 1: Check the slug

curl https://agents.ml/api/check/my-agent
Enter fullscreen mode Exit fullscreen mode
{"slug":"my-agent","available":true}
Enter fullscreen mode Exit fullscreen mode

Slugs are lowercase alphanumeric with hyphens.

Step 2: Claim the page

curl -X POST https://agents.ml/api/claim \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Agent",
    "slug": "my-agent",
    "tagline": "Does something useful",
    "author": "Your Name",
    "email": "you@example.com",
    "category": "coding",
    "githubRepo": "https://github.com/you/my-agent",
    "website": "https://my-agent.dev"
  }'
Enter fullscreen mode Exit fullscreen mode
{
  "ok": true,
  "slug": "my-agent",
  "message": "Confirmation email sent. Click the link to publish.",
  "pendingTtlSeconds": 14400
}
Enter fullscreen mode Exit fullscreen mode

You get a confirmation email. Click the link and the page is published.

The required fields are:

  • name
  • slug
  • tagline
  • author
  • email

Everything else is optional.

What the public URL gives you

1. Human-readable profile page

Open https://agents.ml/my-agent in a browser and you get a clean public page with:

  • the name and tagline
  • links
  • endpoints
  • skills
  • agent files

That alone is useful because it gives you one canonical place to point people.

2. Public JSON

curl https://agents.ml/my-agent?format=json
Enter fullscreen mode Exit fullscreen mode
{
  "name": "My Agent",
  "slug": "my-agent",
  "tagline": "Does something useful",
  "author": "Your Name",
  "category": "coding",
  "endpoints": [],
  "links": [
    {"label": "GitHub", "url": "https://github.com/you/my-agent"},
    {"label": "Website", "url": "https://my-agent.dev"}
  ],
  "url": "https://agents.ml/my-agent"
}
Enter fullscreen mode Exit fullscreen mode

Useful for scripts, registries, and anything else that wants a straightforward machine-readable profile.

3. A2A agent card

curl https://agents.ml/my-agent/agent-card.json
Enter fullscreen mode Exit fullscreen mode

This returns a generated A2A card based on the profile data. If you later add endpoints, auth metadata, skills, and links, the card updates with them.

4. Markdown via content negotiation

curl -H "Accept: text/markdown" https://agents.ml/my-agent
Enter fullscreen mode Exit fullscreen mode
---
name: My Agent
author: Your Name
category: coding
slug: my-agent
url: https://agents.ml/my-agent
---

# My Agent
by Your Name - coding

> Does something useful

## Links

- [GitHub](https://github.com/you/my-agent)
- [Website](https://my-agent.dev)
Enter fullscreen mode Exit fullscreen mode

That gives LLM-based systems a cleaner representation than raw HTML while keeping the public URL the same.

5. README badge

[![Listed on agents.ml](https://agents.ml/badge/my-agent)](https://agents.ml/my-agent)
Enter fullscreen mode Exit fullscreen mode

Small detail, but useful if you want your repo and public agent page to point to each other.

It also speaks JSON-RPC

Every profile URL is also a live A2A JSON-RPC endpoint.

For example:

curl -X POST https://agents.ml/my-agent \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"agent/getCard"}'
Enter fullscreen mode Exit fullscreen mode

That returns the agent card wrapped in a JSON-RPC response, so the same public identity can also answer protocol-shaped discovery requests directly.

Updating the profile later

After the page is live, you can request an edit link by email and add richer metadata:

  • endpoints
  • auth requirements
  • skills
  • tags
  • links
  • agent files like SKILL.md

That matters because the value of a public agent URL is not just that it exists, but that it stays useful as your agent evolves.

Why I think this matters

A lot of agent projects still behave like demos: they work, but they are not easy to find, query, or understand from the outside.

The minimum viable public identity for an agent is not just a repo link. It is a stable URL with structured metadata.

That does not have to mean a huge registry or a complicated platform. It just means picking a clean pattern and sticking to it:

  • one canonical URL
  • multiple machine-friendly representations
  • a structured agent card
  • enough metadata for another system to decide what to do next

That is the part I think more agent builders should standardize early.

If you want a fast way to do it, you can try it at agents.ml/claim or use the API directly:

curl -X POST https://agents.ml/api/claim \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Your Agent",
    "slug": "your-agent",
    "tagline": "What it does in one line",
    "author": "You",
    "email": "you@example.com",
    "category": "coding"
  }'
Enter fullscreen mode Exit fullscreen mode

Takes about a minute, and then your agent has a public home instead of just a trail of docs.

Top comments (0)