-
Notifications
You must be signed in to change notification settings - Fork 142
Add agent-readiness discovery endpoints for AI agents #478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
edmundmiller
wants to merge
4
commits into
master
Choose a base branch
from
cursor/agent-readiness-893e
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
218a076
Add agent-readiness discovery endpoints and infrastructure
cursoragent 4854994
Sync agent skills index from nextflow-io/agent-skills
cursoragent c050bab
Apply prettier formatting for pre-commit CI
cursoragent 8ac2e45
Address ewels review: remove hallucinated/non-existent endpoints
claude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # CloudFront agent-readiness configuration | ||
|
|
||
| Production hosting uses S3 + CloudFront. Apply these after deploying static files. | ||
|
|
||
| ## Link response headers (RFC 8288) | ||
|
|
||
| 1. Create a response headers policy from `response-headers-policy.json`, or attach equivalent `Link` headers to the default cache behavior for `/` and `/index.html`. | ||
| 2. Alternatively, rely on `scripts/set-s3-agent-metadata.sh` (runs during `make publish`) which sets S3 object metadata on `index.html`. | ||
|
|
||
| ## Markdown content negotiation | ||
|
|
||
| 1. Publish the CloudFront Function in `markdown-negotiation.js`. | ||
| 2. Associate it with **viewer-request** on the default behavior. | ||
| 3. Ensure `index.md` is deployed to S3 (copied from `public/index.md` via the Astro build). | ||
|
|
||
| The function rewrites `/` and `/index.html` to `/index.md` when `Accept: text/markdown` is present. | ||
|
|
||
| ## Netlify previews | ||
|
|
||
| PR previews use `public/_headers` for Link headers and `netlify/edge-functions/markdown-negotiate.js` for markdown negotiation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // CloudFront Function: serve markdown when Accept: text/markdown is present. | ||
| // Associate with viewer-request on the nextflow.io CloudFront distribution. | ||
| function handler(event) { | ||
| var request = event.request; | ||
| var headers = request.headers; | ||
| var accept = headers.accept ? headers.accept.value : ""; | ||
| var uri = request.uri; | ||
|
|
||
| if (accept.indexOf("text/markdown") === -1) { | ||
| return request; | ||
| } | ||
|
|
||
| if (uri === "/" || uri === "/index.html") { | ||
| request.uri = "/index.md"; | ||
| } | ||
|
|
||
| return request; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| { | ||
| "Comment": "Link response headers for nextflow.io agent discovery (RFC 8288)", | ||
| "Name": "nextflow-io-agent-discovery-headers", | ||
| "HeadersConfig": { | ||
| "HeaderBehavior": "whitelist", | ||
| "Headers": { | ||
| "Quantity": 1, | ||
| "Items": ["Link"] | ||
| } | ||
| }, | ||
| "CustomHeadersConfig": { | ||
| "Quantity": 1, | ||
| "Items": [ | ||
| { | ||
| "Header": "Link", | ||
| "Value": "</.well-known/api-catalog>; rel=\"api-catalog\", </docs.seqera.io/nextflow/>; rel=\"service-doc\", </openapi.json>; rel=\"service-desc\"", | ||
| "Override": false | ||
| } | ||
| ] | ||
| }, | ||
| "SecurityHeadersConfig": {}, | ||
| "CorsConfig": {} | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # DNS for AI Discovery (DNS-AID) | ||
|
|
||
| Publish the records in `nextflow.io.zone` under the `_agents` namespace for `nextflow.io`. | ||
|
|
||
| ## Requirements | ||
|
|
||
| 1. Add `_index._agents.nextflow.io` and `_a2a._agents.nextflow.io` SVCB records (see zone file). | ||
| 2. Enable DNSSEC on the public zone and publish DS records at your domain registrar. | ||
| 3. Verify with DNS-over-HTTPS: | ||
|
|
||
| ```bash | ||
| curl -s 'https://cloudflare-dns.com/dns-query?name=_index._agents.nextflow.io&type=SVCB' \ | ||
| -H 'accept: application/dns-json' | ||
| ``` | ||
|
|
||
| ## Production note | ||
|
|
||
| DNS-AID records are managed outside this repository (Route 53, Cloudflare DNS, or your registrar). Apply the zone file through your DNS operations workflow after review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| ; DNS for AI Discovery (DNS-AID) records for nextflow.io | ||
| ; Deploy this zone (or merge these records) with your DNS provider. | ||
| ; Sign the zone with DNSSEC and publish DS records at the registrar. | ||
|
|
||
| $ORIGIN nextflow.io. | ||
| $TTL 3600 | ||
|
|
||
| ; Index entrypoint — points agents to the site's API catalog | ||
| _index._agents.nextflow.io. IN SVCB 1 nextflow.io. alpn="h3,h2" port=443 mandatory=alpn,port | ||
|
|
||
| ; Agent-to-agent discovery entrypoint | ||
| _a2a._agents.nextflow.io. IN SVCB 1 nextflow.io. alpn="h3,h2" port=443 mandatory=alpn,port |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| const MARKDOWN_PATHS = { | ||
| "/": "/index.md", | ||
| "/index.html": "/index.md", | ||
| }; | ||
|
|
||
| export default async function handler(request, context) { | ||
| const accept = request.headers.get("Accept") ?? ""; | ||
| if (!accept.includes("text/markdown")) { | ||
| return context.next(); | ||
| } | ||
|
|
||
| const url = new URL(request.url); | ||
| const markdownPath = MARKDOWN_PATHS[url.pathname]; | ||
| if (!markdownPath) { | ||
| return context.next(); | ||
| } | ||
|
|
||
| const markdownUrl = new URL(markdownPath, url.origin); | ||
| const markdownResponse = await context.rewrite(markdownUrl.toString()); | ||
| if (!markdownResponse.ok) { | ||
| return context.next(); | ||
| } | ||
|
|
||
| const body = await markdownResponse.text(); | ||
| const tokenEstimate = Math.ceil(body.length / 4); | ||
|
|
||
| return new Response(body, { | ||
| status: 200, | ||
| headers: { | ||
| "Content-Type": "text/markdown; charset=utf-8", | ||
| "x-markdown-tokens": String(tokenEstimate), | ||
| Vary: "Accept", | ||
| "Cache-Control": "public, max-age=300, must-revalidate", | ||
| }, | ||
| }); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| { | ||
| "$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json", | ||
| "source": "https://github.com/nextflow-io/agent-skills", | ||
| "skills": [ | ||
| { | ||
| "name": "create-workflow", | ||
| "type": "skill-md", | ||
| "description": "INVOKE THIS SKILL IMMEDIATELY when user asks to: write/create/build a Nextflow pipeline or workflow,\ncreate any bioinformatics pipeline (RNA-seq, DNA-seq, variant calling, ChIP-seq, etc.),\nor compose/chain Nextflow modules from the Nextflow Registry. This skill handles all Nextflow workflow creation tasks.", | ||
| "url": "https://nextflow.io/.well-known/agent-skills/create-workflow/SKILL.md", | ||
| "digest": "sha256:cb038d5bc1c2b5a7e76f309cf28b8dfe889e88235d03717a9862f2b5a7434972" | ||
| }, | ||
| { | ||
| "name": "install-nextflow", | ||
| "type": "skill-md", | ||
| "description": "Install or upgrade Nextflow on the user's machine. Use when the user wants to install Nextflow, check their current Nextflow version, upgrade Nextflow, or set up the prerequisites (Java 17+) needed to run Nextflow.", | ||
| "url": "https://nextflow.io/.well-known/agent-skills/install-nextflow/SKILL.md", | ||
| "digest": "sha256:a2b8ba6464bc60dbc51c5aa47d024a9efd4e44af3c17f5e27a4ea099ffa5e4e9" | ||
| }, | ||
| { | ||
| "name": "launch-workflow", | ||
| "type": "skill-md", | ||
| "description": "Launch Nextflow pipeline executions on cloud and HPC clusters via Seqera Platform. Use when the user wants to run/launch/submit a pipeline on a cloud or cluster compute environment, configure a compute environment, push pipeline changes to GitHub before launching, or sign in to Seqera Platform.", | ||
| "url": "https://nextflow.io/.well-known/agent-skills/launch-workflow/SKILL.md", | ||
| "digest": "sha256:40ee0cca1679931ecdc284e86193b34a400d861f25d341cf3a358d4dce310cd3" | ||
| }, | ||
| { | ||
| "name": "run-module", | ||
| "type": "skill-md", | ||
| "description": "Run Nextflow Registry modules natively using `nextflow module` commands. Use when running, listing, or getting info about Nextflow modules.", | ||
| "url": "https://nextflow.io/.well-known/agent-skills/run-module/SKILL.md", | ||
| "digest": "sha256:206c2ad84616fca3290e3ed9d004404ea4b298d78cbb739efafdd65458a1f666" | ||
| } | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "linkset": [ | ||
| { | ||
| "anchor": "https://nextflow.io/", | ||
| "service-desc": [ | ||
| { | ||
| "href": "https://nextflow.io/openapi.json", | ||
|
edmundmiller marked this conversation as resolved.
|
||
| "type": "application/json" | ||
| } | ||
| ], | ||
| "service-doc": [ | ||
| { | ||
| "href": "https://docs.seqera.io/nextflow/", | ||
| "type": "text/html" | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "serverInfo": { | ||
| "name": "nextflow.io", | ||
| "version": "1.0.0" | ||
| }, | ||
| "transport": { | ||
| "type": "webmcp", | ||
| "pageUrl": "https://nextflow.io/" | ||
| }, | ||
| "capabilities": ["tools"] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
| "issuer": "https://nextflow.io", | ||
| "scopes_supported": [], | ||
| "agent_auth": { | ||
| "skill": "https://nextflow.io/auth.md", | ||
| "register_uri": "https://nextflow.io/agent/register", | ||
| "identity_types_supported": ["anonymous"], | ||
| "anonymous": { | ||
| "credential_types_supported": ["access_token"] | ||
| }, | ||
| "claim_uri": "https://nextflow.io/agent/claim" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "resource": "https://nextflow.io", | ||
| "authorization_servers": ["https://nextflow.io"], | ||
| "scopes_supported": [], | ||
| "bearer_methods_supported": ["header"], | ||
| "resource_documentation": "https://docs.seqera.io/nextflow/" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| / | ||
| Link: </.well-known/api-catalog>; rel="api-catalog", </docs.seqera.io/nextflow/>; rel="service-doc", </openapi.json>; rel="service-desc" | ||
|
|
||
| /index.html | ||
| Link: </.well-known/api-catalog>; rel="api-catalog", </docs.seqera.io/nextflow/>; rel="service-doc", </openapi.json>; rel="service-desc" | ||
|
|
||
| /.well-known/api-catalog | ||
| Content-Type: application/linkset+json | ||
| Cache-Control: public, max-age=300, must-revalidate | ||
| Access-Control-Allow-Origin: * | ||
|
|
||
| /.well-known/oauth-authorization-server | ||
| Content-Type: application/json | ||
| Cache-Control: public, max-age=300, must-revalidate | ||
| Access-Control-Allow-Origin: * | ||
|
|
||
| /.well-known/oauth-protected-resource | ||
| Content-Type: application/json | ||
| Cache-Control: public, max-age=300, must-revalidate | ||
| Access-Control-Allow-Origin: * | ||
|
|
||
| /.well-known/mcp/server-card.json | ||
| Content-Type: application/json | ||
| Cache-Control: public, max-age=300, must-revalidate | ||
| Access-Control-Allow-Origin: * | ||
|
|
||
| /.well-known/agent-skills/index.json | ||
| Content-Type: application/json | ||
| Cache-Control: public, max-age=300, must-revalidate | ||
| Access-Control-Allow-Origin: * | ||
|
|
||
| /auth.md | ||
| Content-Type: text/markdown; charset=utf-8 | ||
| Cache-Control: public, max-age=300, must-revalidate | ||
| Access-Control-Allow-Origin: * | ||
|
|
||
| /index.md | ||
| Content-Type: text/markdown; charset=utf-8 | ||
| Cache-Control: public, max-age=300, must-revalidate | ||
| Access-Control-Allow-Origin: * | ||
|
|
||
| /openapi.json | ||
| Content-Type: application/json | ||
| Cache-Control: public, max-age=300, must-revalidate | ||
| Access-Control-Allow-Origin: * |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| # auth.md | ||
|
|
||
| You are an agent. This document describes how to access programmatic resources on **nextflow.io**, the official website for the Nextflow workflow framework. | ||
|
|
||
| Not an agent? See the [Nextflow documentation](https://docs.seqera.io/nextflow/) for human-oriented guides. | ||
|
|
||
| ## Public access (no registration required) | ||
|
|
||
| Most resources on nextflow.io are public and do not require authentication: | ||
|
|
||
| - **Documentation** — [https://docs.seqera.io/nextflow/](https://docs.seqera.io/nextflow/) | ||
| - **RSS feed** — [https://nextflow.io/feed.xml](https://nextflow.io/feed.xml) | ||
| - **API catalog** — [https://nextflow.io/.well-known/api-catalog](https://nextflow.io/.well-known/api-catalog) | ||
| - **OpenAPI spec** — [https://nextflow.io/openapi.json](https://nextflow.io/openapi.json) | ||
| - **Markdown pages** — send `Accept: text/markdown` to any page URL, or read `https://nextflow.io/index.md` | ||
|
|
||
| ## Discovery | ||
|
|
||
| Start with these machine-readable discovery documents: | ||
|
|
||
| 1. `GET /.well-known/oauth-protected-resource` — protected resource metadata (RFC 9728) | ||
| 2. `GET /.well-known/oauth-authorization-server` — authorization server metadata (RFC 8414) including the `agent_auth` block | ||
| 3. `GET /.well-known/api-catalog` — API catalog (RFC 9727) | ||
| 4. `GET /.well-known/mcp/server-card.json` — MCP server card | ||
| 5. `GET /.well-known/agent-skills/index.json` — agent skills index | ||
|
|
||
| ## Agent registration | ||
|
|
||
| nextflow.io does not operate protected APIs that require agent credentials today. The registration endpoints below are reserved for future programmatic access: | ||
|
|
||
| | Endpoint | Method | Purpose | | ||
| | --- | --- | --- | | ||
| | `https://nextflow.io/agent/register` | `POST` | Reserved agent registration endpoint | | ||
| | `https://nextflow.io/agent/claim` | `POST` | Reserved claim ceremony endpoint | | ||
|
|
||
| **Supported identity type:** `anonymous` (read-only public resources only). | ||
|
|
||
| **Credential types:** `access_token` (not currently issued). | ||
|
|
||
| If you receive `404` or `501` from a registration endpoint, treat all public resources as unauthenticated read-only access. | ||
|
|
||
| ## Using credentials | ||
|
|
||
| When credentials become available, send them on API requests: | ||
|
|
||
| ```http | ||
| GET /feed.xml HTTP/1.1 | ||
| Host: nextflow.io | ||
| Authorization: Bearer <access_token> | ||
| ``` | ||
|
|
||
| ## Errors | ||
|
|
||
| | Status | Meaning | Action | | ||
| | --- | --- | --- | | ||
| | 401 | Authentication required but not provided | Re-read `/.well-known/oauth-protected-resource` | | ||
| | 404 | Endpoint not implemented | Use public read-only resources instead | | ||
| | 429 | Rate limited | Exponential backoff, then retry | | ||
|
|
||
| ## Related standards | ||
|
|
||
| - [RFC 8414](https://www.rfc-editor.org/rfc/rfc8414) — OAuth Authorization Server Metadata | ||
| - [RFC 9728](https://www.rfc-editor.org/rfc/rfc9728) — OAuth Protected Resource Metadata | ||
| - [auth.md protocol](https://github.com/workos/auth.md) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Should add mention of this to the agent-skills repo
CLAUDE.mdso that we keep them in sync.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call — that's a change in the
nextflow-io/agent-skillsrepo which is out of scope for this PR. Can you add that CLAUDE.md note there? Something like: "The website syncs skills from this repo at build time into/.well-known/agent-skills/index.json— updatescripts/generate-agent-skills-index.mjsin nextflow-io/website if the skills directory structure changes."Generated by Claude Code