agentspeed.

docs.docker.com

scanned 7/25/2026, 7:40:37 PM · cached · refresh in 19h · rubric 2026.07.4
Built with Webflow
robots.txt present: passrobots.txt allows AI agents: passContent-Signal directives: passllms.txt present: passSitemap present: passLink response headers: failCanonical URL: passMCP server card: failOAuth authorization metadata: failOAuth resource metadata: failAPI catalog / OpenAPI: failWeb Bot Auth: failMarkdown negotiation: passText-to-markup ratio: failContent without JavaScript: skipHeading hierarchy: warnCookie wall blocks content: warnPage title: passMeta description: passJSON-LD present: failStructured data validates: skipSchema type coverage: passPaywall / login wall: passAgent Skills manifest: failWebMCP actions: failPrimary action reachable: passReachability: passTime to first byte: passFull render time: skipPage weight: pass72/ 100 · C
Needs work

This is how AI agents (not browsers) experience docs.docker.com. The score weights five categories of machine-readability; the ticks on the arc are the 30 individual checks behind it.

✉ Email me this report + alert me when it changes ↓

Top fixes

Checks tagged “emerging” are 2026 agent-protocol standards most of the web hasn’t adopted yet — adopting early is an edge, not a defect.

failJSON-LD presentStructured data

No JSON-LD blocks found. Add a <script type="application/ld+json"> with a schema.org type for this page.

Fix · Webflow: Add JSON-LD in Page Settings → Custom Code (inside <head>) for the page’s type.

failLink response headersDiscoverability

No HTTP Link: response headers. Emit canonical/alternate/describedby relations so HEAD-only or stream-rendering agents get them without parsing HTML.

Fix: Emit `Link:` headers for canonical, alternate-language, and describedby relations. Agents that fetch HEAD-only or stream-render rely on these.

failText-to-markup ratioReadability

Visible text is 3.8% of HTML weight (6517/172998 bytes). Low. Markup may be crowding out agent-usable text.

Fix: Heavy ad or navigation markup crowds out agent-usable text. Aim for a text-to-DOM ratio above 15%.

warnCookie wall blocks contentReadability

Consent modal detected (cookielaw.org); content still visible. Verify the modal does not block first-paint for screenshot agents.

Fix: Defer cookie consent overlay until after content is visible, or render behind the primary content. Agents without JS or with ad-blocking profiles see a blank page otherwise.

warnHeading hierarchyReadability

Heading issues: 1 skipped level(s).

Fix: Use a single H1 and avoid skipping heading levels (H1 → H3).

failMCP server cardemergingDiscoverability

No valid MCP Server Card at /.well-known/mcp/server-card.json. Publish one so agents can discover your tools without HTML scraping.

Fix: Publish an MCP Server Card describing the tools your site exposes. Agents discover capabilities via `/.well-known/mcp/server-card.json`. See modelcontextprotocol.io for the schema.

Don’t lose this report

Get it in your inbox now — and a heads-up whenever docs.docker.com’s agent-readiness score changes. Free, unsubscribe anytime.

Fix it

Generated, ready-to-ship files for the gaps above — copy them or download and drop them into your repo.

Add JSON-LD structured data
Paste inside <head>. Use Article/Product instead of Organization on those page types.
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Docker Docs",
  "url": "https://docs.docker.com/"
}
</script>
Qualifies for certificationBronze

This score clears the Bronze threshold (70+). Certification turns it into a dated, publicly verifiable attestation — a verification URL, an embeddable badge, and weekly monitoring for a full year. Scores under 70 can’t buy this, which is what makes displaying it mean something.

Get certified — $199/year →

What the agent receives

