BOZOS MCP
An MCP server that allows AI agents to read public webpages and PDFs, locate literal quotations, and check citation batches against source text. It provides tools for fetching source content, verifying exact matches, and submitting feedback, operating without authentication or installation requirements for HTTP access.
Endpoint and access
No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.
https://bozos.si/api/mcpWhat you can do with it
- Read public webpages and PDFs to extract text and provenance
- Check up to ten citations in one call to verify exact quotations
- Submit feedback reports to the service owner
- Retrieve agent recipes and content indexes
Source and maintenance
Protocol and capabilities
- Server
- bozos 1.10.0
- MCP protocol
- 2025-06-18
- Tools
- 9 advertised
- Resources
- 33 advertised
- Resource templates
- 0 advertised
- Prompts
- Not advertised
{
"tools": {
"listChanged": false
},
"resources": {
"subscribe": false,
"listChanged": false
}
}Server-provided instructions
Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.
Tools
9 advertised
readSource — Read a public HTTPS page or PDF as text with source and citation metadata
Read a public HTTPS page or PDF as text with source and citation metadata. Returns the page text itself, not a model-written summary, so you can quote and cite it. No AI model. Checks robots.txt for BOZOSReader, does not execute scripts, stores no content in the application, and makes outbound public HTTPS requests. Supports HTML, Markdown, plain text, and the text layer of PDFs (pages gives each page's code-point range); no OCR or JavaScript rendering. Limits: 15 seconds, 3 page redirects, 2 MiB source (10 MiB and 300 pages for PDFs), 100000 output code points. GET also accepts url, max_characters and format directly, or a JSON body in ?json= / ?b64=. Declared canonical URL and author/date fields are publisher-supplied and unverified. Cite final_url. Errors always return JSON. gzip, deflate, and Brotli response bodies are decoded before the size limit and source hash are computed. Headless instructions: https://bozos.si/tools/source-reader.md. Source failures include recovery and upstream. For upstream_error, robots_unavailable, and retry_after_redirect, upstream contains stage (robots or source), HTTP status, and parsed Retry-After seconds; other failures set upstream to null. No automatic retries or waiting. Redirects requesting a future delay stop with retry_after_redirect. For retry_later failures with a valid upstream delay, the response exposes a Retry-After header; MCP preserves it in si.bozos/retry-after metadata. Upstream failures continue to use HTTP 424. Set include_quote_source:true with JSON output to also receive the exact matching text from this retrieval, with its own hash and truncation flag. HTML text excludes generated titles and link destinations; Markdown/plain text keep literal syntax (outer whitespace trimmed); PDFs use the text layer. Reuse quote_source.source_text and source_truncated in supplied-text checks. Keep original retrieval metadata yourself. The second representation is opt-in and independently bounded by max_characters. Same as POST https://bozos.si/api/v1/source-reader.
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"maxLength": 4096,
"description": "Public HTTPS URL on the default port, without credentials. Private addresses and IP literals are blocked."
},
"max_characters": {
"type": "integer",
"default": 40000,
"maximum": 100000,
"minimum": 1000,
"description": "Maximum returned Unicode code points per representation. Markdown and optional quote_source text are truncated independently."
},
"include_quote_source": {
"type": "boolean",
"default": false,
"description": "JSON only. Include quote_source: the literal matching text, its SHA-256, length, PDF page ranges, and independent truncation flag, from this same retrieval. Reuse source_text and source_truncated in Quote Checker or Citation Checker without fetching again. Increases response size; omitted by default."
}
},
"additionalProperties": false
}{
"type": "object",
"required": [
"schema_version",
"requested_url",
"final_url",
"title",
"markdown",
"retrieved_at",
"integrity",
"output",
"citation",
"safety"
],
"properties": {
"pages": {
"type": [
"array",
"null"
],
"items": {
"type": "object",
"required": [
"page",
"start",
"end"
],
"properties": {
"end": {
"type": "integer"
},
"page": {
"type": "integer"
},
"start": {
"type": "integer"
}
}
},
"description": "PDF only: one entry per page with its one-based number and code-point range [start, end) in markdown. Null for other sources."
},
"title": {
"type": "string"
},
"output": {
"type": "object",
"properties": {
"truncated": {
"type": "boolean"
},
"characters": {
"type": "integer"
},
"full_characters": {
"type": "integer"
}
}
},
"markdown": {
"type": "string"
},
"final_url": {
"type": "string",
"format": "uri"
},
"integrity": {
"type": "object",
"properties": {
"source_bytes": {
"type": "integer"
},
"source_sha256": {
"type": "string"
},
"markdown_sha256": {
"type": "string"
}
}
},
"extraction": {
"type": "string",
"description": "main-content, readability, body, passthrough, or pdf-text-layer."
},
"quote_source": {
"type": [
"object",
"null"
],
"required": [
"source_text",
"source_truncated",
"representation",
"characters",
"full_characters",
"checked_text_sha256",
"pages"
],
"properties": {
"pages": {
"type": [
"array",
"null"
],
"items": {
"type": "object",
"required": [
"page",
"start",
"end"
],
"properties": {
"end": {
"type": "integer"
},
"page": {
"type": "integer"
},
"start": {
"type": "integer"
}
}
},
"description": "PDF page numbers and code-point ranges [start, end) in source_text; null for other source types. Supplied-text checks do not automatically retain these page labels."
},
"characters": {
"type": "integer",
"maximum": 100000,
"minimum": 1
},
"source_text": {
"type": "string",
"maxLength": 100000,
"minLength": 1,
"description": "Exact text to submit as source_text. Offsets and checked_text_sha256 refer to this string unchanged. HTML excludes generated titles, Markdown syntax, metadata, and link destinations. Plain text and Markdown retain their literal syntax with outer whitespace trimmed, as in URL Quote Checker."
},
"representation": {
"enum": [
"extracted_html_text",
"pdf_text_layer",
"literal_text"
],
"type": "string"
},
"full_characters": {
"type": "integer",
"minimum": 1
},
"source_truncated": {
"type": "boolean",
"description": "Pass this flag to the supplied-text checker. Independent of output.truncated, which describes Markdown."
},
"checked_text_sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$",
"description": "SHA-256 of source_text encoded as UTF-8, after its own truncation. A content identifier, not a truth or origin guarantee."
}
},
"description": "Present only with include_quote_source:true and format=json. Matching text from the same source retrieval, using the same extraction as URL Quote Checker with the same max_characters. Null if Markdown exists but no literal matching text was extracted. Keep final_url, retrieved_at, and integrity with this response; resubmitting text does not verify its provenance.",
"additionalProperties": false
},
"retrieved_at": {
"type": "string",
"format": "date-time"
}
}
}{
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}checkQuote — Check a quotation against its source without AI
Check a quotation against its source without AI. Use this to locate a quotation in supplied text or one public HTTPS source. Returns original passages, ranges, context, hashes, and URL provenance. Supply exactly one of source_text or url. Only whitespace may be normalized; case, punctuation, and word boundaries are preserved. Does not judge truth, paraphrases, or author intent. Source content is not retained. Source URL failures return non-2xx and source_unavailable; absent quotes in partial sources remain inconclusive. Source failures include recovery and upstream. For upstream_error, robots_unavailable, and retry_after_redirect, upstream contains stage (robots or source), HTTP status, and parsed Retry-After seconds; other failures set upstream to null. No automatic retries or waiting. Redirects requesting a future delay stop with retry_after_redirect. For retry_later failures with a valid upstream delay, the response exposes a Retry-After header; MCP preserves it in si.bozos/retry-after metadata. Upstream failures continue to use HTTP 424. To read a page before choosing quotations, call readSource with include_quote_source:true, then supply its quote_source.source_text and source_truncated without refetching. Retain the original reader response for URL provenance; submitted text is still labeled supplied_text. Same as POST https://bozos.si/api/v1/quote-check.
{
"type": "object",
"required": [
"quote"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"maxLength": 4096,
"description": "Public HTTPS URL. Uses the guarded Source Reader, checks robots.txt, and does not render JavaScript. HTML is checked as extracted main text; Markdown and plain text are literal."
},
"quote": {
"type": "string",
"maxLength": 4000,
"minLength": 1,
"description": "Quotation to locate. Case and punctuation are preserved; word-like edges must not cut into source words."
},
"max_matches": {
"type": "integer",
"default": 5,
"maximum": 20,
"minimum": 1,
"description": "Maximum returned passages. Counts cover all matches; matches_truncated reports omitted passages."
},
"source_text": {
"type": "string",
"maxLength": 100000,
"minLength": 1,
"description": "Check the supplied text literally. Supply exactly one of source_text or url."
},
"max_characters": {
"type": "integer",
"default": 100000,
"maximum": 100000,
"minimum": 1000,
"description": "URL mode only: maximum checked Unicode code points. Truncation remains explicit."
},
"source_truncated": {
"type": "boolean",
"default": false,
"description": "For supplied source_text only: declare that the text is a partial source. A missing quotation then returns matched:null and status:source_truncated."
},
"context_characters": {
"type": "integer",
"default": 120,
"maximum": 500,
"minimum": 0,
"description": "Unicode code points of source context to return before and after each match."
},
"normalize_whitespace": {
"type": "boolean",
"default": true,
"description": "Collapse Unicode whitespace runs to one ASCII space and trim the quotation for lookup. Case and punctuation remain unchanged. Exact and normalized occurrences are labelled separately."
}
},
"additionalProperties": false
}{
"type": "object",
"required": [
"schema_version",
"status",
"matched",
"quote",
"match_counts",
"matches",
"matches_truncated",
"matching",
"offsets",
"source",
"warnings",
"interpretation",
"safety"
],
"properties": {
"quote": {
"type": "string"
},
"safety": {
"type": "object"
},
"source": {
"type": "object",
"required": [
"kind",
"representation",
"characters",
"full_characters",
"truncated",
"checked_text_sha256"
],
"properties": {
"kind": {
"enum": [
"url",
"supplied_text"
],
"type": "string"
},
"final_url": {
"type": "string"
},
"truncated": {
"type": "boolean"
},
"characters": {
"type": "integer"
},
"retrieved_at": {
"type": "string"
},
"representation": {
"enum": [
"extracted_html_text",
"literal_text",
"supplied_text",
"pdf_text_layer"
],
"type": "string"
},
"full_characters": {
"type": "integer"
},
"checked_text_sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
}
}
},
"status": {
"enum": [
"exact_match",
"normalized_match",
"not_found",
"source_truncated"
],
"type": "string"
},
"matched": {
"type": [
"boolean",
"null"
]
},
"matches": {
"type": "array",
"items": {
"type": "object",
"required": [
"start",
"end",
"utf16_start",
"utf16_end",
"line_start",
"line_end",
"text",
"before",
"after",
"kind"
],
"properties": {
"end": {
"type": "integer",
"minimum": 0
},
"kind": {
"enum": [
"exact_match",
"normalized_match"
],
"type": "string"
},
"text": {
"type": "string"
},
"after": {
"type": "string"
},
"start": {
"type": "integer",
"minimum": 0
},
"before": {
"type": "string"
},
"line_end": {
"type": "integer",
"minimum": 1
},
"page_end": {
"type": [
"integer",
"null"
],
"description": "PDF sources only: one-based page where the match ends."
},
"utf16_end": {
"type": "integer",
"minimum": 0
},
"line_start": {
"type": "integer",
"minimum": 1
},
"page_start": {
"type": [
"integer",
"null"
],
"description": "PDF sources only: one-based page where the match starts."
},
"utf16_start": {
"type": "integer",
"minimum": 0
}
}
},
"maxItems": 20
},
"offsets": {
"type": "object"
},
"matching": {
"type": "object"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"match_counts": {
"type": "object",
"required": [
"total",
"exact",
"normalized"
],
"properties": {
"exact": {
"type": "integer",
"minimum": 0
},
"total": {
"type": "integer",
"minimum": 0
},
"normalized": {
"type": "integer",
"minimum": 0
}
}
},
"interpretation": {
"type": "string"
},
"schema_version": {
"type": "string",
"const": "1.0"
},
"matches_truncated": {
"type": "boolean"
}
}
}{
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}checkCitations — Check cited links or quotations in supplied source text, without AI
Check cited links or quotations in supplied source text, without AI. Use this to check 1-10 cited public HTTPS links before relying on them, in one call. Send urls to check links, or citations to also check a quotation per link: each quote is matched against the same retrieval with Quote Checker's literal rules (case, punctuation, and word boundaries preserved; whitespace normalized) and returns up to three original passages with offsets and, for PDFs, page numbers. Returns, per link, the final URL, redirects, HTTP status, content type, title, content hash, and a specific failure reason. Readable means the reader got extractable text; it does not show the page is accurate or supports a claim. A quote match means the words appear, not that they support the claim. Failed means this reader could not read it, which can mean a dead link or a site that refuses automated requests, needs JavaScript or a login, or disallows BOZOSReader in robots.txt; its quotation is then unchecked (quote_check null). Uses the guarded Source Reader. Content is not retained. Repeat a URL for multiple quotations: each distinct requested URL is read once per batch (fragments ignored, query strings preserved, redirect aliases kept separate). Sources are retrieved again in later requests. Optional unique citation ids are echoed on success and failure. Results explain offsets, matching rules, checked text representation and lengths, and distinguish matches_truncated from source_truncated. Inspect individual results even when HTTP or MCP reports a successful batch. For text your agent already has, send sources [{id,source_text,source_truncated?}] and citations [{source_id,quote,id?}]. Several citations can share a source_id. These checks make no source-fetch requests and return status supplied_text, null URL/HTTP/retrieval metadata, and a checked_text_sha256; they do not verify origin or authenticity. Mixed URL and supplied-text batches are allowed. summary.supplied counts supplied-text entries separately from readable URLs. Set source_truncated true for excerpts or incomplete input so missing quotations remain inconclusive. All supplied text is checked literally, including markup. Use POST or MCP for text; encoded GET bodies are also supported. Entire requests, including JSON/MCP overhead, are limited to 64 KiB. Failed URL entries carry upstream metadata (including robots-versus-source stage and Retry-After seconds) and a recovery hint. Delays belong to individual entries; a mixed batch never sets a whole-response Retry-After or retries sources automatically. To read a page before choosing quotations, call readSource with include_quote_source:true, then supply its quote_source.source_text and source_truncated without refetching. Retain the original reader response for URL provenance; submitted text is still labeled supplied_text. Same as POST https://bozos.si/api/v1/citation-check.
{
"type": "object",
"properties": {
"urls": {
"type": "array",
"items": {
"type": "string",
"format": "uri",
"maxLength": 4096
},
"maxItems": 10,
"minItems": 1,
"description": "Public HTTPS URLs to check, 1-10, in order, without quotations. Each uses the guarded Source Reader: robots.txt is respected, at most three redirects are followed, and scripts are not run."
},
"sources": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"source_text"
],
"properties": {
"id": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Non-blank source identifier, unique in sources."
},
"source_text": {
"type": "string",
"maxLength": 100000,
"minLength": 1,
"description": "Non-blank text checked literally, preserving original whitespace and offsets. Share it across citations instead of repeating the text. No markup removal, fetching, or code execution."
},
"source_truncated": {
"type": "boolean",
"default": false,
"description": "Set true for an excerpt or incomplete source. A missing quotation is then inconclusive for the complete source."
}
},
"additionalProperties": false
},
"maxItems": 10,
"minItems": 1,
"description": "Optional caller-supplied sources, only with citations. Refer to each by source_id. No URL provenance is accepted or verified. The entire request must fit within 64 KiB."
},
"citations": {
"type": "array",
"items": {
"type": "object",
"oneOf": [
{
"not": {
"required": [
"source_id"
]
},
"required": [
"url"
]
},
{
"not": {
"required": [
"url"
]
},
"required": [
"source_id",
"quote"
]
}
],
"properties": {
"id": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Optional non-blank citation identifier, unique within the batch; echoed unchanged on success and failure."
},
"url": {
"type": "string",
"format": "uri",
"maxLength": 4096
},
"quote": {
"type": "string",
"maxLength": 4000,
"minLength": 1,
"description": "The exact words attributed to this source."
},
"source_id": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "References an id in sources. Use exactly one of url or source_id; source_id requires quote. No URL is fetched for this entry."
}
},
"additionalProperties": false
},
"maxItems": 10,
"minItems": 1,
"description": "1–10 citations in result order. Use url with optional quote, or source_id with required quote. Repeated URLs share a retrieval; source_id references reuse the supplied text. Optional citation ids must be unique."
}
},
"description": "Supply exactly one of urls or citations. Optional sources requires citations; source_id references must exist and supplied-text citations require quote. Source IDs and citation IDs must each be unique in their own list.",
"additionalProperties": false
}{
"type": "object",
"required": [
"schema_version",
"summary",
"results",
"interpretation",
"safety"
],
"properties": {
"safety": {
"type": "object",
"properties": {
"ai_used": {
"type": "boolean",
"const": false
},
"content_retained": {
"type": "boolean",
"const": false
},
"scripts_executed": {
"type": "boolean",
"const": false
}
}
},
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"url",
"status",
"error",
"message",
"http_status",
"requested_url",
"final_url",
"redirected",
"redirects",
"content_type",
"title",
"source_sha256",
"source_bytes",
"retrieved_at"
],
"properties": {
"id": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Optional non-blank citation identifier, unique within the batch; echoed unchanged on success and failure."
},
"url": {
"type": [
"string",
"null"
],
"description": "URL as supplied for URL citations; null for supplied-text citations."
},
"error": {
"type": [
"string",
"null"
],
"description": "Failure code, such as upstream_error, robots_disallowed, no_readable_content, unsupported_content_type, dns_failed, timeout, invalid_url, or private_destination. Null when readable."
},
"quote": {
"type": "string",
"description": "The quotation as supplied, when one was sent."
},
"title": {
"type": [
"string",
"null"
],
"description": "Publisher-supplied title; unverified."
},
"status": {
"enum": [
"readable",
"failed",
"supplied_text"
],
"type": "string",
"description": "readable: URL was fetched and text extracted; supplied_text: caller-provided text was checked without a fetch; failed: URL could not be read."
},
"message": {
"type": [
"string",
"null"
]
},
"recovery": {
"enum": [
"check_request",
"check_url",
"respect_robots",
"retry_later",
"use_supplied_text",
"review_source"
],
"type": "string",
"description": "Suggested next step after a source failure. BOZOS does not retry or wait automatically. retry_later may succeed but is not guaranteed; honor upstream delay and client budgets. use_supplied_text refers only to text the caller is authorized to supply."
},
"upstream": {
"type": [
"object",
"null"
],
"required": [
"stage",
"http_status",
"retry_after_seconds"
],
"properties": {
"stage": {
"enum": [
"robots",
"source"
],
"type": "string"
},
"http_status": {
"type": "integer",
"maximum": 599,
"minimum": 100
},
"retry_after_seconds": {
"type": [
"integer",
"null"
],
"maximum": 9007199254740991,
"minimum": 0,
"description": "Parsed upstream Retry-After: nonnegative seconds or an HTTP-date converted to seconds at receipt, rounded up. Null for missing, malformed, or unrepresentable values; zero is a known elapsed/zero delay."
}
},
"description": "Present for failed source checks; null if no failing HTTP response was recorded. A robots response is not the page status."
},
"final_url": {
"type": [
"string",
"null"
]
},
"redirects": {
"type": "array",
"items": {
"type": "object",
"properties": {
"to": {
"type": "string"
},
"from": {
"type": "string"
},
"status": {
"type": "integer"
}
}
}
},
"source_id": {
"type": "string",
"description": "Supplied source identifier, present only for supplied-text results."
},
"redirected": {
"type": [
"boolean",
"null"
]
},
"http_status": {
"type": [
"integer",
"null"
],
"description": "Final HTTP status when the server answered. Null when no response was received or the check stopped before one."
},
"quote_check": {
"type": [
"object",
"null"
],
"required": [
"status",
"matched",
"match_counts",
"matches",
"checked_text_sha256",
"source_truncated",
"warnings",
"matches_truncated",
"matching",
"offsets",
"source"
],
"properties": {
"source": {
"type": "object",
"required": [
"representation",
"characters",
"full_characters"
],
"properties": {
"characters": {
"type": "integer",
"maximum": 100000,
"minimum": 0,
"description": "Unicode code points checked."
},
"representation": {
"enum": [
"extracted_html_text",
"literal_text",
"pdf_text_layer",
"supplied_text"
],
"type": "string"
},
"full_characters": {
"type": "integer",
"minimum": 0,
"description": "Code points in the full extraction or submitted text before any checker output limit; for incomplete supplied text the original document length is unknown."
}
}
},
"status": {
"enum": [
"exact_match",
"normalized_match",
"not_found",
"source_truncated"
],
"type": "string"
},
"matched": {
"type": [
"boolean",
"null"
],
"description": "Null when the source was truncated and the quote was not found in the checked part."
},
"matches": {
"type": "array",
"items": {
"type": "object",
"required": [
"start",
"end",
"utf16_start",
"utf16_end",
"line_start",
"line_end",
"text",
"before",
"after",
"kind"
],
"properties": {
"end": {
"type": "integer",
"minimum": 0
},
"kind": {
"enum": [
"exact_match",
"normalized_match"
],
"type": "string"
},
"text": {
"type": "string"
},
"after": {
"type": "string"
},
"start": {
"type": "integer",
"minimum": 0
},
"before": {
"type": "string"
},
"line_end": {
"type": "integer",
"minimum": 1
},
"page_end": {
"type": [
"integer",
"null"
],
"description": "PDF sources only: one-based page where the match ends."
},
"utf16_end": {
"type": "integer",
"minimum": 0
},
"line_start": {
"type": "integer",
"minimum": 1
},
"page_start": {
"type": [
"integer",
"null"
],
"description": "PDF sources only: one-based page where the match starts."
},
"utf16_start": {
"type": "integer",
"minimum": 0
}
}
},
"maxItems": 3
},
"offsets": {
"type": "object",
"required": [
"unit",
"start",
"end",
"utf16",
"lines",
"relative_to"
],
"properties": {
"end": {
"type": "string"
},
"unit": {
"type": "string"
},
"lines": {
"type": "string"
},
"pages": {
"type": "string"
},
"start": {
"type": "string"
},
"utf16": {
"type": "string"
},
"relative_to": {
"type": "string"
}
}
},
"matching": {
"type": "object",
"required": [
"normalize_whitespace",
"case_sensitive",
"punctuation_sensitive",
"word_boundaries",
"fuzzy_matching"
],
"properties": {
"case_sensitive": {
"type": "boolean",
"const": true
},
"fuzzy_matching": {
"type": "boolean",
"const": false
},
"word_boundaries": {
"type": "boolean",
"const": true
},
"normalize_whitespace": {
"type": "boolean",
"const": true
},
"punctuation_sensitive": {
"type": "boolean",
"const": true
}
}
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"match_counts": {
"type": "object",
"required": [
"total",
"exact",
"normalized"
],
"properties": {
"exact": {
"type": "integer",
"minimum": 0
},
"total": {
"type": "integer",
"minimum": 0
},
"normalized": {
"type": "integer",
"minimum": 0
}
}
},
"source_truncated": {
"type": "boolean",
"description": "Only part of the original source is represented: a fetched extraction exceeded the limit, or the caller declared supplied text incomplete. Missing quotations are inconclusive."
},
"matches_truncated": {
"type": "boolean",
"description": "More passages matched than the three returned; this does not indicate an incomplete source."
},
"checked_text_sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
}
},
"description": "Present when a quote was sent; null when the link could not be read."
},
"content_type": {
"type": [
"string",
"null"
]
},
"retrieved_at": {
"type": [
"string",
"null"
]
},
"source_bytes": {
"type": [
"integer",
"null"
]
},
"requested_url": {
"type": [
"string",
"null"
]
},
"source_sha256": {
"type": [
"string",
"null"
],
"description": "SHA-256 of the response body after HTTP decompression."
}
}
},
"maxItems": 10,
"minItems": 1
},
"summary": {
"type": "object",
"required": [
"total",
"readable",
"failed"
],
"properties": {
"total": {
"type": "integer"
},
"failed": {
"type": "integer"
},
"quotes": {
"type": "object",
"properties": {
"found": {
"type": "integer"
},
"checked": {
"type": "integer"
},
"not_found": {
"type": "integer"
},
"unchecked": {
"type": "integer"
},
"inconclusive": {
"type": "integer"
}
},
"description": "Present when citations were sent with quotes."
},
"readable": {
"type": "integer"
},
"supplied": {
"type": "integer",
"minimum": 1,
"description": "Present only when supplied-text citations were checked; counts these entries separately from fetched readable URLs."
}
},
"description": "Counts citation entries, including repeats. total = readable + failed + supplied (treat omitted supplied as 0). Supplied text is not counted as a readable URL."
},
"interpretation": {
"type": "string"
},
"schema_version": {
"type": "string",
"const": "1.0"
}
}
}{
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}structuredDiff — Compare two JSON values or two texts without AI
Compare two JSON values or two texts without AI. Use this to see exactly what changed between two supplied versions. format json (default): returns added, removed, and changed paths as JSON Pointers; objects compare by key (order ignored), arrays by index (no move detection), and a different type counts as a change. format text: returns line hunks with one-based line numbers, comparing exactly including whitespace and case. Returns canonical SHA-256 hashes (json) or text hashes. Up to 500 changes are returned; counts cover all. Limits: 64 KiB body, 2000 lines per text, 64 nesting levels. Nothing is fetched or retained. A difference is not a judgment of meaning. Same as POST https://bozos.si/api/v1/diff.
{
"type": "object",
"required": [
"before",
"after"
],
"properties": {
"after": {
"description": "The later version, of the same kind."
},
"before": {
"description": "The earlier version: any JSON value, or a string when format is text."
},
"format": {
"enum": [
"json",
"text"
],
"type": "string",
"default": "json",
"description": "json compares structure; text compares lines."
}
},
"additionalProperties": false
}{
"type": "object",
"required": [
"schema_version",
"format",
"identical",
"summary",
"hashes",
"interpretation",
"safety"
],
"properties": {
"hunks": {
"type": "array",
"items": {
"type": "object",
"required": [
"op",
"before_start",
"after_start",
"before_lines",
"after_lines"
],
"properties": {
"op": {
"enum": [
"added",
"removed",
"changed"
],
"type": "string"
},
"after_lines": {
"type": "array",
"items": {
"type": "string"
}
},
"after_start": {
"type": "integer",
"minimum": 1
},
"before_lines": {
"type": "array",
"items": {
"type": "string"
}
},
"before_start": {
"type": "integer",
"minimum": 1
}
}
},
"description": "format text only."
},
"format": {
"enum": [
"json",
"text"
],
"type": "string"
},
"hashes": {
"type": "object"
},
"safety": {
"type": "object"
},
"changes": {
"type": "array",
"items": {
"type": "object",
"required": [
"op",
"path"
],
"properties": {
"op": {
"enum": [
"added",
"removed",
"changed"
],
"type": "string"
},
"path": {
"type": "string",
"description": "RFC 6901 JSON Pointer; empty string is the document root."
},
"after": {
"description": "New value (added, changed)."
},
"before": {
"description": "Previous value (removed, changed)."
}
}
},
"description": "format json only."
},
"summary": {
"type": "object",
"description": "json: changes, added, removed, changed. text: hunks, lines_removed, lines_added, before_lines, after_lines."
},
"identical": {
"type": "boolean"
},
"interpretation": {
"type": "string"
},
"schema_version": {
"type": "string",
"const": "1.0"
},
"hunks_truncated": {
"type": "boolean"
},
"changes_truncated": {
"type": "boolean"
}
}
}{
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}validateJsonSchema — Validate JSON against a JSON Schema without AI
Validate JSON against a JSON Schema without AI. Use this to check supplied data against a supplied JSON Schema before relying on it. Returns valid, and each failure with the JSON Pointer of the failing value, the schema path, the keyword, and the reason. Nothing is repaired or coerced. Drafts 2020-12 (default), 2019-09, 7, and 4. References resolve only inside the supplied schema; nothing is fetched. The pattern and patternProperties keywords are refused with unsupported_keyword because user-supplied regular expressions can hang a server. Limits: 64 KiB total, 100 errors returned (error_count covers all), 64 nesting levels. Nothing is retained. Valid means this instance satisfies this schema, not that the data is correct. Same as POST https://bozos.si/api/v1/schema-validate.
{
"type": "object",
"required": [
"schema",
"instance"
],
"properties": {
"draft": {
"enum": [
"2020-12",
"2019-09",
"7",
"4"
],
"type": "string",
"default": "2020-12"
},
"schema": {
"type": "object",
"description": "The JSON Schema object."
},
"instance": {
"description": "Any JSON value to validate."
}
},
"additionalProperties": false
}{
"type": "object",
"required": [
"schema_version",
"valid",
"draft",
"error_count",
"errors",
"errors_truncated",
"interpretation",
"validator",
"safety"
],
"properties": {
"draft": {
"type": "string"
},
"valid": {
"type": "boolean"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"required": [
"instance_path",
"schema_path",
"keyword",
"message"
],
"properties": {
"keyword": {
"type": "string"
},
"message": {
"type": "string"
},
"schema_path": {
"type": "string",
"description": "JSON Pointer to the failing keyword in the schema, following $ref."
},
"instance_path": {
"type": "string",
"description": "JSON Pointer to the failing value in the instance; empty string is the whole instance."
}
}
}
},
"safety": {
"type": "object"
},
"validator": {
"type": "string"
},
"error_count": {
"type": "integer"
},
"interpretation": {
"type": "string"
},
"schema_version": {
"type": "string",
"const": "1.0"
},
"errors_truncated": {
"type": "boolean"
}
}
}{
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}inspectAgentAccess — Inspect how a public URL looks to AI agents, without AI
Inspect how a public URL looks to AI agents, without AI. Use this to see what an agent would encounter at a public HTTPS URL. Reports robots.txt status and, for BOZOSReader and five named AI crawlers plus *, whether the path is allowed; the page's redirects, status, content type, selected headers (cache, Link, X-Robots-Tag, Content-Signal), title, description, canonical, meta robots, alternate and service-desc link relations, JSON-LD and anchor counts; whether the URL serves text/markdown when asked; and whether llms.txt, llms-full.txt, the API catalog, openapi.json, the MCP server card, and the sitemap exist (JSON entry points are checked for valid JSON). Respects robots.txt for BOZOSReader: a disallowed or unreadable robots.txt means the page is not fetched. At most 20 requests, 20 seconds; no scripts run; nothing is retained or scored. An allowed value is what robots.txt says, not what an operator does. Same as POST https://bozos.si/api/v1/access-inspect.
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"maxLength": 4096,
"description": "Public HTTPS URL to inspect."
}
},
"additionalProperties": false
}{
"type": "object",
"required": [
"schema_version",
"requested_url",
"inspected_at",
"robots",
"page",
"markdown_negotiation",
"entry_points",
"interpretation",
"safety"
],
"properties": {
"page": {
"type": "object",
"description": "fetched:false with skipped_because or error when the page could not be retrieved."
},
"robots": {
"type": "object",
"description": "robots.txt status and, per crawler token (BOZOSReader, GPTBot, ClaudeBot, Google-Extended, PerplexityBot, CCBot, *), whether the URL's path is allowed and the matching rule."
},
"safety": {
"type": "object"
},
"entry_points": {
"type": "array",
"items": {
"type": "object",
"required": [
"path",
"description",
"url",
"fetched"
],
"properties": {
"url": {
"type": "string"
},
"path": {
"type": "string"
},
"found": {
"type": "boolean"
},
"status": {
"type": "integer"
},
"fetched": {
"type": "boolean"
},
"valid_json": {
"type": "boolean"
},
"description": {
"type": "string"
},
"redirect_to": {
"type": [
"string",
"null"
]
},
"content_type": {
"type": [
"string",
"null"
]
}
}
}
},
"inspected_at": {
"type": "string"
},
"requested_url": {
"type": "string"
},
"interpretation": {
"type": "string"
},
"schema_version": {
"type": "string",
"const": "1.0"
},
"markdown_negotiation": {
"type": [
"object",
"null"
]
}
}
}{
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}search — Search BOZOS
Search every BOZOS reference guide, dataset, note, and tool by keyword. Returns resource ids to pass to `fetch`, with the canonical URL to cite.
{
"type": "object",
"required": [
"query"
],
"properties": {
"query": {
"type": "string",
"maxLength": 200,
"description": "Search words, up to 200 characters"
}
},
"additionalProperties": false
}{
"type": "object",
"required": [
"results"
],
"properties": {
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"title",
"url",
"snippet"
],
"properties": {
"id": {
"type": "string"
},
"url": {
"type": "string"
},
"title": {
"type": "string"
},
"snippet": {
"type": "string"
}
}
}
}
}
}{
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}fetch — Read a BOZOS resource
Return the full text of a BOZOS resource by id (from `search`, or from https://bozos.si/content-index.json): the Markdown version of a guide or note, or a JSON dataset. Pass agent-recipes#check-existing-text for one executable recipe, a record permalink (https://bozos.si/ai-crawlers.json#gptbot) or <dataset id>#<record id> to get one record. Cite the returned url.
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Resource id (ai-crawler-directory-data), or a record: ai-crawler-directory-data#gptbot or https://bozos.si/ai-crawlers.json#gptbot"
}
},
"additionalProperties": false
}{
"type": "object",
"required": [
"id",
"title",
"url",
"text",
"metadata"
],
"properties": {
"id": {
"type": "string"
},
"url": {
"type": "string"
},
"text": {
"type": "string"
},
"title": {
"type": "string"
},
"metadata": {
"type": "object"
}
}
}{
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}submitFeedback — Submit public feedback directly to the private BOZOS inbox
Submit public feedback directly to the private BOZOS inbox. WRITE OPERATION. Saves a private report and may queue a server-side notification only to bozos@bozos.si. No sender email account, login, browser, or API key is required. Use only within your principal's permissions. Sender names are unverified. Corrections require quoted_claim and evidence; source suggestions require evidence. No arbitrary recipients or attachments. Identical normalized reports return the original receipt. A receipt confirms storage, not email delivery or acceptance of a correction. GET and HEAD return 405 and never write. Limits: 16 KiB per request, 5 new reports/minute and 50 per rolling day globally. Instructions: https://bozos.si/tools/contact-submit.md. Same as POST https://bozos.si/api/v1/contact-submit.
{
"type": "object",
"required": [
"kind",
"summary",
"sender"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"maxLength": 500,
"description": "A BOZOS URL; this service does not accept unrelated-site messages."
},
"via": {
"type": "string",
"maxLength": 40
},
"kind": {
"enum": [
"correction",
"question",
"source",
"broken-link",
"data-request",
"feedback"
],
"type": "string"
},
"credit": {
"type": "boolean",
"default": false
},
"sender": {
"type": "object",
"required": [
"agent"
],
"properties": {
"agent": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"operator": {
"type": "string",
"maxLength": 120
},
"reply_to": {
"type": "string",
"maxLength": 200,
"description": "Optional; no email address is required."
},
"human_reviewed": {
"type": "boolean",
"default": false,
"description": "Self-reported, not proof of identity or permission."
}
},
"additionalProperties": false
},
"details": {
"type": "string",
"maxLength": 4000
},
"summary": {
"type": "string",
"maxLength": 140,
"minLength": 1
},
"evidence": {
"type": "array",
"items": {
"type": "string",
"format": "uri",
"maxLength": 500
},
"maxItems": 10,
"description": "At least one required for corrections and source suggestions. URLs are not fetched."
},
"proposed": {
"type": "string",
"maxLength": 4000
},
"resource_id": {
"type": "string",
"maxLength": 120
},
"quoted_claim": {
"type": "string",
"maxLength": 4000,
"description": "Required for corrections."
}
},
"additionalProperties": false
}{
"type": "object",
"required": [
"received",
"report_id",
"received_at",
"duplicate"
],
"properties": {
"message": {
"type": "string"
},
"received": {
"const": true
},
"duplicate": {
"type": "boolean"
},
"report_id": {
"type": "string",
"format": "uuid"
},
"received_at": {
"type": "string",
"format": "date-time"
}
}
}{
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}Prompts
Not advertised
Resources
33 advertised
source-reliability-study — Source reliability and the cost of a citation workflow
Fourteen controlled cases for PDF columns and tables, Unicode quotations, redirects, and partial sources, plus request counts, body sizes and local timings for seven citation workflows. Full evidence, fixtures and limits included.
https://bozos.si/notes/source-reliability.mdcitation-checking-case-study — What a citation check can tell you: eight reproducible cases
Actual HTTP and MCP outputs for exact quotes, whitespace, punctuation, a PDF passage, partial text, a missing URL, a changed number, and an unquoted link. Includes fixtures, commands, full evidence, and explicit limitations.
https://bozos.si/notes/citation-checking-case-study.mdcitation-review-kit — Review a draft’s citations: a complete Python integration kit
Produce Markdown review reports and full JSON evidence over HTTP or MCP. Handle absent quotations, unreadable sources, incomplete text, and request failures distinctly. Includes eight controlled cases, tests, and reusable CC0 code.
https://bozos.si/guides/citation-review.mdcitation-workflow-input — Sample draft citations
Three public citation cases for the runnable Python workflow: a present quotation, an absent quotation, and an unreadable source.
https://bozos.si/examples/citations.jsonquote-checker — Quote Checker: find a quotation in its source
Check supplied text or a public HTTPS page for an exact or whitespace-normalized quotation. Returns original passages, Unicode and UTF-16 offsets, line numbers, context, and source hashes. A match establishes presence, not truth.
https://bozos.si/tools/quote-checker.mdcitation-checker — Citation Checker: do cited links resolve and read?
Check up to 10 citations in one call: fetch public HTTPS links or reuse supplied source text. Return matching passages, offsets, hashes, PDF page numbers for fetched PDFs, and specific retrieval failures. Supplied text is labeled separately; readable or matched is not the same as supportive or true.
https://bozos.si/tools/citation-checker.mdagent-start — Choose a source check for your task
For AI agents: choose a relevant call, retrieve one executable recipe, reuse existing text, and interpret source evidence without an installation or download. Direct HTTP and MCP examples with explicit incomplete and unavailable results.
https://bozos.si/tools/agent-start.mdagent-recipes — Executable agent access recipes
Retrieve one task recipe with ?id= or MCP fetch agent-recipes#id. Includes an absolute HTTP request, MCP call, use conditions, result interpretation, and explicit effects. Write examples never run automatically.
https://bozos.si/agent-recipes.jsoncontact-submit — Send a report directly to BOZOS
Submit public corrections, questions, and broken links to a private BOZOS inbox and receive a receipt. No email account, sign-in, API key, or JavaScript is required. This is a write operation.
https://bozos.si/tools/contact-submit.mdsource-reader — Source Reader: public URL to Markdown
Extract readable Markdown from a public HTTPS page, or the text of a PDF with page ranges, with headings, links, citation metadata, retrieval time, and SHA-256 hashes. No AI model. Respects robots.txt.
https://bozos.si/tools/source-reader.mdai-crawler-directory-guide — AI Crawler Directory
Every documented AI and search crawler (GPTBot, ClaudeBot, Google-Extended, PerplexityBot, and more): what it does, whether it obeys robots.txt, whether it feeds training, and its official IP list. Verified against each operator's documentation.
https://bozos.si/reference/ai-crawlers.mdai-crawler-directory-data — AI crawler directory dataset
32 crawler and control tokens from 14 operators with category, robots.txt behavior, training use, documentation URL, IP list URL, verification date, and any primary-source report that contradicts the documentation. Lists frequently asked tokens with no operator documentation (Bytespider, cohere-ai) separately.
https://bozos.si/ai-crawlers.jsonai-optout-signals-guide — AI Opt-out Signals: Who Honors What
Which AI operators say they honor robots.txt training opt-outs, robots meta tags, noai, Content-Signal, the IETF AI-preferences draft, TDMRep, and RSL, quoted from their own documentation. Where an operator says nothing, the pages and terms searched are listed.
https://bozos.si/reference/ai-optout-signals.mdai-optout-signals-data — AI opt-out signals dataset
7 opt-out and preference signals with their status and specification, and a cell per operator per signal (honors, not-stated, not-applicable, or unknown) with verbatim quotes or the exact terms and pages searched.
https://bozos.si/ai-optout-signals.jsonbot-verification-guide — Bot Verification: How to Tell the Real Crawler
How to confirm that a request really came from GPTBot, Googlebot, ClaudeBot, Applebot, or another AI crawler: published IP ranges, forward-confirmed reverse DNS, and Web Bot Auth signatures, per operator, quoted from their own documentation.
https://bozos.si/reference/bot-verification.mdbot-verification-data — Bot verification dataset
3 verification methods with limits and specifications, and a cell per operator per method (documented, not-stated, or unknown) with verbatim quotes, IP-list URLs, hostname patterns, and Signature-Agent values, plus an observed snapshot of each published IP list.
https://bozos.si/bot-verification.jsonagent-web-signals-guide — Agent Web Signals Field Guide
What robots.txt, sitemaps, HTTP validators, OpenAPI, JSON Schema, JSON Feed, llms.txt, and agent indexes establish, and what they do not authorize.
https://bozos.si/reference/agent-web-signals.mdagent-web-signals-data — Agent Web Signals dataset
Eight discovery signals with classification, what each establishes, what it does not, and a primary reference.
https://bozos.si/agent-web-signals.jsonvulcanbench-cache-audit — What cheaper cache reads change in VulcanBench
A different cache-read rate cuts the estimated Sonnet sweep by 27.44%. The cost-per-success comparison tells a subtler story.
https://bozos.si/notes/vulcanbench-cache-reads.mdcost-per-success-explainer — The denominator does the damage
Dividing the same spending by observed successes instead of attempts narrows a 27.1% price gap to 1.4%.
https://bozos.si/notes/cost-per-success.mdwhat-repricing-proves — A lower price is not a smarter model
One changed price takes a large chunk out of the estimate while the recorded answers stay exactly as they were.
https://bozos.si/notes/what-repricing-proves.mdwindows-365-for-agents — Even the AI gets a company computer
Reading the docs for Windows 365 for Agents: pricing, limits, and what would be worth testing. Based on public documentation, not hands-on use.
https://bozos.si/notes/even-ai-company-computer.mdtelescript-agent-allowance — The agent had an allowance in 1993
General Magic's Telescript paper put explicit limits on what a software agent could do and consume.
https://bozos.si/notes/telescript-agent-allowance.mdthe-at-sign — The @ was doing a job
Ray Tomlinson needed a way to say which computer a person was on. The symbol already said 'at'.
https://bozos.si/notes/the-at-sign.mdmcp-guide — Connect to BOZOS over MCP
A public remote MCP server at https://bozos.si/api/mcp that lists nine source-checking tools, with every utility at https://bozos.si/api/mcp/all. Search and read BOZOS resources, check sources, and submit private feedback. Feedback submission is a write operation; other tools are read-only. No sign-in.
https://bozos.si/tools/mcp.mdconformance-v1 — Conformance V1 manifest
Machine-executable requests with exact dot-path assertions.
https://bozos.si/conformance/v1/manifest.jsonagent-contact-data — Agent contact policy (JSON)
Channels, message kinds, required fields, subject format, and rules for agent messages.
https://bozos.si/contact.jsoncorrections-data — Corrections log (JSON)
Machine-readable corrections with resource IDs and dates.
https://bozos.si/corrections.jsoncontent-index — Content index
Every resource with a stable ID, type, summary, audience, and significant-update date.
https://bozos.si/content-index.jsonagent-index — Agent index
Interaction model, entry points, utilities, contact channels, and citation guidance.
https://bozos.si/agents.jsonupdates-feed — JSON Feed
Substantive changes, newest first.
https://bozos.si/feed.jsonmcp-server-card — MCP server card
Transport, endpoint, capabilities, and tool list for the BOZOS MCP server, readable before connecting.
https://bozos.si/.well-known/mcp/server-card.jsonopenapi — OpenAPI 3.1 description
Contract for every utility operation.
https://bozos.si/openapi.json30-day availability
Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.
- Successful checks
- 1 of 1 (100%)
- Average latency
- 1425 ms
- 95th percentile latency
- 1425 ms
Maintenance history
Public check and source-refresh events. Editorial and ownership records remain private.
- · probe · passed · 1425 ms · metadata changed · 9 tool(s), 33 resource(s), 0 resource template(s)
Connect from your client
Each snippet registers the same endpoint; pick the client you use.
Claude Code
claude mcp add --transport http bozos-mcp https://bozos.si/api/mcpCodex
codex mcp add bozos-mcp --url https://bozos.si/api/mcpCursor
{
"mcpServers": {
"bozos-mcp": {
"url": "https://bozos.si/api/mcp"
}
}
}Cline
{
"mcpServers": {
"bozos-mcp": {
"type": "streamableHttp",
"url": "https://bozos.si/api/mcp",
"disabled": false
}
}
}VS Code
{
"servers": {
"bozos-mcp": {
"type": "http",
"url": "https://bozos.si/api/mcp"
}
}
}Gemini CLI
gemini mcp add --transport http bozos-mcp https://bozos.si/api/mcpClaude Desktop
{
"mcpServers": {
"bozos-mcp": {
"url": "https://bozos.si/api/mcp"
}
}
}Windsurf
{
"mcpServers": {
"bozos-mcp": {
"serverUrl": "https://bozos.si/api/mcp"
}
}
}Let your agent find its tools
Find servers like BOZOS MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.
Other documentation and reference servers
Do you run BOZOS MCP?
Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.