# Agent Discovery

This page maps the machine-readable side of gabrimatic.info. Every important link here is live: JSON, MCP, A2A, OAuth metadata, Markdown alternates, and the policy files agents need before they start guessing.

Quickstart for LLM agents: [`/llms.txt`](https://www.gabrimatic.info/llms.txt) is the shortest text path through the same surface.

**Level 5 / 5, Agent-Native.** Verified by [isitagentready.com](https://isitagentready.com/www.gabrimatic.info). The score is re-scanned after deploys so it reflects the public site, not a local assumption.

## Real-time protocols

- **Model Context Protocol** (Streamable HTTP, JSON-RPC 2.0): `POST https://www.gabrimatic.info/api/mcp`. Stateless MCP server for the portfolio. It implements `initialize`, `ping`, `tools/list`, `tools/call`, `resources/list`, `resources/read`, `prompts/list`, and `prompts/get`. Tools: `get_profile`, `get_journey`, `get_repos`, `get_page_markdown`. Prompts: `profile_overview`, `hiring_snapshot`, `repo_tour`. Requests must send `Accept: application/json, text/event-stream` (the streamable HTTP transport requires both). Discovery card at [`/.well-known/mcp/server-card.json`](https://www.gabrimatic.info/.well-known/mcp/server-card.json). Try it:

  ```
  curl -s -X POST https://www.gabrimatic.info/api/mcp \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json, text/event-stream' \
    -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
  ```
- **Google Agent-to-Agent (A2A)** (JSON-RPC 2.0): `POST https://www.gabrimatic.info/api/a2a`. Stateless A2A endpoint. It implements `message/send`, `tasks/get`, and `tasks/cancel`. Responses complete synchronously and point back to the sources they rely on. Agent Card at [`/.well-known/agent-card.json`](https://www.gabrimatic.info/.well-known/agent-card.json).
- **WebMCP** (in-page tool registration): `navigator.modelContext` on `https://www.gabrimatic.info/`. When the site loads in an MCP-aware browser, `/webmcp.js` registers `navigate`, `get_page_markdown`, and `list_repos` via `navigator.modelContext.registerTool`.

## JSON API

| Resource | URL | Cache |
| --- | --- | --- |
| Profile | [`/api/profile`](https://www.gabrimatic.info/api/profile) | 1 hour |
| Professional journey | [`/api/journey`](https://www.gabrimatic.info/api/journey) | 1 hour |
| GitHub repositories (live) | [`/api/repos`](https://www.gabrimatic.info/api/repos) | edge 5 min, SWR 5 min |
| Merged open-source contributions (live) | [`/api/contributions`](https://www.gabrimatic.info/api/contributions) | edge 15 min, SWR 15 min |

`/api/repos` accepts `?per_page=` (1 to 100, default 100) and `?sort=` (`updated`, `created`, `pushed`, `full_name`; default `updated`). `/api/contributions` groups merged external public PRs into one project entry with a same-origin logo URL and a link to the merged PRs in that repository. All endpoints set `Access-Control-Allow-Origin: *`.

The two live endpoints serve stale copies while revalidating, so the `fetchedAt` in a cached response can legitimately lag: up to ten minutes for repositories and thirty for contributions. Each payload carries its own `cache` object stating exactly that policy - check it before flagging a timestamp as stale.

The JSON API is described by [`/openapi.json`](https://www.gabrimatic.info/openapi.json) (OpenAPI 3.1). `/api/profile` and `/api/journey` return an `ETag`; send `If-None-Match` to skip unchanged bodies. A bare `GET /api` returns a JSON index of every live endpoint, and an unknown `/api/*` path returns a 404 that carries the same map, so a wrong guess always shows the way back.

## OAuth 2.1 authorization server

OAuth is published for agents that expect bearer-token discipline before tool calls. The read surfaces still allow anonymous access, so this is optional for normal retrieval. Dynamic Client Registration supports loopback agent callbacks and same-site callbacks; authorization requires exact `redirect_uri` matching against the registration.

| Endpoint | URL | Spec |
| --- | --- | --- |
| Authorization server metadata | [`/.well-known/oauth-authorization-server`](https://www.gabrimatic.info/.well-known/oauth-authorization-server) | RFC 8414 |
| OpenID Connect discovery | [`/.well-known/openid-configuration`](https://www.gabrimatic.info/.well-known/openid-configuration) | OIDC Core |
| Protected resource metadata | [`/.well-known/oauth-protected-resource`](https://www.gabrimatic.info/.well-known/oauth-protected-resource) | RFC 9728 |
| JWKS (EdDSA public key) | [`/.well-known/jwks.json`](https://www.gabrimatic.info/.well-known/jwks.json) | RFC 7517 |
| Agent authentication guide | [`/auth.md`](https://www.gabrimatic.info/auth.md) | auth.md |
| Web Bot Auth directory | [`/.well-known/http-message-signatures-directory`](https://www.gabrimatic.info/.well-known/http-message-signatures-directory) | Web Bot Auth + RFC 9421 |
| Dynamic client registration | `POST /api/oauth/register` | RFC 7591, loopback or same-site redirect URIs |
| Authorization endpoint | `GET /api/oauth/authorize` | RFC 6749 + PKCE S256, exact registered redirect match |
| Token endpoint | `POST /api/oauth/token` | RFC 6749 + OAuth 2.1 |

Access tokens are `EdDSA`-signed JWTs (`typ: at+jwt`), `iss = https://www.gabrimatic.info`, `aud = https://www.gabrimatic.info/api/mcp`, 1 hour TTL. Supported scopes: `mcp:read`, `mcp:tools`.

## Markdown for Agents

Every page route returns Markdown when the request carries `Accept: text/markdown`. Direct `*.md` URLs are equivalent. This keeps the visual Flutter app and the retrievable text connected to the same source of truth.

```
curl -s -H 'Accept: text/markdown' https://www.gabrimatic.info/journey
```

| Route | Markdown alternate |
| --- | --- |
| `/` | [`/index.md`](https://www.gabrimatic.info/index.md) |
| `/journey` | [`/journey.md`](https://www.gabrimatic.info/journey.md) |
| `/interests` | [`/interests.md`](https://www.gabrimatic.info/interests.md) |
| `/opensource` | [`/opensource.md`](https://www.gabrimatic.info/opensource.md) |
| `/definition` | [`/definition.md`](https://www.gabrimatic.info/definition.md) |
| `/accessibility` | [`/accessibility.md`](https://www.gabrimatic.info/accessibility.md) |
| `/agents` | [`/agents.md`](https://www.gabrimatic.info/agents.md) |

## Discovery

- **llms.txt** (LLM agent quickstart): [`/llms.txt`](https://www.gabrimatic.info/llms.txt). Single Markdown file in the de-facto llms.txt format. Lists the JSON endpoints, Markdown alternates, MCP/A2A discovery cards, and OAuth surfaces. It is the shortest path from a domain name to useful context. The companion [`/llms-full.txt`](https://www.gabrimatic.info/llms-full.txt) is every page's Markdown concatenated in reading order, for agents that want the whole site in one request.
- **Agent Skills index**: [`/.well-known/agent-skills/index.json`](https://www.gabrimatic.info/.well-known/agent-skills/index.json). Lists each SKILL.md with a SHA-256 digest so agents can cache it and verify what they read.
- **API Catalog** (RFC 9727): [`/.well-known/api-catalog`](https://www.gabrimatic.info/.well-known/api-catalog). Linkset advertising the APIs, discovery cards, and Markdown alternates exposed by the site.
- **Sitemap**: [`/sitemap.xml`](https://www.gabrimatic.info/sitemap.xml). Standard XML sitemap, also advertised through RFC 8288 `Link` headers on `/`.
- **RFC 8288 Link headers**: `HEAD /` returns `Link` headers for the sitemap, `/llms.txt`, the Agent Skills index, the A2A card, the MCP server card, OAuth metadata, the API catalog, the HTTP message signatures directory, the agents page, the Markdown alternate, and service links for `/api/mcp` and `/api/a2a`.
- **Content Signals**: [`/robots.txt`](https://www.gabrimatic.info/robots.txt). `Content-Signal: search=yes, ai-input=yes, ai-train=no`: retrieval and user-requested answering are allowed; training use is not. Training-only crawlers are blocked by user-agent.
