Skip to content

Tool surface

The tools the site’s MCP server publishes, and the arguments each one accepts.

---
title: "Tool surface"
description: "The tools the site’s MCP server publishes, and the arguments each one accepts."
url: "https://lateano.com/demos/tool-surface"
author: "Colin Lateano"
relatedPosts:
  - title: "The tool surface behind this site"
    url: "https://lateano.com/writing/the-tool-surface-behind-this-site"
tags:
  - title: "How I work"
    url: "https://lateano.com/tags/how-i-work"
---

# Tool surface

The tools the site’s MCP server publishes, and the arguments each one accepts.

The tools

These are the tools the site’s MCP server publishes. Their descriptions, annotations and arguments come from the same catalogue an agent discovers through tools/list.

  • List collections

    list_collections
    • Read-only
    • Non-destructive
    • Advertises idempotence
    • Closed world

    List the collections the site publishes — their names, their addresses and how many documents each holds. Three collections hold every document a search can reach, so one call learns what search_content ranges over and a bound is rarely worth naming. The site also publishes pages that belong to no collection, such as its documentation, its about page and its indexes: no search returns them, and list_pages is what enumerates them. Hand a name back to search_content as its collection argument to narrow a search to one. This answers no document text and no tags: search_content finds documents by words, and list_tags gives the vocabulary that cuts across these collections.

    limitintegeroptional
    How many collections to return. Omitted, every collection comes back, and the set is small enough that this is the usual call. A number below 1 is refused rather than read as no bound.
  • List pages

    list_pages
    • Read-only
    • Non-destructive
    • Advertises idempotence
    • Closed world

    List the pages no collection holds — the site's documentation, its about page and its index pages — each with its address, its title and what it is about. These are the pages search_content cannot return: a search ranges over collections, and nothing files these into one, so a question about how this site works is answered here rather than there. Hand an address back to get_page_info for that page's metadata and its links. This answers no document text: hand an address to get_page_markdown to read what is written at it, and search_content finds documents by words.

    limitintegeroptional
    How many pages to return. Omitted, every one comes back, however many there are. A number below 1 is refused rather than read as no bound.
  • Search content

    search_content
    • Read-only
    • Non-destructive
    • Advertises idempotence
    • Closed world

    Search posts, glossary terms and demos at once, best match first. Give it words to match, a collection, or a tag: a call that gives none of the three describes no question and is refused. Three shapes cover most questions — {"match":{"text":"caching","in":"all"}} looks for a word in every field; {"tag":"<a slug list_tags reported>"} returns what carries one tag, and list_tags is where a real slug comes from; {"collection":"glossary","match":{"text":"cache","in":"title"}} narrows to one collection and one field. For one known slug, get_post answers directly; for the metadata of one known route, get_page_info does, and get_page_markdown reads what is written at one. Every answer reports matched beside its rows — how many documents the search found, whether or not they all fit. Where matched is larger than the rows returned, narrow the question with a collection, a tag, or a different field: twenty-five is the most any one search returns, and there is no page after it.

    match{ text: string, in: title | body | description | aliases | tags | all }optional
    What to look for. Omit it and a collection or a tag must narrow the search instead.
    collectionwriting | glossary | demosoptional
    Narrow to one collection.
    tagstringoptional
    Narrow to one tag, by the slug list_tags reports.
    limitintegeroptional
    How many results to return, from 1 to 25. Omitted, the search returns 10. A number outside that range is refused rather than reduced to fit.
  • Get post

    get_post
    • Read-only
    • Non-destructive
    • Advertises idempotence
    • Closed world

    Look up one post by its slug and get its metadata. The text is not in this answer: hand the row’s path to get_page_markdown to read it. Every row also names the address the markdown is published at, for a caller that fetches its own.

    slugstringrequired
    The post's slug — the last segment of its address.
  • List tags

    list_tags
    • Read-only
    • Non-destructive
    • Advertises idempotence
    • Closed world

    List the tags in use across the site — each slug, the title a reader reads, how many documents carry it across the whole site, and that same count broken down by collection. The whole-site number is returned, so there is no need to add the collections up. Tags cut across collections, so this is what to read when the question is about a subject rather than a kind of page. Hand a slug back to search_content as its tag argument. This answers no document text: search_content finds documents by words, and get_page_markdown reads what is written at one address.

    limitintegeroptional
    How many tags to return. Omitted, the whole vocabulary comes back, which is the usual call. A bound takes them in the order this list already answers in rather than by how many documents carry each, so a bounded call is a shorter list rather than the most used ones. A number below 1 is refused rather than read as no bound.
  • Get page info

    get_page_info
    • Read-only
    • Non-destructive
    • Advertises idempotence
    • Closed world

    Get the metadata and graph edges for one route — what cites it, what it cites, and what shares its tags. For searching by words rather than address, search_content is the tool.

    routestringrequired
    An absolute path from the site root, such as /glossary. `/` is the site root.
  • Read a page

    get_page_markdown
    • Read-only
    • Non-destructive
    • Advertises idempotence
    • Closed world

    Read the markdown of one page, by its address. This is how you read a page you found: search_content and list_pages answer addresses, and this answers what is written at one. An index page — a tag page, a collection archive, the site root — is a list of links rather than prose, because that is what the page itself is. A long page is cut, and the answer says where it was cut and names the address that publishes the whole of it. This answers no metadata: get_page_info reads a page’s title, its collection and its links.

    routestringrequired
    An absolute path from the site root, such as /glossary. `/` is the site root.
  • Send feedback

    submit_feedback
    • Write
    • Non-destructive
    • Advertises idempotence
    • Closed world

    Record a message for the author of this site. Useful when a person asks to send feedback, when something on the site reads wrong, or when a task here found that something is not here at all — a page, a definition, a Tool, or an argument. One idempotency key names one submission: send a new key to say something new, and reuse that same key only to retry a call that may not have arrived. The submission is stored for the author to read later; no reply comes back through this tool.

    idempotency_keystring (uuid)required
    A UUID that names this submission. Reuse it unchanged only to retry the same message, kind, severity, and about route; generate a new UUID when any of those changes. Upper and lower case name one key. Two spellings of one route the site publishes are one route, and a route it does not publish is stored as written.
    messagestringrequired
    What to tell the author, in plain words.
    kindmissing | broken | confusing | inaccurate | otherrequired
    What the message is about: something that should be here and is not (missing), something here that does not work (broken), something here that is hard to follow (confusing), something here that is not true (inaccurate), or none of those (other). Where two of them fit, ask what would answer the message: missing is answered by writing something new, and broken by repairing something that is already here.
    severityhigh | medium | lowrequired
    How much it matters.
    aboutstringoptional
    The route the message is about, such as /glossary/mcp. Omitted, it concerns the site as a whole.