The agent’s-eye view
Docker Docs Get started Guides Manuals Reference Gordon Gordon, your AI assistant for Docker docs Search { if (theme === 'auto') document.firstElementChild.className = e.matches ? 'dark' : 'light'; }; mql.addEventListener('change', handler); $watch('theme', val => applyTheme(val)); return () => mql.removeEventListener('change', handler); " @click="theme = (theme === 'light' ? 'dark' : theme === 'dark' ? 'auto' : 'light')"> !m.isStreaming) // Watch for store changes to focus input this.$watch('$store.gordon.isOpen', (isOpen) => { if (isOpen) { this.$nextTick(() => { this.$refs.input?.focus() }) } }) // Watch for query from store and populate input this.$watch('$store.gordon.query', (query) => { if (query) { this.currentQuestion = query const shouldAutoSubmit = this.$store.gordon.autoSubmit this.$nextTick(() => { if (shouldAutoSubmit) { this.askQuestion() } else { this.$refs.input?.focus() this.$refs.input?.select() } }) // Clear the store query and autoSubmit flag after using them this.$store.gordon.query = '' this.$store.gordon.autoSubmit = false } }) }, getTurnCount() { return this.messages.filter(m => m.role === 'user').length }, getRemainingTurns() { return this.maxTurnsPerThread - this.getTurnCount() }, isThreadLimitReached() { return this.getTurnCount() >= this.maxTurnsPerThread }, shouldShowCountdown() { const remaining = this.getRemainingTurns() return remaining > 0 && remaining { if (this.$refs.input) { this.$refs.input.style.height = 'auto' } }) this.isLoading = true this.error = null // Add placeholder for assistant response const responseIndex = this.messages.length this.messages.push({ role: 'assistant', content: '', isStreaming: true, questionAnswerId: null, feedback: null, copied: false }) this.$nextTick(() => { this.$refs.messagesContainer?.scrollTo({ top: this.$refs.messagesContainer.scrollHeight, behavior: 'smooth' }) }) try { await this.streamGordonResponse(responseIndex) } catch (err) { // Only set error if messages weren't cleared if (this.messages.length > 0) { if (err.message === 'RATE_LIMIT_EXCEEDED') { this.error = 'You\'ve exceeded your question quota for the day. Please come back tomorrow.' } else { this.error = 'Failed to get response. Please try again.' } } console.error('Gordon API error:', err) // Only try to remove message if it still exists if (this.messages[responseIndex]) { this.messages.splice(responseIndex, 1) } } finally { this.isLoading = false } }, getSessionId() { let sessionId = sessionStorage.getItem('gordon-session-id') if (!sessionId) { sessionId = `docs-${Date.now()}-${Math.random().toString(36).substr(2, 9)}` sessionStorage.setItem('gordon-session-id', sessionId) } return sessionId }, async streamGordonResponse(responseIndex) { // Build API request from messages, excluding the streaming placeholder // The placeholder is at responseIndex, so we take everything before it const conversationMessages = this.messages.slice(0, responseIndex).map((msg, i) => { const message = { role: msg.role, content: msg.content } // Add copilot_references to the last message (most recent user question) if (i === responseIndex - 1) { message.copilot_references = [ { data: { origin: 'docs-website', email: 'docs@docker.com', uuid: this.getSessionId(), action: 'AskGordon', ...(this.includePageContext && { page_url: window.location.href, page_title: &#34;Home&#34; }) } } ] } return message }) const isNewConversation = !this.threadId const payload = { messages: conversationMessages, ...(this.threadId && { thread_uuid: this.threadId }) } const response = await fetch(window.GORDON_BASE_URL + '/public/ask', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }) if (!response.ok) { if (response.status === 429) { throw new Error('RATE_LIMIT_EXCEEDED') } throw new Error(`HTTP ${response.status}: ${response.statusText}`) } const reader = response.body.getReader() const decoder = new TextDecoder() while (true) { const { done, value } = await reader.read() if (done) break const chunk = decoder.decode(value, { stream: true }) const lines = chunk.split('\n') for (const line of lines) { if (!line.trim() || !line.startsWith('data: ')) continue const data = line.slice(6) if (data === '[DONE]') continue try { const parsed = JSON.parse(data) // Capture thread_id for new conversations if (parsed.thread_id) { if (isNewConversation) { this.threadId = parsed.thread_id // $persist auto-saves to sessionStorage } else if (parsed.thread_id !== this.threadId) { console.warn('Backend returned unexpected thread_id:', parsed.thread_id) } continue } // Capture question_answer_id for feedback if (parsed.question_answer_id) { this.messages[responseIndex].questionAnswerId = parsed.question_answer_id continue } if (parsed.choices && parsed.choices[0]?.delta?.content) { const content = parsed.choices[0].delta.content this.messages[responseIndex].content += content this.$nextTick(() => { const container = this.$refs.messagesContainer if (container) { const isNearBottom = container.scrollHeight - container.scrollTop - container.clientHeight { setTimeout(() => { message.copied = false }, 2000) }) } catch (err) { console.error('Failed to copy:', err) } } }" x-cloak @keydown.escape.window=$store.gordon.close()> 0">Start a new chat What can I help you with? I'm Gordon, your AI assistant for Docker and documentation questions. Try asking Get started with Docker Docker Hardened Images MCP Toolkit Create an org 0" class="relative flex flex-col gap-4"> Was this helpful? Helpful Not quite Copy remaining in this thread. You've reached the maximum of questions per thread. For better answer quality, start a new thread. Start a new thread When enabled, Gordon considers the current page you're viewing to provide more relevant answers. Share feedback Answers are generated based on the documentation. How can we help? How do I get started with Docker? Can I run my AI agent in a sandbox? What is a container? What are Docker Hardened Images? Why should I use Docker Compose? Get started Learn Docker basics. Guides Optimize your development workflows with Docker. Manuals Install, set up, configure, and use Docker products. Reference Browse the CLI and API documentation. Featured topics Docker Hardened Images Get started with Docker Sandboxes Docker Desktop overview Install Docker Engine Dockerfile reference Docker Build overview Product offerings Pricing About us llms.txt llms-full.txt Cookies Settings | Terms of Use | Status | Legal Copyright © 2013-2026 Docker Inc. All rights reserved.

Show your score

Embed this badge on your site. It links back to this live scan and updates on every rescan.

AgentSpeed score for docs.docker.com
<a href="https://agentspeed.com/scan/docs.docker.com"><img src="https://agentspeed.com/badge/docs.docker.com" alt="AgentSpeed agent-readiness score" height="56"></a>

Track this score

Get this report by email, then a heads-up when docs.docker.com’s agent-readiness actually changes — a check regressing, or the composite dropping.

Two things never trigger an email: a score change caused by us publishing a new rubric, because that is a different instrument rather than a change to your site, and movement explained only by timing-derived checks, which shift run to run on a site nobody touched.

Want it on your own schedule, with Slack or a webhook instead of email? Score-drift monitoring is on every paid plan.

Full breakdown

15 pass2 warn10 fail3 skip
Discoverability
pass
robots.txt present
A robots.txt is reachable at the site root.
100/100
pass
robots.txt allows AI agents
All 8 answer-time access agents allowed.
100/100
pass
Content-Signal directivesemerging
Content-Signal directives are advertised, declaring fine-grained AI usage preferences.
100/100
pass
llms.txt present
Found /llms.txt (5707 bytes), H1 + at least one link present.
100/100
pass
Sitemap present
sitemap.xml reachable and referenced from robots.txt.
100/100
fail
Link response headers
No HTTP Link: response headers. Emit canonical/alternate/describedby relations so HEAD-only or stream-rendering agents get them without parsing HTML.
0/100
pass
Canonical URL
Canonical points to self: https://docs.docker.com/.
100/100
fail
MCP server cardemerging
No valid MCP Server Card at /.well-known/mcp/server-card.json. Publish one so agents can discover your tools without HTML scraping.
0/100
fail
OAuth authorization metadataemerging
No RFC 8414 metadata at /.well-known/oauth-authorization-server. Agents that act on behalf of users need this to discover your authorization endpoints.
0/100
fail
OAuth resource metadataemerging
No RFC 9728 metadata at /.well-known/oauth-protected-resource. Publish it so agents can discover required scopes without hand-coded credentials.
0/100
fail
API catalog / OpenAPIemerging
No /.well-known/api-catalog (RFC 9727) and no /openapi.json|yaml. Publish one so agents that integrate with APIs can discover your endpoints.
0/100
fail
Web Bot Authemerging
No Web Bot Auth JWKS at /.well-known/http-message-signatures-directory.json. Publish one to allow trusted agents while keeping a default-deny posture for the rest.
0/100
Readability
pass
Markdown negotiationemerging
Requests with Accept: text/markdown return a markdown representation — agents prefer markdown over HTML for summarization and citation.
100/100
fail
Text-to-markup ratio
Visible text is 3.8% of HTML weight (6517/172998 bytes). Low. Markup may be crowding out agent-usable text.
28/100
skip
Content without JavaScript
Browser pass unavailable; cannot measure JS dependency.
warn
Heading hierarchy
Heading issues: 1 skipped level(s).
75/100
warn
Cookie wall blocks content
Consent modal detected (cookielaw.org); content still visible. Verify the modal does not block first-paint for screenshot agents.
70/100
pass
Page title
A concise <title> is present (11 chars).
100/100
pass
Meta description
A well-sized meta description is present (124 chars).
100/100
Structured data
fail
JSON-LD present
No JSON-LD blocks found. Add a <script type="application/ld+json"> with a schema.org type for this page.
0/100
skip
Structured data validates
No JSON-LD blocks present; nothing to validate (covered by structured_data.jsonld_present).
pass
Schema type coverage
Page intent unclear; no specific schema.org type expected.
100/100
Actionability
pass
Paywall / login wall
No paywall or login-wall detected on the landing URL.
100/100
fail
Agent Skills manifestemerging
No Agent Skills manifest at /.well-known/agent-skills.json. Enumerate the tasks agents can perform (search, add-to-cart, contact-support) so they pick the right one without scraping.
0/100
fail
WebMCP actionsemerging
No WebMCP detected. On pages with first-class actions (cart, support, account), embed a WebMCP server so on-page agents invoke tools directly.
0/100
pass
Primary action reachable
Primary offering identified ("Docker documentation and guides") with price/CTA ("Get started with Docker").
100/100
pass
Reachability
HTTP 200.
100/100
Performance
pass
Time to first byte
TTFB 85ms. Healthy.
100/100
skip
Full render time
Full-render time unavailable (browser pass skipped or failed).
pass
Page weight
Initial document is a lean 169 KB.
100/100
Beyond the scan

Running AI agents of your own? AgentSpeed also monitors them in production — every run, its latency, cost, and failures, with alerts when something breaks. Free for 10,000 events a month, no credit card.

Start watching free →See plans