Jamf Docs MCP Server
Summary: The Jamf Docs MCP Server lets AI assistants search, browse, and read official Jamf documentation across 28 products, with tools, resources, and prompts exposed over MCP.
List products & publications (
jamf_docs_list_products): get all 28 Jamf product IDs, publications (release notes, technical papers, courses, guides), topic filters, and docType filters.Search documentation (
jamf_docs_search): keyword search filtered by product, topic, docType, version, and language, with pagination, suggestions on no results, and spelling/quote handling.Fetch articles (
jamf_docs_get_article): retrieve full article content by URL ormapId+contentId, with section extraction,summaryOnlyoutlines, related links, and token-bounded truncation.Browse tables of contents (
jamf_docs_get_toc): navigate a product's or any single publication's TOC, with version and language selection plus paging.Batch fetch (
jamf_docs_batch_get_articles): pull up to 10 article URLs concurrently with per-article success/failure reporting.Glossary lookup (
jamf_docs_glossary_lookup): fuzzy-match Jamf terminology definitions (English-only).MCP resources:
jamf://products,jamf://topics, and template resources for product TOC and version lists.MCP prompts: prebuilt workflows
jamf_troubleshoot,jamf_setup_guide, andjamf_compare_versions.Interactive viewer: hosts supporting MCP Apps render search/TOC/article results as a clickable UI instead of plain markdown.
Multi-language and tunable: every tool (except product listing) supports 11 locales and
maxTokens/outputMode/responseFormatcontrols for token-efficient output.Flexible transport: runs over stdio or HTTP/SSE (with CORS, per-IP rate limiting, proxy trust, caching, retries, and timeouts configurable via env vars).
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Jamf Docs MCP ServerHow do I configure SSO in Jamf Pro?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Jamf Docs MCP Server
An MCP server that gives AI assistants (Claude, Cursor, etc.) direct access to Jamf official documentation. Ask Jamf-related questions and get answers based on the latest docs from learn.jamf.com.
Supported Products (28): Jamf Pro, Jamf School, Jamf Connect, Jamf Protect, Jamf Now, Jamf Safe Internet, Jamf Insights, RapidIdentity, Jamf Trust, Jamf Routines, Self Service+, Jamf App Catalog, Jamf Account, Jamf Security Cloud, Elevate, Composer, Jamf Parent, Jamf Teacher, Jamf Setup and Reset, Jamf Assessment, Title Editor, Jamf Infrastructure Manager, Jamf AD CS Connector, Jamf PKI Proxy, Jamf Migrate, Jamf Remote Assist, Jamf Cloud Distribution Service, Healthcare Listener
Installation
@modelcontextprotocol/server is a peer dependency, and the CLI imports it
at startup (dist/index.js → @modelcontextprotocol/server/stdio). If it is
missing from the install tree the process exits immediately with
ERR_MODULE_NOT_FOUND — the install itself succeeds, so the failure only
shows up when you run the server.
Most install paths bring it in automatically:
Install method | Peer installed |
| Yes |
| Yes |
| Yes |
| No |
Yarn 1 (classic) | No |
If you use one of the last two — or if you are vendoring the package — install the SDK alongside it:
npm install @get-technology-inc/jamf-docs-mcp-server @modelcontextprotocol/server@^2Why it is a peer dependency, not a regular one. This package hands
McpServer instances to its consumers, and those consumers pass them to
createMcpHandler from their own SDK copy. If the two resolve to different
copies of the SDK, an instance built by one module's Protocol is inspected by
another's, and every 2026-07-28 request fails with
Cannot read properties of undefined (reading 'includes') — an HTTP 500 with
no useful diagnostic. Declaring the SDK as a peer states the single-copy
requirement instead of relying on the consumer's tree happening to hoist it;
listing it under dependencies as well would reintroduce exactly the duplicate
it exists to prevent.
Node.js 24 or newer is required. 5.x is the last release line that supports
Node.js 20 and 22. On those versions an unpinned
npx -y @get-technology-inc/jamf-docs-mcp-server resolves to the newest 5.x
on its own, because npm prefers the newest release whose engines field
accepts the running Node: the server keeps working, but stops receiving
updates until Node is upgraded. Use
@get-technology-inc/jamf-docs-mcp-server@5 to make that explicit.
Related MCP server: Apple Dev MCP Server
Quick Start
Claude Desktop
Edit claude_desktop_config.json:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"jamf-docs": {
"command": "npx",
"args": ["-y", "@get-technology-inc/jamf-docs-mcp-server"]
}
}
}Restart Claude Desktop to apply.
Claude Code (CLI)
claude mcp add jamf-docs -- npx -y @get-technology-inc/jamf-docs-mcp-serverCursor
Edit ~/.cursor/mcp.json:
{
"mcpServers": {
"jamf-docs": {
"command": "npx",
"args": ["-y", "@get-technology-inc/jamf-docs-mcp-server"]
}
}
}Verify Installation
Test with MCP Inspector:
npx @modelcontextprotocol/inspector npx -y @get-technology-inc/jamf-docs-mcp-serverUsage Examples
Once configured, just ask your AI assistant:
"How do I configure SSO in Jamf Pro?"
"What are the system requirements for Jamf Protect?"
"Explain the MDM enrollment process"
"What changed in the latest Jamf Connect release notes?"
Available Tools
Tool | Description |
| List all supported products, topics, and document type filters |
| Search documentation by keyword with filtering and pagination |
| Retrieve full content of a specific documentation article |
| Browse the table of contents for a product or any single publication |
| Fetch multiple articles in one call (up to 10 URLs) |
| Look up Jamf terminology and definitions (fuzzy matching) |
jamf_docs_list_products
Returns all available Jamf products and their IDs, available topic filters, and document type filters.
Parameter | Type | Default | Description |
|
|
| Detail level of the response |
|
|
| Output format |
| number (100–50000) |
| Maximum tokens in response. Higher than the other tools' |
This is the one tool without a language parameter. Every tool's input schema
is strict, so an unrecognised key is rejected
(Unrecognized key: "language") rather than silently ignored.
Each publication's locales are the languages Jamf publishes it in. For a
jamf-support-* publication, they are the languages whose support.jamf.com home
page lists it. jamf_docs_get_toc serves a publication in any other language as
its en-US edition, with a localeNote.
If a source cannot be read, the reply lists what it could and says so:
incomplete names each unavailable source, and the markdown reply says the same
at the top. maps-registry is the list of documentation maps, from learn.jamf.com
or a custom MapsProvider, where the publication list and the product versions
both come from, so either can then be missing or a compiled-in default.
jamf-support is support.jamf.com, whose jamf-support-* publications are then
missing, or, when only some of its languages cannot be read, leave those out of
their locales. No incomplete means every source answered.
jamf_docs_search
Searches across all Jamf product documentation.
Parameter | Type | Default | Description |
| string (2–200 chars, or one Chinese, Japanese or Korean character) | required | Search keywords |
| string | — | Filter by product ID (e.g., |
| string | — | Filter by topic category (e.g., |
| string | — | Filter by document type: |
| string (at most 50 chars) | — | Filter by version (e.g., |
| string |
| Documentation language/locale |
| number (1–50) |
| Results per page |
| number (1–100) |
| Page number for pagination |
| number (100–50000) |
| Maximum tokens in response |
|
|
| Detail level; use |
|
|
| Output format |
Pages are cut to maxTokens. A page holds up to limit results, as many as fit, and the next page starts at the first one that did not fit. Every result is on exactly one page, but which page depends on limit and maxTokens, so keep them the same while paging. The markdown footer names them beside the next page when they are not the default, and structuredContent echoes back what to resend: filters, limit and maxTokens. The MCP App's "Show more" resends all of them. A result larger than maxTokens on its own is alone on its page, with its snippet cut to fit and ended with …. Only that page has tokenInfo.truncated: true, and truncatedResult names the result and what it costs whole (estimatedTokens); outputMode: "full" markdown names the maxTokens to repeat the call with. If limit and maxTokens make more pages than page accepts (100), page 100 offers no next page and paginationNote says what reaches the rest.
Jamf's search also ranks courses and learning paths of the Jamf Training Catalog (trainingcatalog.jamf.com) among the documentation. They come back as results like any other, at the rank Jamf's search gives them and under the same product and topic filters, marked external: true (External in markdown). jamf_docs_get_article cannot read them: open the url in a browser. They have no mapId + contentId pair. Jamf classifies them as training content, so their docType is training, and docType: "training" returns them among the training topics, at the rank Jamf's search gives them; any other docType, or a specific version, leaves them out.
"No results found" means the search ran and nothing in the product documentation matched (with responseFormat: "json", the JSON body with total: 0). The reply still lists what matched outside the product documentation (otherSources) and queries to try instead (suggestions). A query with Chinese, Japanese, Korean or Thai words, searched in a language whose documentation is not written in them (such as en-US, the default, which is in English), is suggested none of those words, and the reply says to search with the English terms or which language to search instead (in JSON, localeNote). Fluid Topics finds a page with any one word of a query that has no phrase in double quotes and no word marked + or -. So such a query that found nothing is not suggested fewer of its own words, which find nothing either, and the markdown reply says to check the spelling or try other terms. Curly quotes (“ ” „ ‟), the full-width ", the corner brackets 「」 and 『』 and the guillemets « » are sent to Fluid Topics as straight double quotes, so a phrase quoted with them is searched as a phrase. Two exceptions: 「」, 『』 or « » around a query's only word are sent as typed, since a phrase of one word matches only the form typed (in de-DE, "Konfigurationsprofil" has 1,717 results and Konfigurationsprofil 7,141); and when no page has a phrase quoted with them, the search runs once more with those marks as typed, which matches the words loosely, and says so in queryNote. A straight-quoted phrase that finds nothing is suggested its words without the quotes. Full-width letters and digits (SSO, 15) are sent as ASCII, which in most languages Fluid Topics does not read them as, and are matched as ASCII against the other sources' titles. If the search cannot be completed (learn.jamf.com is unreachable, times out, or answers with an error, or a custom search backend, a SearchProvider, fails), the tool returns an error (isError: true) that says what failed, that this is not a "no results", and whether trying again may help. Pages outside the product documentation that matched follow it, in a second text block.
jamf_docs_get_article
Fetches and converts a documentation article to clean markdown or JSON. Address
the article either by url, or by the mapId + contentId pair that search
results and the table of contents carry — one of the two is required, and a
call with neither is an error.
Passing both, as a search result allows, is fine. On learn.jamf.com the pair
decides which article is fetched, and the result's url is that article's own
address, read from its metadata or else the table of contents; a note says so
when the url you passed does not match it. Only if neither has the address
does the result keep the url you passed. A concepts.jamf.com or
support.jamf.com url is fetched by URL, and a note says the pair was ignored.
A support.jamf.com collection URL, which jamf_docs_get_toc lists each
subcollection by, returns the collection's list of articles. A concepts.jamf.com
URL whose path starts with no locale code, which the site answers with a page
that only redirects to the en page, returns that page, under its own URL. The
site root, https://concepts.jamf.com/, which picks a language in the browser,
returns the en home page, /en/. With language, either returns that
language's edition where the site has one.
Parameter | Type | Default | Description |
| string | — | Full |
| string | — | Fluid Topics map ID (from search results or the TOC). Use with |
| string | — | Fluid Topics content ID (from search results or the TOC). Use with |
| string (at most 200 chars) | — | Extract only a named section (e.g., |
| boolean |
| Return only article outline, and the article's sub-topics when it has any — token-efficient way to preview before fetching full content |
| boolean |
| Include links to related articles |
| string | locale in the URL | Documentation language/locale. Overrides the locale in |
| number (100–50000) |
| Maximum tokens in response |
|
|
| Detail level; |
|
|
| Output format |
maxTokens bounds every reply: the article or one section, a summaryOnly outline, a missed section's reply, and any note about how the call was resolved, all counted in tokenInfo.tokenCount. When content exceeds maxTokens, the tool truncates the response and lists the remaining sections with their token counts, as many as fit. An outline or a list of sections or sub-topics cut to fit says how many it left out, and truncated is true. Use the section parameter on a follow-up call to retrieve a specific part.
jamf_docs_get_toc
Retrieves the navigation structure (table of contents) for a product, or for any
single publication — release notes, technical papers, courses, evaluation and
configuration guides. Exactly one of product and publication is required;
passing both, or neither, is an error. (Before 5.1, product was required and
publication did not exist.)
Parameter | Type | Default | Description |
| string | — | Product ID (see supported products below) |
| string (1–200 chars) | — | Bundle family ID of one publication, e.g. |
| string (at most 50 chars) | latest | Specific version to fetch (e.g., |
| string |
| Documentation language/locale. A product or publication Jamf does not publish in it is served as its en-US edition, with a |
| number (1–100) |
| Page number for paginated TOC |
| number (100–50000) |
| Maximum tokens in response |
|
|
| Use |
|
|
| Output format |
Pages are cut to maxTokens. A page holds up to 10 top-level entries, each with everything under it, as many as fit, and the next page starts at the first one that did not fit. Every top-level entry is on exactly one page, but which page depends on maxTokens (and on the tree, so on version and language), so keep them the same while paging. The markdown footer names maxTokens beside the next page when it is not the default, and structuredContent echoes back what to resend: productId or publicationId, version, language (when one was asked for) and maxTokens. The MCP App's "Show more" resends all of them. A top-level entry larger than maxTokens on its own is alone on its page, cut to the entries under it that fit. Only that page has tokenInfo.truncated: true, and truncatedEntry says how many of its entries are shown and what the whole entry costs (estimatedTokens); outputMode: "full" markdown names the maxTokens to repeat the call with. ("compact" lists top-level entries only, so a cut there hides nothing it would show.) If maxTokens makes more pages than page accepts (100), page 100 offers no next page and paginationNote names a maxTokens that reaches the rest.
jamf_docs_batch_get_articles
Fetches multiple documentation articles in a single call. Each URL is fetched concurrently, and invalid domains are reported as per-article errors without failing the entire batch.
Parameter | Type | Default | Description |
| string[] (1–10) | required | Array of Jamf documentation URLs (same hosts as |
| number (1–5) |
| Maximum parallel requests |
| string | locale in each URL | Documentation language/locale. Overrides the locale in each URL. A learn.jamf.com publication Jamf does not publish in it is served in en-US, and a concepts.jamf.com or support.jamf.com page with no edition in it as its URL names it, both with a note; each result's |
| number (100–50000) |
| Total token budget across all articles |
|
|
| Detail level per article |
|
|
| Output format |
jamf_docs_glossary_lookup
Looks up a term in the Jamf official glossary and returns matching definitions using fuzzy matching. A term of 4 characters or fewer is treated as an abbreviation and must be a whole word of the entry's name, so DEP does not match zero-touch deployment. A 4-character term may be a plural, or miss a letter or swap two (MDMs, LDPA). Glossary content is currently English-only; non-English language values are accepted but results will be in English. A reply with no match says so when the term was asked in another language or is written in a script other than Latin, such as Chinese (in JSON, warning). Full-width letters and digits in a term (MDM) are matched as ASCII.
"No glossary entries found" means the glossary was read and no entry matches (with responseFormat: "json", the JSON body with totalMatches: 0). If entries match but not even the first fits in maxTokens, the reply says how many matched and the maxTokens the first one needs; truncatedContent lists each entry left out and its estimated tokens. If the glossary cannot be read (learn.jamf.com is unreachable, times out, or answers with an error, or a custom maps list, a MapsProvider, fails), the tool returns an error (isError: true) that says what failed and whether trying again may help. If some matching entries cannot be fetched, the reply answers from the others and says so: incomplete names the entries it may be missing. If one of those would have led the answer, because its title names the term more closely than any entry that was fetched, the reply is an error instead, so a lesser entry is never given in its place.
Parameter | Type | Default | Description |
| string (2–100 chars) | required | Glossary term to look up |
| string | — | Accepted, but does not filter: Jamf publishes one platform-wide glossary with no product classification |
| string |
| Documentation language/locale (glossary is English-only) |
| number (100–50000) |
| Maximum tokens in response |
|
|
| Detail level |
|
|
| Output format |
MCP Resources
Static and dynamic reference data accessible without tool calls:
Resource | URI | Description |
Products list |
| All available Jamf products with IDs and version info (fetched dynamically from API) |
Topics list |
| Topic categories for filtering documentation searches |
Product TOC |
| The whole table of contents of a product's current documentation (template resource; see below) |
Product versions |
| Available documentation versions for a specific product (template resource) |
Template resources support tab-completion on productId in compatible clients. A productId of more than 100 characters is refused as invalid params, and one that names no product gets a body that says so and lists the product IDs.
jamf://products/{productId}/toc holds the whole table of contents of the product's current en-US documentation, nested as jamf_docs_get_toc returns it in JSON, up to 20000 tokens counted from entry titles as that tool counts maxTokens. That is a bound on the titles, not on the size of the JSON, which also carries each entry's URL and ids. On 2026-09-28 every product fitted: the largest, Jamf Pro, was about 8,400 such tokens (794 entries, 267 KB of JSON). complete says whether toc is the whole tree. When it is not, shownEntries counts the entries it holds and missing says what is left out and, where jamf_docs_get_toc can return it, which call does. mapId is the map the entries were read from: with an entry's contentId it is the pair jamf_docs_get_article fetches that entry by. A map is one version in one language, so the pair needs no version or language beside it. mapId is absent when no one map is known for the entries; each entry's url still fetches it.
MCP Prompts
Pre-built prompt workflows that guide the AI through multi-step documentation tasks:
jamf_troubleshoot
Guides the AI through a structured troubleshooting workflow: searching for relevant documentation, previewing articles with summaryOnly, then providing a root-cause diagnosis and step-by-step resolution.
Argument | Type | Description |
| string (required, at most 2,000 chars) | Description of the issue to troubleshoot |
| string (optional, at most 100 chars) | Jamf product ID to scope the search |
jamf_setup_guide
Directs the AI to generate a step-by-step setup guide for a Jamf feature, including prerequisites, configuration steps, and verification.
Argument | Type | Description |
| string (required, at most 2,000 chars) | The feature or capability to set up |
| string (optional, at most 100 chars) | Jamf product ID to scope the search |
jamf_compare_versions
Instructs the AI to compare table-of-contents structures and key articles between two product versions, summarizing new features, removed capabilities, and migration considerations.
Argument | Type | Description |
| string (required, at most 100 chars) | Jamf product ID |
| string (required, at most 50 chars) | First version to compare (e.g., |
| string (required, at most 50 chars) | Second version to compare (e.g., |
Supported Products
Product ID | Name | Description |
| Jamf Pro | Apple device management for enterprise |
| Jamf School | Apple device management for education |
| Jamf Connect | Identity and access management |
| Jamf Protect | Endpoint security for Apple |
| Jamf Now | Simple Apple device management for small businesses |
| Jamf Safe Internet | Content filtering and web security for education and business |
| Jamf Insights | Analytics and reporting platform for Apple fleet |
| RapidIdentity | Identity and access management platform |
| Jamf Trust | Zero-trust network access for Apple devices |
| Jamf Routines | Automated workflow orchestration for device management |
| Self Service+ | Next-generation self-service portal for macOS and mobile |
| Jamf App Catalog | Curated application catalog for managed deployments |
| Jamf Account | Identity, licensing, and platform services portal |
| Jamf Security Cloud | Cloud security portal for Jamf Connect and Jamf Protect |
| Elevate | Guided remediation and device health portal |
| Composer | macOS package building and editing |
| Jamf Parent | Parental device controls for school-issued devices |
| Jamf Teacher | Classroom device management for teachers |
| Jamf Setup and Reset | Device personalisation and wipe-and-reprovision apps |
| Jamf Assessment | Locked-down assessment mode for education devices |
| Title Editor | Custom software title patch definitions |
| Jamf Infrastructure Manager | On-premises proxy for LDAP and other internal services |
| Jamf AD CS Connector | Certificate issuance via Active Directory Certificate Services |
| Jamf PKI Proxy | Proxy for certificate authorities behind a firewall |
| Jamf Migrate | Migrating macOS devices between Jamf Pro instances |
| Jamf Remote Assist | Remote screen sharing and support sessions |
| Jamf Cloud Distribution Service | Jamf-hosted package distribution (JCDS) |
| Healthcare Listener | Integration with healthcare information systems |
Key Features
Compact Mode: Use
outputMode: "compact"for token-efficient responses; articles show a ~500-token preview with an available sections listSummary Only: Use
summaryOnly: trueonjamf_docs_get_articleto preview an article outline before fetching full contentSection Extraction: Use
section: "Prerequisites"to retrieve only the part of an article you needBatch Fetching: Use
jamf_docs_batch_get_articlesto fetch up to 10 articles in one call with concurrent requestsGlossary Lookup: Use
jamf_docs_glossary_lookupto look up Jamf terminology with fuzzy matchingMulti-language: Every tool except
jamf_docs_list_productsaccepts alanguageparameter for localized documentation:en-US(default),ja-JP,zh-TW,de-DE,es-ES,fr-FR,nl-NL,th-TH,it-IT,pt-BR,zh-CNDocument Type Filter: Use
docTypeonjamf_docs_searchto narrow results todocumentation,release-notes,training,solution-guide,glossary, orgetting-startedVersion Query: Use the
versionparameter to query documentation for a specific product versionPagination: Search results support
pageandlimit; table of contents supportspage; product lists are not paginatedSearch Suggestions: Receive helpful suggestions when a search returns no results
Token Management: All tools accept a
maxTokensparameter (100–50000; default 5000, or 10000 forjamf_docs_list_products) to control response size
MCP Apps (interactive viewer)
Hosts that negotiate the MCP Apps extension (io.modelcontextprotocol/ui) render
jamf_docs_search, jamf_docs_get_toc and jamf_docs_get_article results as an
interactive viewer instead of plain markdown: search hits are clickable through to
the article, TOC entries open in place, and articles carry section navigation and a
back stack. All three tools reference one self-contained ui:// resource, whose
URI carries a hash of the bundle it names (ui://jamf-docs/app-<hash>.html).
Hosts that do not negotiate the extension ignore the metadata and get exactly the
markdown they always did.
The resource is served with a 24-hour public cache hint, which is safe precisely
because the URI is content-addressed: a given URI names one exact bundle forever,
and a new bundle arrives under a new URI rather than replacing an old one. Hosts
pick up a changed viewer on their next tools/list refresh.
Design
The viewer paints no background and owns no colour. It reads the host's theme,
design tokens and fonts out of hostContext (applyDocumentTheme,
applyHostStyleVariables, applyHostFonts) and builds every rule from those,
so the panel is a piece of the host's surface rather than a web page embedded in
one. app-ui/styles.ts carries a :root fallback for each token, because hosts
may send any subset of the 76 style variables.
Before 5.10 it did the opposite: a hardcoded palette with a
prefers-color-scheme dark block. That media query reports the operating
system, not the host — so a user running Claude in dark mode on a light OS got
a white slab in a dark conversation, and no tuning of the greys could fix it.
Inline and fullscreen
The two display modes render different things, because Claude's design guidelines make them different surfaces. An inline card is a compact summary that fits its own content; fullscreen is where a documentation browser lives.
Inline | Fullscreen | |
Search hits | 3 | the page |
Table-of-contents rows | 8 | the page |
Article prose | 3 blocks, stopping before any table or code block | whole |
Breadcrumbs, Back, parent link | — | ✓ |
Section rail, neighbour list | — | ✓ |
Type-ahead filter, paging | — | ✓ |
Actions | 1 | as needed |
Opening a result from an inline panel sends ui/request-display-mode before
the tools/call, so the article arrives in the mode built for it. A host that
declines, or that offers no fullscreen, still gets the article in place.
Two documented constraints drive this.
Inline apps must not scroll internally. On a touch device the conversation view owns vertical panning, so a vertical gesture starting inside an inline app is handed to the conversation — an internal scroll container does not scroll at all, and everything past the host's cap becomes unreachable rather than below the fold. Bounding what is rendered instead keeps search at ~518px, the table of contents at ~373px and an article at ~554px, all fully visible.
Inline apps must not drill in. "Drill-ins, breadcrumbs, or multiple views" are named patterns to avoid, which is why every piece of navigation chrome above is fullscreen-only.
The article preview is counted in blocks rather than characters. A character budget does not predict height: 900 characters of prose is three short paragraphs, and 900 characters containing a settings table is 700px of panel.
Style variables in app-ui/styles.ts are transcribed from the same guidelines.
Article navigation
jamf_docs_get_article publishes navigation — parent, siblings,
children, and the true totals alongside the (capped) lists.
This matters more than it sounds. Fluid Topics serves one topic per API call
while learn.jamf.com concatenates a topic and its children into a single page,
so every <h2> a reader sees on the site is a separate topic here — verified at
9 of 9 on "Computer Configuration Profiles", whose API payload contains zero
heading tags of any level. Without navigation, a client showing that page has
the introduction and no route to the nine procedures the page consists of on the
website. The viewer renders them as In this section.
It is derived from the map's TOC index, the same index the breadcrumb and the internal links are resolved from. An article loads that index once and shares it between all three.
Developing the viewer
npm run dev:app-ui # http://127.0.0.1:5173 — edit app-ui/*.ts, the frame reloadsapp-ui/dev/harness.ts is a local MCP Apps host built on the SDK's AppBridge,
which accepts Client | null — a host with no server behind it is a supported
mode. It speaks the real protocol to the real App class and answers
tools/call out of app-ui/dev/fixtures.json, real structuredContent
captured from the live tools by npm run fixtures:app-ui.
It exists because the viewer only runs inside a host, so there is nothing to
look at without one, and the alternative loop — build, launch the Inspector,
click through — is tens of seconds per edit. It also does three things no
inspector can: strip hostContext.styles entirely (the check that proves the
:root fallbacks are coherent as a set), resize the container continuously
across the @container breakpoints, and lie about deviceCapabilities.hover.
Before shipping, run the viewer through the real thing as well — it is the only
place the actual ui:// resource, CSP and _meta are exercised:
npm run build && npm run test:inspectorThe MCP Apps viewer is broken in 4.0.0 — upgrade past it. The build step that
inlines the UI bundle into the HTML document used a replacement string, so every
$ pattern in the minified JavaScript was expanded instead of copied. The
document that shipped is not parseable JavaScript, and a host that renders it gets
SyntaxError: missing ) after argument list and a blank panel. Nothing else in
4.0.0 is affected — tools, resources and prompts return the same results either
way, since a host that cannot render the app falls back to the markdown. Fixed in
4.0.1.
4.0.1 alone did not reach every host. Up to and including 4.0.1 the resource
lived at a fixed ui://jamf-docs/app.html with a 24-hour public cache hint, so a
host that had read the broken 4.0.0 bundle kept serving it from cache for up to a
day after the server was upgraded — the corrected bundle was published under the
same URI and never fetched. Upgrading past 4.0.1 fixes the distribution as well as
the bundle: the URI now changes with the content, so a host holding the 4.0.0 copy
simply stops asking for it. No manual cache clearing is needed, and the remaining
delay is the one-hour tools/list hint rather than 24 hours.
HTTP/SSE Transport Mode
In addition to the default stdio transport, the server supports an HTTP transport for use as a remote or shared MCP endpoint.
Starting the HTTP Server
# Using the npm script (defaults: localhost:3000)
npm run start:http
# Using the built binary directly with custom options
node dist/index.js --transport http --port 8080 --host 127.0.0.1CLI Arguments
Argument | Default | Description |
|
| Transport mode: |
|
| Port to listen on, a whole number from 1 to 65535. Any other value stops the server with an error |
|
| Host to bind to. A blank value stops the server with an error |
Each can also be written --port=8080. An argument the server does not know, such as a
misspelt --prot, or an option given no value, is ignored, with a warning on stderr.
Security note: The default host
127.0.0.1restricts access to localhost only. Binding to0.0.0.0exposes the server to the network; only do this in controlled environments.
HTTP Endpoints
Endpoint | Method | Description |
|
| MCP JSON-RPC endpoint (streamable HTTP transport) |
|
| Health check — returns |
Connecting an MCP Client via HTTP
Claude Desktop or other MCP clients that support HTTP transport can connect with:
{
"mcpServers": {
"jamf-docs": {
"url": "http://127.0.0.1:3000/mcp"
}
}
}CORS Configuration
By default the server does not set CORS headers (cross-origin requests are blocked). To allow specific origins, set the CORS_ALLOWED_ORIGINS environment variable:
CORS_ALLOWED_ORIGINS=https://myapp.example.com node dist/index.js --transport httpMultiple origins are separated by commas.
Rate Limiting
The HTTP server applies per-IP token-bucket rate limiting. The default is 60 requests per minute. Override with the RATE_LIMIT_RPM environment variable.
By default the "IP" is the TCP peer address. Behind a reverse proxy every
request arrives from the proxy, so all clients share one RATE_LIMIT_RPM
bucket and one busy client throttles everyone. Set TRUST_PROXY=true (or 1)
to take the client address from X-Forwarded-For instead. Only those two exact
values turn it on — TRUE, yes or anything else leaves it off. When it is on:
The rightmost entry is used: the address appended by the proxy directly in front of the server. Entries to its left are whatever the client sent and can be forged, so they are ignored. That is right for exactly one proxy hop; behind two (a CDN in front of nginx, say) the rightmost entry is the outer proxy, and clients arriving through it share a bucket again.
A request without
X-Forwarded-Forfalls back to the peer address.X-Real-IPandForwardedare not read, so the proxy must sendX-Forwarded-Forfor the setting to have any effect.The address feeds the rate limiter and nothing else.
Leave it off when clients reach the server directly. With it on and no proxy in
front, a client can send any X-Forwarded-For it likes and get a fresh bucket
on every request, which defeats the limit.
Configuration
All settings are optional. Set them as environment variables before launching the server. A setting that is empty, or only whitespace, counts as unset. A numeric setting must be a whole number within its range. Any other value is ignored, with a warning on stderr, and the default is used.
Cache Settings
Variable | Default | Range | Description |
|
| — | Cache directory. Must be a directory used only for this cache; see below |
|
| 1 min–30 days | TTL for search result cache entries |
|
| 1 min–30 days | TTL for articles, the glossary and each map's topic index; see below |
|
| 1 min–30 days | TTL for the product list: the maps list the product catalogue is read from, support.jamf.com's collections and the search indexes of concepts.jamf.com and support.jamf.com; see below |
|
| 1 min–30 days | TTL for tables of contents, from any source, and the map TOC index |
|
| 10–10000 | Maximum number of entries kept in the in-memory cache |
CACHE_DIR must be a directory used only for this cache. The server writes
entries there as <hash>.json, and every start deletes the ones that have
expired or can't be read. Files with other names are left alone, but don't
point it at a project root or a directory other tools use.
A relative path, including the default
.cache, resolves against the server's working directory. It must stay inside that directory. If the host starts the server from/, set an absoluteCACHE_DIR: on macOS/.cachecan't be created, so nothing reaches the disk.A path inside
/etc,/usr,/var,/sys,/proc,/dev,/sbinor/binis rejected, relative or absolute. Symlinks are resolved first, so on macOS/private/etc/…is rejected just like/etc/…. An unset or blankCACHE_DIRisn't checked.Your home directory and the server's temp directory (
TMPDIR) are allowed even when they're under one of those. On macOS so is your per-user temp directory, under/private/var/folders, even when the host does not pass the serverTMPDIR, as an MCP SDK stdio client does not. On ostree systems such as Fedora Silverblue/homeis a link to/var/home.A rejected value falls back to
.cache, with a warning on stderr. That is relative to the working directory too, so if the working directory is inside a system directory, the fallback is as well.
What each TTL covers:
CACHE_TTL_SEARCH: the search resultsjamf_docs_searchreads from learn.jamf.com.CACHE_TTL_ARTICLE: each articlejamf_docs_get_articleandjamf_docs_batch_get_articlesfetch, from any source, with the breadcrumb and internal links built when it was fetched; the glossary's term list and definitions; each learn.jamf.com map's topic index, which a page URL is resolved with; and thejamf://topicslist.CACHE_TTL_PRODUCTS: the list of learn.jamf.com maps, which products, versions and publications are read from on every call, so the products and versionsjamf_docs_list_productsandjamf://productslist are never older than it; support.jamf.com's list of collections; and the title indexesjamf_docs_searchsearches concepts.jamf.com and support.jamf.com with. The maps list's age counts from when it was fetched, also for a server that starts later and reads it from the cache. A title index built while a page its titles are listed on could not be read is kept for a minute.CACHE_TTL_TOC: each table of contentsjamf_docs_get_tocandjamf://products/{productId}/tocserve, whether it is read from a learn.jamf.com map, concepts.jamf.com's sitemap or a support.jamf.com collection page; the titles concepts.jamf.com's section index pages list, which its tables of contents and title indexes use; and the map TOC index an article'snavigationis read from. The glossary's term list is read from a map's table of contents too, and is kept with the glossary, forCACHE_TTL_ARTICLE.
A support.jamf.com collection page is requested once for both of its uses:
whichever of jamf_docs_get_article and a table of contents or title index
reads it first keeps what the other reads from it too, each for its own TTL.
An article's breadcrumb and internal links are built from the map TOC index
when the article is fetched, and kept with it for CACHE_TTL_ARTICLE. Its
navigation is read from the index on every call, so with CACHE_TTL_TOC
shorter than CACHE_TTL_ARTICLE, a reply can carry a breadcrumb older than
its navigation.
6.0.12 and earlier did not read CACHE_TTL_TOC. In 6.0.12 the Fluid Topics
tables of contents and the map TOC index were kept for CACHE_TTL_ARTICLE,
and the concepts.jamf.com and support.jamf.com ones for CACHE_TTL_PRODUCTS,
7 days by default where they now get 24 hours. The products and versions
jamf_docs_list_products lists were cached apart from the maps list, for
CACHE_TTL_ARTICLE, so a version Jamf published could show under
publications up to 24 hours before it showed under products. A server
that read the maps list from the cache kept it for CACHE_TTL_PRODUCTS from
that read, not from when the list was fetched, so it could serve a list up to
twice that old.
Request Settings
Applied to every outbound request to a documentation host.
Variable | Default | Range | Description |
|
| 1000–60000 ms | Per-attempt HTTP timeout |
|
| 0–10 | Retry attempts after the first. Only 429, 5xx, network errors and timeouts are retried, with exponential backoff and |
|
| 100–30000 ms | Base for the backoff between retries. No effect while |
|
| 0–10000 ms | Minimum gap between outbound requests, retries included. |
|
| Latin-1 | Sent on every request so this client is identifiable to Jamf. An HTTP header can carry no character above U+00FF and no control character but a tab. Line breaks are removed; a value with any other such character is ignored, with a warning on stderr |
HTTP Transport Settings
Variable | Default | Range | Description |
|
| 1–10000 | Inbound requests per minute per IP (HTTP transport only) |
| `` (empty) | — | Comma-separated list of allowed CORS origins (HTTP transport only) |
| off |
| Take the client IP for the per-IP rate limit from the rightmost |
Development
git clone https://github.com/GET-Technology-Inc/jamf-docs-mcp-server.git
cd jamf-docs-mcp-server
npm install
npm run dev # stdio mode with file watching
npm run start:http # HTTP transport modeAvailable Scripts
Script | Description |
| Compile TypeScript to |
| Development mode with auto-reload (stdio) |
| Live preview of the MCP Apps viewer at http://127.0.0.1:5173 |
| Re-capture the viewer's fixtures from the live tools |
| Start HTTP/SSE transport mode |
| Pre-PR run: unit, integration and e2e |
| Unit tests only — hermetic, no network |
| Integration tests only (live Jamf APIs) |
| Upstream contract suites. Run out of band by |
| End-to-end tests only (live Jamf APIs) |
| Everything, contract suites included |
| Coverage over the unit tier, as CI reports it |
| Launch MCP Inspector against local build |
| Lint source files |
| TypeScript type check without emitting |
License
MIT - Copyright (c) 2025 GET Technology Inc.
Disclaimer
This is an unofficial tool and is not affiliated with Jamf.
Links
Available Tools
6 toolsjamf_docs_batch_get_articlesBatch Get Jamf Documentation ArticlesARead-onlyIdempotent
Retrieve multiple Jamf documentation articles in a single request.
Fetches up to 10 articles in parallel with concurrency control. Useful for comparing articles, gathering information from multiple pages, or bulk research.
Args:
urls (string[], required): Array of 1-10 https:// article URLs on learn.jamf.com, docs.jamf.com, concepts.jamf.com, support.jamf.com, each at most 2048 characters. Any other URL fails as its own per-article error, and a longer one fails the call's input validation
concurrency (number, optional): Max parallel requests 1-5 (default: 3)
language (string, optional): Documentation language/locale. Overrides the locale in each URL, which is used when this is omitted. A learn.jamf.com publication Jamf does not publish in it is served in en-US, and a concepts.jamf.com or support.jamf.com page with no edition in it as its URL names it, both with a note; each result's contentLocale says which language was served
maxTokens (number, optional): Total token budget across all articles 100-50000 (default: 5000). Distributed evenly.
outputMode ('full' | 'compact'): Output detail level (default: 'full'). Use 'compact' for brief output.
responseFormat ('markdown' | 'json'): Output format (default: 'markdown')
Returns: An array of article results. Each article independently succeeds or fails. For JSON format, returns a BatchResponse object with results, summary, and tokenInfo. A result carries contentLocale, the language its content is in, where the article says.
Examples:
Compare two products: urls=["https://learn.jamf.com/.../page/A.html", "https://learn.jamf.com/.../page/B.html"]
Bulk fetch with compact output: urls=[...], outputMode="compact", maxTokens=10000
Note: Token budget is split evenly across articles. Use higher maxTokens for more articles.
A note on an article (such as one about language) counts toward its share.
Partial failures are reported per-article without failing the entire batch.
| Name | Required | Description | Default |
|---|---|---|---|
| urls | Yes | Array of Jamf documentation article URLs (1-10), each at most 2048 characters | |
| language | No | Documentation language/locale. Overrides the locale in the article URL, which is used when this is omitted. A learn.jamf.com publication Jamf does not publish in it is served in en-US, and a concepts.jamf.com or support.jamf.com page with no edition in it as the URL names it, both with a note; contentLocale says which language was served. Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN | |
| maxTokens | No | Total token budget across all articles (100-50000, default: 5000) | |
| outputMode | No | Output detail level: "full" for detailed output or "compact" for brief output | full |
| concurrency | No | Maximum parallel requests (1-5, default: 3) | |
| responseFormat | No | Output format: "markdown" for human-readable or "json" for machine-readable | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | |
| summary | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, idempotent, non-destructive, openWorld), and the description adds substantial behavior beyond that: per-article independent success/failure, partial failures not aborting the batch, concurrency control limits, token budget split evenly across articles, and locale fallback to en-US with a note. This is rich operational context an agent could not get from the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the one-line purpose, then organized into Args/Returns/Examples/Notes, with zero filler sentences and the key constraint (token budget split) called out last. Slightly verbose because the Args block restates ranges already present in the schema, but the added notes justify the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter batch tool with an output schema, the description covers everything an agent needs to call it correctly: URL domain restrictions, concurrency, budget behavior, locale fallback, partial-failure reporting, and response format. Return values are described but the output schema already handles them, so nothing is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline would be 3, but the description goes further: it explains that maxTokens is distributed evenly across articles (not per-article), that language overrides the URL locale, and that out-of-domain URLs fail as their own per-article error while over-length URLs fail input validation. Those are semantics the schema does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Retrieve multiple Jamf documentation articles in a single request') and the batch scope, which cleanly separates it from the sibling jamf_docs_get_article for single articles. An agent can route on the plural/batch distinction without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear intended contexts ('comparing articles, gathering information from multiple pages, or bulk research'), which is genuine when-to-use guidance. It does not explicitly name jamf_docs_get_article as the single-article alternative, so selection between the two is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jamf_docs_get_articleGet Jamf Documentation ArticleARead-onlyIdempotent
Retrieve the full content of a specific Jamf documentation article.
This tool fetches and parses a Jamf documentation article, converting it to a clean, readable format. Works with any article from learn.jamf.com, docs.jamf.com, concepts.jamf.com, support.jamf.com.
Address the article either by url, or by the mapId + contentId pair
that search results and TOC entries carry. One of the two is required. Passing
both, as a search result allows, is fine: on learn.jamf.com the pair decides
which article is fetched, and the result's url is that article's own address
(a note says so if the url you passed does not match it). A
concepts.jamf.com or support.jamf.com url is fetched by url, and a note says
the pair was ignored. A support.jamf.com collection url, which a TOC lists
each subcollection by, returns the collection's list of articles.
Args:
url (string, optional): Full https:// URL of the article, on learn.jamf.com, docs.jamf.com, concepts.jamf.com, support.jamf.com, at most 2048 characters. Required unless mapId and contentId are given
mapId (string, optional): Fluid Topics map ID, from a search result or a TOC. Use with contentId, instead of url or alongside it
contentId (string, optional): Fluid Topics content ID, from a search result or a TOC entry. Use with mapId, instead of url or alongside it
language (string, optional): Documentation language/locale. Overrides the locale in url, which is used when this is omitted. A learn.jamf.com publication Jamf does not publish in it is served in en-US, and a concepts.jamf.com or support.jamf.com page with no edition in it as the url names it, both with a note; contentLocale says which language was served. No effect on a mapId + contentId pair (a map is in one language)
section (string, optional): Extract only a specific section by title or ID (e.g., "Prerequisites", "Configuration")
summaryOnly (boolean, optional): Return only article summary and outline instead of full content (default: false). Token-efficient way to preview an article and its sub-topics
includeRelated (boolean, optional): Include links to related articles (default: false)
maxTokens (number, optional): Maximum tokens in response 100-50000 (default: 5000)
outputMode ('full' | 'compact'): Output detail level (default: 'full'). Use 'compact' for brief output
responseFormat ('markdown' | 'json'): Output format (default: 'markdown')
Returns: For JSON format: { "title": string, "content": string, "url": string, "product": string, "version": string, "contentLocale": string, // the language content is in, where the article says "breadcrumb": string[], "relatedArticles": [...], "tokenInfo": { "tokenCount": number, "truncated": boolean, "maxTokens": number }, "sections": [ { "id": string, "title": string, "level": number, "tokenCount": number } ] }
For Markdown format: The article content with token info and available sections.
Examples:
Get full article: url="https://learn.jamf.com/en-US/bundle/jamf-pro-documentation/page/Computer_Configuration_Profiles.html"
Fetch a search result directly: mapId="...", contentId="..." (both from the result)
Get specific section: url="...", section="Prerequisites"
Limit response size: url="...", maxTokens=2000
Errors:
"Either url or both mapId and contentId must be provided." if neither url nor the full pair is given
"URL must be from learn.jamf.com, docs.jamf.com, concepts.jamf.com, support.jamf.com" (an input validation error) if url is not https:// on one of those hosts
"URL must not exceed 2048 characters" (an input validation error) if url is longer
"Topic not found", "Cannot resolve bundleId", "Cannot resolve product" or "HTTP 404" if no article is found at that address, with advice on finding it
Note: maxTokens bounds every reply: the article or one section, a
summaryOnly outline, a missed section's reply, and any note about how the
call was resolved, all counted in tokenInfo.tokenCount. Large articles are
intelligently truncated with remaining sections listed, as many as fit; a list
cut to fit says how many it left out, and truncated is true.
Use the section parameter, at most 200 characters, to retrieve
specific sections for long articles.
A section that matches no heading is not an error: the reply says
'Section "" not found' and lists the article's sections, or says it has
none. Most learn.jamf.com topics have no headings; what the website shows as
their sections are sub-topics, which the reply lists with their urls, a matching
one first.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Full https:// URL of the Jamf documentation article, on learn.jamf.com, docs.jamf.com, concepts.jamf.com, support.jamf.com, at most 2048 characters. Alternative: use mapId + contentId for direct fetch. One of the two is required. | |
| mapId | No | Fluid Topics map ID (from search results or TOC). Use with contentId for direct fetch. | |
| section | No | Extract only a specific section by title or ID (e.g., "Prerequisites", "Configuration"), at most 200 characters | |
| language | No | Documentation language/locale. Overrides the locale in the article URL, which is used when this is omitted. A learn.jamf.com publication Jamf does not publish in it is served in en-US, and a concepts.jamf.com or support.jamf.com page with no edition in it as the URL names it, both with a note; contentLocale says which language was served. No effect on a mapId + contentId pair, whose map is already in one language. Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN | |
| contentId | No | Fluid Topics content ID (from search results or TOC). Use with mapId for direct fetch. | |
| maxTokens | No | Maximum tokens in response (100-50000, default: 5000) | |
| outputMode | No | Output detail level: "full" for detailed output or "compact" for brief output | full |
| summaryOnly | No | Return only article summary and outline instead of full content (token-efficient) | |
| includeRelated | No | Include related article links in the response | |
| responseFormat | No | Output format: "markdown" for human-readable or "json" for machine-readable | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | Yes | |
| mapId | No | |
| title | Yes | |
| content | Yes | |
| product | No | |
| version | No | |
| sections | Yes | |
| contentId | No | |
| truncated | Yes | |
| breadcrumb | No | |
| navigation | No | |
| tokenCount | No | |
| lastUpdated | No | |
| contentLocale | No | |
| versionStatus | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already covering readOnly/idempotent/openWorld/non-destructive, the description goes well beyond them: it discloses precedence between url and the id pair on each host, language fallback to en-US with a note and contentLocale, and detailed truncation behavior bounded by maxTokens. It also documents non-error behaviors such as a section that matches no heading, which an agent could not infer otherwise.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with purpose and organized into Args/Returns/Errors/Note sections, so it is easy to scan. It is nonetheless long, and the Args block and Returns block largely restate what the schema and output schema already carry, which is redundancy rather than information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with 3 enums and an output schema, the definition covers resolution logic, fallbacks, truncation, error strings, and edge cases (empty section lists, ignored id pairs). An agent has everything needed to call it correctly and interpret the response without opening other tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds genuine meaning beyond the schema: the resolution precedence of mapId+contentId versus url per host, language override semantics (including why it has no effect on an id pair), and the section-not-found behavior. This is more than the schema conveys, though some param text is duplicated rather than additive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Retrieve the full content of a specific Jamf documentation article') and clarifies the supported hosts, so the agent knows exactly what this does. It implicitly distinguishes itself from siblings by noting that search results and TOC entries supply the mapId/contentId pair, but it never names a sibling tool or states an explicit boundary against batch_get_articles.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear routing context: address by `url` or by the `mapId`+`contentId` pair that search results and TOC entries carry, and notes `summaryOnly` as a token-efficient preview path. However, it does not state when to prefer this over `jamf_docs_batch_get_articles` for multiple articles, and offers no explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jamf_docs_get_tocGet Documentation Table of ContentsARead-onlyIdempotent
Get the table of contents for Jamf documentation.
Browse the navigation structure of either a Jamf product or any single Jamf
publication - release notes, technical papers, courses, evaluation guides and
configuration guides all live on the publication axis rather than the product
one. Exactly one of product and publication is required.
Args:
product (string): Product ID - one of: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog, jamf-account, jamf-security-cloud, elevate, composer, jamf-parent, jamf-teacher, jamf-setup-reset, jamf-assessment, title-editor, jamf-infrastructure-manager, jamf-adcs-connector, jamf-pki-proxy, jamf-migrate, jamf-remote-assist, jamf-cloud-distribution-service, healthcare-listener
publication (string): Bundle family id of any single publication, e.g. "technical-paper-laps" or "jamf-pro-release-notes". Call jamf_docs_list_products for the available ids
version (string, optional): Specific version (e.g., "11.13.0") or "current" (defaults to latest), at most 50 characters
language (string, optional): Documentation language/locale (default: en-US). A product or publication Jamf does not publish in it is served as its en-US edition, and localeNote says so
page (number, optional): Page number for pagination 1-100 (default: 1)
maxTokens (number, optional): Maximum tokens in response 100-50000 (default: 5000)
outputMode ('full' | 'compact'): Output detail level (default: 'full'). Use 'compact' for flat list without nested children
responseFormat ('markdown' | 'json'): Output format (default: 'markdown')
Returns: For JSON format: { "product": string, "version": string, "mapId": string, // absent for a concepts.jamf.com or support.jamf.com TOC, // and when a TOC provider names no map "toc": [...], // each entry: title, url, and contentId when from a map "tokenInfo": { "tokenCount": number, "truncated": boolean, "maxTokens": number }, "pagination": { "page": number, "pageSize": number, "totalPages": number, "totalItems": number, "hasNext": boolean, "hasPrev": boolean }, "truncatedEntry"?: { // only on a page cut to fit; see the Note "title": string, "shownEntries": number, "totalEntries": number, "estimatedTokens": number } }
For Markdown format: A hierarchical list of documentation topics with pagination and token info.
Examples:
Browse Jamf Pro documentation: product="jamf-pro"
Get page 2 of TOC: product="jamf-pro", page=2
Limit response size: product="jamf-pro", maxTokens=2000
Errors:
"Invalid option: expected one of ..." (an input validation error) if product is not a known product ID
'Version "" not found', followed by the available versions, if that version is not published
Note: Use this to discover what topics are available before searching or retrieving specific articles. Large TOCs are paginated by top-level entry: a page holds up to 10 of them, each with everything under it, as many as fit maxTokens, and the next page starts at the first that did not fit. Every top-level entry is on exactly one page, but which page depends on maxTokens, so keep maxTokens the same while paging; the markdown footer names it beside the next page when it is not the default. A top-level entry larger than maxTokens on its own is alone on its page, cut to the entries under it that fit; only that page has tokenInfo.truncated, and truncatedEntry.estimatedTokens is what the whole entry costs. If maxTokens makes more pages than page accepts (100), page 100 offers no next page and paginationNote names a maxTokens that reaches the rest. The response-level mapId and an entry's contentId together form the pair jamf_docs_get_article accepts for a direct fetch. Full markdown shows the mapId only, and compact markdown shows neither; use responseFormat="json" (or read structuredContent) for both. A concepts.jamf.com or support.jamf.com TOC has neither: it names no map, and its entries carry only title, url and children. Read any of its entries by url with jamf_docs_get_article; a support.jamf.com subcollection's url is its collection page, which reads as the list of its articles. structuredContent also carries what to send back for the next page: productId (or publicationId), version, language (when one was asked for) and maxTokens. The JSON text has no id or language, and has the budget as tokenInfo.maxTokens. structuredContent.entries is the TOC flattened in document order and always carries every descendant; each entry's depth (0 for top level) is what restores the nesting. The markdown is not the same view: outputMode="full" shows that nesting as indentation, while outputMode="compact" lists only the top-level entries and shows no nesting at all.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number for pagination (1-100, default: 1) | |
| product | No | Product ID: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog, jamf-account, jamf-security-cloud, elevate, composer, jamf-parent, jamf-teacher, jamf-setup-reset, jamf-assessment, title-editor, jamf-infrastructure-manager, jamf-adcs-connector, jamf-pki-proxy, jamf-migrate, jamf-remote-assist, jamf-cloud-distribution-service, healthcare-listener | |
| version | No | Specific version (e.g. "11.13.0"), at most 50 characters; defaults to latest | |
| language | No | Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN | |
| maxTokens | No | Maximum tokens in response (100-50000, default: 5000) | |
| outputMode | No | Output detail level: "full" for detailed output or "compact" for brief output | full |
| publication | No | Bundle family id for any Jamf publication, e.g. "technical-paper-laps" or "jamf-pro-release-notes". Use this for the documents that are not one of the products in `product` — release notes, technical papers, courses, evaluation and configuration guides. Exactly one of `product` or `publication` is required. Call jamf_docs_list_products to see the available ids. | |
| responseFormat | No | Output format: "markdown" for human-readable or "json" for machine-readable | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | |
| mapId | No | |
| entries | Yes | |
| hasMore | Yes | |
| product | Yes | |
| version | Yes | |
| language | No | |
| maxTokens | Yes | |
| productId | No | |
| localeNote | No | |
| totalPages | Yes | |
| versionNote | No | |
| totalEntries | Yes | |
| publicationId | No | |
| paginationNote | No | |
| truncatedEntry | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, open-world), but the description goes well beyond them: pagination is by top-level entry with maxTokens affecting page boundaries, truncation is signalled via tokenInfo.truncated and truncatedEntry, concepts/support TOCs lack mapId/contentId, and language fallback to en-US surfaces as localeNote. These are non-obvious operational behaviors an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Structure is sound (Args/Returns/Examples/Errors/Note), but the Args section reproduces the schema's parameter descriptions and full enum lists verbatim, adding no value, and the trailing Note is an undifferentiated wall of prose mixing pagination mechanics, id and format rules. It is over-sized for what must be conveyed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even though an output schema exists and return values needn't be explained, the definition covers errors, examples, pagination edge cases and follow-up tool wiring. Nothing needed to invoke this 8-parameter tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, and the description does repeat the enum lists nearly verbatim. However it adds genuine meaning the schema lacks: the product-vs-publication mutual exclusivity and their semantic split, the language fallback behavior, and that outputMode='compact' yields only top-level entries with no nesting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get the table of contents'), then immediately scopes it to two axes (product vs publication) and clarifies that release notes, technical papers and guides live on the publication axis. It also contrasts itself with siblings by saying this is for discovery 'before searching or retrieving specific articles,' so an agent can distinguish it from jamf_docs_search and jamf_docs_get_article.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing guidance: call jamf_docs_list_products for available publication ids, use jamf_docs_get_article with the mapId/contentId pair for a direct fetch, and use this tool to discover topics before searching. The when-to-use condition is stated outright rather than inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jamf_docs_glossary_lookupLookup Jamf Glossary TermARead-onlyIdempotent
Look up a term in the Jamf official glossary and get its definition.
This tool searches the Jamf Platform Technical Glossary, one glossary shared by every Jamf product, and returns matching term definitions using fuzzy matching. A term of 4 characters or fewer is treated as an abbreviation and must be a whole word of the entry's name, so "DEP" does not match "zero-touch deployment". A 4-character term may be a plural, or miss a letter or swap two ("MDMs", "LDPA").
Note: Glossary content is currently only available in English (en-US). Non-English language parameters are accepted but results will be in English. A reply with no match says so when the term was asked in another language or written in a script other than Latin, such as Chinese.
Args:
term (string, required): Glossary term to look up (2-100 characters). Supports fuzzy matching.
product (string, optional): Accepted, but does not filter: Jamf publishes one platform-wide glossary with no product classification
language (string, optional): Documentation language/locale (default: en-US). Note: glossary is English-only.
maxTokens (number, optional): Maximum tokens in response 100-50000 (default: 5000)
outputMode ('full' | 'compact'): Output detail level (default: 'full')
responseFormat ('markdown' | 'json'): Output format (default: 'markdown')
Returns: For JSON format: { "term": string, "totalMatches": number, "entries": [{ "term": string, "definition": string, "url": string }], "tokenInfo": { "tokenCount": number, "truncated": boolean, "maxTokens": number }, "truncatedContent"?: { "omittedCount": number, "omittedItems": [{ "title": string, "estimatedTokens": number }] }, "incomplete"?: { "unfetched": [{ "term": string, "url": string }], "message": string }, // Set when the English glossary answered a term asked in another language, // or found no match for one written in a script other than Latin. "warning"?: string }
For Markdown format: A formatted list of glossary definitions with source links.
Examples:
"What is MDM?" → term="MDM"
"What is a configuration profile?" → term="Configuration Profile"
"What is Automated Device Enrollment (formerly DEP)?" → term="Automated Device Enrollment"
Errors:
"Glossary lookup for "" failed: ..." (isError) if the glossary could not be read: learn.jamf.com could not be reached, timed out or answered with an error, or a configured maps provider failed. The lookup cannot say whether the glossary has the term, so this is not a "no match". The message says whether trying again may help.
"Invalid option: expected one of ..." (an input validation error) if product is not a known product ID
Note: "No glossary entries found" is not an error. It means the glossary was read and no entry matches; in JSON that is "totalMatches": 0. If entries match but not even the first fits in maxTokens, the reply says how many matched and the maxTokens the first one needs: "truncatedContent" lists each entry left out and the tokens it costs. If some matching entries could not be fetched, the reply answers from the rest and says so: "incomplete" names the entries it may be missing. If the entry that would lead the answer is one of them, that is the error above instead.
| Name | Required | Description | Default |
|---|---|---|---|
| term | Yes | Glossary term to look up (e.g., "MDM", "Configuration Profile", "Automated Device Enrollment") | |
| product | No | Accepted, but does not filter: Jamf publishes one platform-wide glossary with no product classification | |
| language | No | Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN | |
| maxTokens | No | Maximum tokens in response (100-50000, default: 5000) | |
| outputMode | No | Output detail level: "full" for detailed output or "compact" for brief output | full |
| responseFormat | No | Output format: "markdown" for human-readable or "json" for machine-readable | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| term | Yes | |
| entries | Yes | |
| truncated | Yes | |
| incomplete | No | |
| totalMatches | Yes | |
| truncatedContent | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/openWorld/idempotent, but the description adds substantial behavior beyond them: a fuzzy-match contract, the abbreviation rule, the English-only result caveat, an explicit distinction between 'no match' and a hard read failure, and how truncation ('truncatedContent') and partial fetches ('incomplete') are reported.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the one-line purpose, then layered detail and edge cases; the Examples and Errors sections are dense and high-value. It is somewhat long and the Args block largely duplicates the 100%-covered input schema, which is the main redundancy, but nothing is padded prose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter, open-world lookup with an output schema, the description covers the non-obvious failure modes an agent needs: no-match is not an error, truncation reports omitted entries and their token cost, partial responses are flagged via 'incomplete', and unreachable-glossary failures are distinguished from misses.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds real meaning: 'product' is accepted yet does not filter because the glossary is platform-wide, and 'language' is accepted yet results stay English. Those warnings prevent the agent from misusing two enum parameters, though maxTokens/outputMode/responseFormat are only restated from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Look up a term in the Jamf official glossary and get its definition,' and names the exact corpus (Jamf Platform Technical Glossary). This clearly distinguishes it from siblings like jamf_docs_search and jamf_docs_get_article, which operate on articles rather than glossary terms.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete usage conditions: fuzzy matching behavior, the 4-character abbreviation rule (so 'DEP' will not match 'zero-touch deployment'), plural/misspelling tolerance, and the English-only constraint. It never explicitly routes the agent away from this tool toward a sibling (e.g., use search for general article lookup), so it stops short of full alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jamf_docs_list_productsList Jamf ProductsARead-onlyIdempotent
List Jamf products, publications, topics, and documentation versions.
Returns two separate catalogues:
Products: the IDs the
productfilter in jamf_docs_search accepts, and theproductparameter of jamf_docs_get_toc. Jamf Pro, Jamf School, Jamf Connect, Jamf Protect, Jamf Now, Jamf Safe Internet and more.Publications: every document Jamf publishes - release notes, technical papers, courses, evaluation and configuration guides - grouped the way Jamf classifies them. Pass one of these IDs as the
publicationparameter of jamf_docs_get_toc. These are documents, not products, and the searchproductfilter does not take them. Each one's "locales" are the languages Jamf publishes it in.
Also lists available topic and docType filters for search.
Args:
maxTokens (number, optional): Maximum tokens in response 100-50000 (default: 10000, higher than other tools because this one answers with a whole catalogue)
outputMode ('full' | 'compact'): Output detail level (default: 'full'). Use 'compact' for brief list
responseFormat ('markdown' | 'json'): Output format (default: 'markdown')
Returns: For JSON format: { "products": [...], "publications": [...], "topics": [...], "incomplete"?: { "unavailable": string[], "message": string }, "tokenInfo": { "tokenCount": number, "truncated": boolean, "maxTokens": number } }
For Markdown format: A formatted list of products and topics with their details.
Examples:
"What Jamf products are available?" → use this tool
"List all Jamf documentation" → use this tool
"What topics can I filter by?" → use this tool
"Where are the Jamf Pro release notes?" → use this tool, then get_toc with the publication ID
Note: This is a read-only operation that does not modify any state.
If a source could not be read, the reply lists what it could and says so. "incomplete" then names each unavailable source, its "message" says what that cost, and the Markdown reply says the same at the top. "maps-registry" is the list of documentation maps, from learn.jamf.com or a configured maps provider, where the publication list and the product versions both come from: either can then be missing or a compiled-in default. "jamf-support" is support.jamf.com, whose jamf-support-* publications are then missing, or, when only some of its languages could not be read, leave those out of their "locales". The message says whether trying again may help. No "incomplete" means every source answered.
| Name | Required | Description | Default |
|---|---|---|---|
| maxTokens | No | Maximum tokens in response (100-50000, default: 10000) | |
| outputMode | No | Output detail level: "full" for detailed output or "compact" for brief output | full |
| responseFormat | No | Output format: "markdown" for human-readable or "json" for machine-readable | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| topics | Yes | |
| products | Yes | |
| incomplete | No | |
| publications | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and openWorld=false. The description adds substantive behavioral context beyond that: the `incomplete` failure field, the maps-registry and jamf-support sources that can be unavailable, retry guidance, and how missing languages affect publication locales. This goes beyond structured safety metadata without contradicting it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a clear one-line summary and bulleted catalogue distinctions. However, the Returns section reproduces return structures that already exist in the output schema, and the multi-paragraph incomplete-source note is verbose for the agent's decision needs. Length is not fully earned given the output schema covers return values.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering safety and an output schema covering return shape, the description still supplies the critical product-vs-publication distinction and source-failure behavior. Nothing an agent needs to call this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters are already documented in the input schema. The description largely repeats outputMode and responseFormat semantics, adding only the rationale that maxTokens defaults higher because this tool returns a whole catalogue. Baseline 3 is appropriate when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb 'List' and the resources covered: Jamf products, publications, topics, and documentation versions. It distinguishes the product IDs it returns from the `product` filter in jamf_docs_search and the `product` parameter of jamf_docs_get_toc, and separately explains publication IDs for get_toc. An agent can tell it apart from siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit user-intent examples ('What Jamf products are available?', 'Where are the Jamf Pro release notes?') mapping to this tool and the follow-up get_toc call. It also warns that publications are not products and that the search `product` filter does not accept them, giving a clear when-not-to-use condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jamf_docs_searchSearch Jamf DocumentationARead-onlyIdempotent
Search Jamf documentation for articles matching your query.
This tool searches across all Jamf product documentation including Jamf Pro, Jamf School, Jamf Connect, Jamf Protect, Jamf Now, Jamf Safe Internet, and more. Results include article titles, snippets, and direct links.
Args:
query (string, required): Search keywords (2-200 characters, or one Chinese, Japanese or Korean character)
product (string, optional): Filter by product ID (use jamf_docs_list_products to see all)
topic (string, optional): Filter by topic. Common: enrollment, profiles, policies, packages, scripts, patch, apps, security, filevault, sso, identity-provider, inventory, reports, api, network. See jamf_docs_list_products for the full list of 40 topic IDs.
docType (string, optional): Filter by document type: documentation, release-notes, training, solution-guide, glossary, getting-started
version (string, optional): Filter by version (e.g., "11.13.0") or "current", at most 50 characters
language (string, optional): Documentation language/locale (default: en-US)
limit (number, optional): Maximum results per page 1-50 (default: 10)
page (number, optional): Page number for pagination 1-100 (default: 1)
maxTokens (number, optional): Maximum tokens in response 100-50000 (default: 5000)
outputMode ('full' | 'compact'): Output detail level (default: 'full'). Use 'compact' for brief, token-efficient output
responseFormat ('markdown' | 'json'): Output format (default: 'markdown')
Returns: For JSON format: { "total": number, "query": string, "results": [...], "tokenInfo": { "tokenCount": number, "truncated": boolean, "maxTokens": number }, "pagination": { "page": number, "pageSize": number, "totalPages": number, "totalItems": number, "hasNext": boolean, "hasPrev": boolean }, // Set when a filter matched nothing and was removed, or could not be applied. "filterRelaxation"?: { "removed": [string], "original": { "": string }, "message": string }, // Set when a result is at a version other than the one asked for. "versionNote"?: string, // Set when no page has a phrase the query quotes in 「」, 『』, 「」 or « » as written: // the query was searched again with those marks read as no quotes, and "results" are // what that found. Also set, with no results, when that found nothing either. "queryNote"?: string, // Set when page was past the last page, and the last is shown instead, or when // limit and maxTokens make more pages than page accepts: it then says what // reaches the rest. "paginationNote"?: string, // How "results" are ordered, and by whom. Absent when "results" is empty. "relevanceNote"?: string, // Pages outside the product documentation, matched on title and ranked // separately from "results", which carry no score to rank them against. // Omitted when none matched. "otherSources"?: [{ "title": string, "url": string, "source": string }], // Queries to try instead, when "results" is empty. "suggestions"?: [string], // When "results" is empty and language is not en-US, as not all documentation is // in it, or the query has Chinese, Japanese, Korean or Thai words and the documentation in // language is not written in them: which documentation to search instead, and how. "localeNote"?: string, // Only on a page that is one result cut to fit; see the Note on paging. "truncatedResult"?: { "title": string, "estimatedTokens": number } }
For Markdown format: A formatted list of search results with pagination and token info.
Examples (common query → recommended filters):
"Configure SSO with Okta in Jamf Connect" → query="SSO Okta", product="jamf-connect", topic="sso"
"Set up FileVault encryption" → query="FileVault encryption", product="jamf-pro", topic="filevault"
"Patch macOS apps" → query="patch policy", product="jamf-pro", topic="patch"
"Smart group criteria" → query="smart group criteria", product="jamf-pro", topic="reports"
"Automated Device Enrollment workflow" → query="ADE prestage", product="jamf-pro", topic="enrollment"
"Shared iPad in a classroom" → query="shared iPad classroom", product="jamf-school", topic="education"
"Jamf Protect custom analytic" → query="custom analytic", product="jamf-protect", topic="protect-analytics"
"Jamf Pro REST API authentication" → query="API role bearer token", product="jamf-pro", topic="api"
"Extension attribute scripts" → query="extension attribute script", product="jamf-pro", topic="extension-attributes"
"Paginate through results" → query="policy", page=2
Errors:
"Search for "" failed: ..." (isError) if the search could not be completed: learn.jamf.com could not be reached, timed out or answered with an error, or a configured search backend failed. This is not a "no results": the search did not complete, so the reply cannot say whether anything matches. The message says whether trying again may help. Pages outside the product documentation that did match follow it, in a second text block.
"Invalid option: expected one of ..." (an input validation error) if product, topic, docType or language is not one of the values the input schema lists
Note: "No results found" is not an error. It means the search ran and nothing in the product documentation matched; in JSON that is "total": 0, with "suggestions" and any "otherSources".
Note: Results are ranked by relevance. Use filters and pagination to navigate large result sets. A page holds up to limit results, as many as fit maxTokens, and the next page starts at the first that did not fit. Every result is on exactly one page, but which page depends on limit and maxTokens, so keep both the same while paging; the markdown footer names them beside the next page when they are not the default, and structuredContent carries limit and maxTokens. A result larger than maxTokens on its own is alone on its page with its snippet cut to fit; only that page has tokenInfo.truncated, and truncatedResult.estimatedTokens is what the whole result costs. If limit and maxTokens make more pages than page accepts (100), page 100 offers no next page and paginationNote says what reaches the rest. Most results carry a mapId + contentId pair; pass both to jamf_docs_get_article to fetch that article directly instead of resolving its URL. The pair is omitted when a result comes from a source that does not resolve one — fall back to the URL in that case, unless the result is external (see the next Note).
Note: A result with "external": true is not a page of the documentation but one Jamf's search lists beside it, such as a course in the Jamf Training Catalog (trainingcatalog.jamf.com), at the rank the search gave it. jamf_docs_get_article cannot read it: open its url in a browser. It has no mapId + contentId pair. Jamf classifies a Training Catalog course as training content, so its docType is "training" and docType "training" returns it; any other docType, or a specific version, leaves it out.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number for pagination (1-100, default: 1) | |
| limit | No | Maximum number of results per page (1-50) | |
| query | Yes | Search keywords to find in Jamf documentation: 2-200 characters, or one Chinese, Japanese or Korean character | |
| topic | No | Filter by topic. Common: enrollment, profiles, policies, packages, scripts, patch, apps, security, filevault, sso, identity-provider, inventory, reports, api, network. See jamf_docs_list_products for the full list of 40 topic IDs. | |
| docType | No | Filter by document type: documentation, release-notes, training, solution-guide, glossary, getting-started | |
| product | No | Filter by product: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog, jamf-account, jamf-security-cloud, elevate, composer, jamf-parent, jamf-teacher, jamf-setup-reset, jamf-assessment, title-editor, jamf-infrastructure-manager, jamf-adcs-connector, jamf-pki-proxy, jamf-migrate, jamf-remote-assist, jamf-cloud-distribution-service, healthcare-listener | |
| version | No | Filter by version (e.g., "11.13.0") or "current", at most 50 characters | |
| language | No | Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN | |
| maxTokens | No | Maximum tokens in response (100-50000, default: 5000) | |
| outputMode | No | Output detail level: "full" for detailed output or "compact" for brief output | full |
| responseFormat | No | Output format: "markdown" for human-readable or "json" for machine-readable | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | |
| limit | No | |
| query | Yes | |
| filters | No | |
| hasMore | Yes | |
| results | Yes | |
| maxTokens | No | |
| queryNote | No | |
| totalPages | Yes | |
| suggestions | No | |
| versionNote | No | |
| otherSources | No | |
| totalResults | Yes | |
| relevanceNote | No | |
| paginationNote | No | |
| truncatedResult | No | |
| filterRelaxation | No | |
| truncatedContent | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds substantial behavioral detail beyond annotations: relevance ranking, pagination coupled to maxTokens, truncation behavior, filterRelaxation, queryNote, localeNote, external results, and the distinction between no-results and errors.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and well structured, but it is very long and repeats parameter documentation and a large Returns schema that the output schema already supplies. Many notes are operationally useful for pagination and edge cases, but the overall length goes beyond concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 11-parameter search tool with rich annotations and an output schema, the description covers errors, pagination interactions, token limits, external results, locale fallbacks, and article retrieval handoff. It leaves almost no contextual gap for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the schema already documents all 11 parameters. The description adds value through recommended filter examples, product/topic lookup pointers, and pagination interaction notes, though much of its Args section repeats schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Search Jamf documentation for articles matching your query,' and explains the product scope. It also distinguishes this from jamf_docs_get_article by describing how results lead to article retrieval, so an agent can select it correctly among siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides concrete query-to-filter examples and points to jamf_docs_list_products for product/topic IDs and jamf_docs_get_article for fetching an article. It does not explicitly state when not to use search versus batch retrieval, but the routing guidance is clear and practical.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v6.0.14- Changed
jamf_docs_batch_get_articles4 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Documentation language/locale. Overrides the locale in the article URL, which is used when this is omitted. Has no effect on concepts.jamf.com or support.jamf.com URLs. Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN"New value: +"Documentation language/locale. Overrides the locale in the article URL, which is used when this is omitted. A learn.jamf.com publication Jamf does not publish in it is served in en-US, and a concepts.jamf.com or support.jamf.com page with no edition in it as the URL names it, both with a note; contentLocale says which language was served. Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN" - changed
Input schema / properties / urls / descriptionPrevious value: -"Array of Jamf documentation article URLs (1-10)"New value: +"Array of Jamf documentation article URLs (1-10), each at most 2048 characters" - added
Input schema / properties / urls / items / maxLengthAdded value: +2048 - added
Output schema / properties / results / items / properties / contentLocaleAdded value: +{ + "type": "string" +}
- Changed
jamf_docs_get_article5 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Documentation language/locale. Overrides the locale in the article URL, which is used when this is omitted. Has no effect on concepts.jamf.com or support.jamf.com URLs, or on a mapId + contentId pair, whose map is already in one language. Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN"New value: +"Documentation language/locale. Overrides the locale in the article URL, which is used when this is omitted. A learn.jamf.com publication Jamf does not publish in it is served in en-US, and a concepts.jamf.com or support.jamf.com page with no edition in it as the URL names it, both with a note; contentLocale says which language was served. No effect on a mapId + contentId pair, whose map is already in one language. Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN" - changed
Input schema / properties / section / descriptionPrevious value: -"Extract only a specific section by title or ID (e.g., \"Prerequisites\", \"Configuration\")"New value: +"Extract only a specific section by title or ID (e.g., \"Prerequisites\", \"Configuration\"), at most 200 characters" - added
Input schema / properties / section / maxLengthAdded value: +200 - changed
Input schema / properties / url / descriptionPrevious value: -"Full https:// URL of the Jamf documentation article, on learn.jamf.com, docs.jamf.com, concepts.jamf.com, support.jamf.com. Alternative: use mapId + contentId for direct fetch. One of the two is required."New value: +"Full https:// URL of the Jamf documentation article, on learn.jamf.com, docs.jamf.com, concepts.jamf.com, support.jamf.com, at most 2048 characters. Alternative: use mapId + contentId for direct fetch. One of the two is required." - added
Input schema / properties / url / maxLengthAdded value: +2048
- Changed
jamf_docs_get_toc2 fields changed- changed
Input schema / properties / version / descriptionPrevious value: -"Specific version (e.g. \"11.13.0\"); defaults to latest"New value: +"Specific version (e.g. \"11.13.0\"), at most 50 characters; defaults to latest" - added
Input schema / properties / version / maxLengthAdded value: +50
- Changed
jamf_docs_search8 fields changed- changed
Input schema / properties / query / descriptionPrevious value: -"Search keywords to find in Jamf documentation"New value: +"Search keywords to find in Jamf documentation: 2-200 characters, or one Chinese, Japanese or Korean character" - changed
Input schema / properties / query / minLengthPrevious value: -2New value: +1 - changed
Input schema / properties / version / descriptionPrevious value: -"Filter by version (e.g., \"11.13.0\") or \"current\""New value: +"Filter by version (e.g., \"11.13.0\") or \"current\", at most 50 characters" - added
Input schema / properties / version / maxLengthAdded value: +50 - added
Output schema / properties / maxTokensAdded value: +{ + "type": "number" +} - added
Output schema / properties / queryNoteAdded value: +{ + "type": "string" +} - added
Output schema / properties / results / items / properties / externalAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / truncatedResultAdded value: +{ + "additionalProperties": false, + "properties": { + "estimatedTokens": { + "type": "number" + }, + "title": { + "type": "string" + } + }, + "required": [ + "title", + "estimatedTokens" + ], + "type": "object" +}
4 tool updates
v6.0.12- Changed
jamf_docs_get_toc4 fields changed- added
Output schema / properties / languageAdded value: +{ + "type": "string" +} - added
Output schema / properties / maxTokensAdded value: +{ + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" +} - added
Output schema / properties / truncatedEntryAdded value: +{ + "additionalProperties": false, + "properties": { + "estimatedTokens": { + "type": "number" + }, + "shownEntries": { + "type": "number" + }, + "title": { + "type": "string" + }, + "totalEntries": { + "type": "number" + } + }, + "required": [ + "title", + "shownEntries", + "totalEntries", + "estimatedTokens" + ], + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "product", - "version", - "totalEntries", - "page", - "totalPages", - "hasMore", - "entries" -]New value: +[ + "product", + "version", + "totalEntries", + "page", + "totalPages", + "hasMore", + "maxTokens", + "entries" +]
- Changed
jamf_docs_glossary_lookup1 field changed- added
Output schema / properties / truncatedContentAdded value: +{ + "additionalProperties": false, + "properties": { + "omittedCount": { + "type": "number" + }, + "omittedItems": { + "items": { + "additionalProperties": false, + "properties": { + "estimatedTokens": { + "type": "number" + }, + "title": { + "type": "string" + } + }, + "required": [ + "title", + "estimatedTokens" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "omittedCount", + "omittedItems" + ], + "type": "object" +}
- Changed
jamf_docs_list_products1 field changed- added
Output schema / properties / incompleteAdded value: +{ + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "unavailable", + "message" + ], + "type": "object" +}
- Changed
jamf_docs_search1 field changed- added
Output schema / properties / results / items / properties / crossFiledAdded value: +{ + "type": "boolean" +}
3 tool updates
v6.0.11- Changed
jamf_docs_batch_get_articles1 field changed- changed
Input schema / properties / language / descriptionPrevious value: -"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN"New value: +"Documentation language/locale. Overrides the locale in the article URL, which is used when this is omitted. Has no effect on concepts.jamf.com or support.jamf.com URLs. Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN"
- Changed
jamf_docs_get_article2 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN"New value: +"Documentation language/locale. Overrides the locale in the article URL, which is used when this is omitted. Has no effect on concepts.jamf.com or support.jamf.com URLs, or on a mapId + contentId pair, whose map is already in one language. Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN" - changed
Input schema / properties / url / descriptionPrevious value: -"Full URL of the Jamf documentation article. Alternative: use mapId + contentId for direct fetch."New value: +"Full https:// URL of the Jamf documentation article, on learn.jamf.com, docs.jamf.com, concepts.jamf.com, support.jamf.com. Alternative: use mapId + contentId for direct fetch. One of the two is required."
- Changed
jamf_docs_glossary_lookup3 fields changed- changed
Input schema / properties / product / descriptionPrevious value: -"Filter by product: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog, jamf-account, jamf-security-cloud, elevate, composer, jamf-parent, jamf-teacher, jamf-setup-reset, jamf-assessment, title-editor, jamf-infrastructure-manager, jamf-adcs-connector, jamf-pki-proxy, jamf-migrate, jamf-remote-assist, jamf-cloud-distribution-service, healthcare-listener"New value: +"Accepted, but does not filter: Jamf publishes one platform-wide glossary with no product classification" - changed
Input schema / properties / term / descriptionPrevious value: -"Glossary term to look up (e.g., \"MDM\", \"Configuration Profile\", \"Smart Group\")"New value: +"Glossary term to look up (e.g., \"MDM\", \"Configuration Profile\", \"Automated Device Enrollment\")" - added
Output schema / properties / incompleteAdded value: +{ + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + }, + "unfetched": { + "items": { + "additionalProperties": false, + "properties": { + "term": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "term", + "url" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "unfetched", + "message" + ], + "type": "object" +}
1 tool update
v5.10.6- Changed
jamf_docs_list_products8 fields changed- changed
Input schema / properties / maxTokens / defaultPrevious value: -5000New value: +10000 - changed
Input schema / properties / maxTokens / descriptionPrevious value: -"Maximum tokens in response (100-50000, default: 5000)"New value: +"Maximum tokens in response (100-50000, default: 10000)" - added
Output schema / properties / publications / items / properties / app / itemsAdded value: +{ + "type": "string" +} - changed
Output schema / properties / publications / items / properties / app / typePrevious value: -"string"New value: +"array" - added
Output schema / properties / publications / items / properties / portal / itemsAdded value: +{ + "type": "string" +} - changed
Output schema / properties / publications / items / properties / portal / typePrevious value: -"string"New value: +"array" - added
Output schema / properties / publications / items / properties / utility / itemsAdded value: +{ + "type": "string" +} - changed
Output schema / properties / publications / items / properties / utility / typePrevious value: -"string"New value: +"array"
6 tool updates
v5.10.1- Changed
jamf_docs_batch_get_articles2 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH"New value: +"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN" - changed
Input schema / properties / language / enumPrevious value: -[ - "en-US", - "ja-JP", - "zh-TW", - "de-DE", - "es-ES", - "fr-FR", - "nl-NL", - "th-TH" -]New value: +[ + "en-US", + "ja-JP", + "zh-TW", + "de-DE", + "es-ES", + "fr-FR", + "nl-NL", + "th-TH", + "it-IT", + "pt-BR", + "zh-CN" +]
- Changed
jamf_docs_get_article2 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH"New value: +"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN" - changed
Input schema / properties / language / enumPrevious value: -[ - "en-US", - "ja-JP", - "zh-TW", - "de-DE", - "es-ES", - "fr-FR", - "nl-NL", - "th-TH" -]New value: +[ + "en-US", + "ja-JP", + "zh-TW", + "de-DE", + "es-ES", + "fr-FR", + "nl-NL", + "th-TH", + "it-IT", + "pt-BR", + "zh-CN" +]
- Changed
jamf_docs_get_toc11 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH"New value: +"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN" - changed
Input schema / properties / language / enumPrevious value: -[ - "en-US", - "ja-JP", - "zh-TW", - "de-DE", - "es-ES", - "fr-FR", - "nl-NL", - "th-TH" -]New value: +[ + "en-US", + "ja-JP", + "zh-TW", + "de-DE", + "es-ES", + "fr-FR", + "nl-NL", + "th-TH", + "it-IT", + "pt-BR", + "zh-CN" +] - changed
Input schema / properties / product / descriptionPrevious value: -"Product ID: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog"New value: +"Product ID: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog, jamf-account, jamf-security-cloud, elevate, composer, jamf-parent, jamf-teacher, jamf-setup-reset, jamf-assessment, title-editor, jamf-infrastructure-manager, jamf-adcs-connector, jamf-pki-proxy, jamf-migrate, jamf-remote-assist, jamf-cloud-distribution-service, healthcare-listener" - changed
Input schema / properties / product / enumPrevious value: -[ - "jamf-pro", - "jamf-school", - "jamf-connect", - "jamf-protect", - "jamf-now", - "jamf-safe-internet", - "jamf-insights", - "jamf-rapididentity", - "jamf-trust", - "jamf-routines", - "self-service-plus", - "jamf-app-catalog" -]New value: +[ + "jamf-pro", + "jamf-school", + "jamf-connect", + "jamf-protect", + "jamf-now", + "jamf-safe-internet", + "jamf-insights", + "jamf-rapididentity", + "jamf-trust", + "jamf-routines", + "self-service-plus", + "jamf-app-catalog", + "jamf-account", + "jamf-security-cloud", + "elevate", + "composer", + "jamf-parent", + "jamf-teacher", + "jamf-setup-reset", + "jamf-assessment", + "title-editor", + "jamf-infrastructure-manager", + "jamf-adcs-connector", + "jamf-pki-proxy", + "jamf-migrate", + "jamf-remote-assist", + "jamf-cloud-distribution-service", + "healthcare-listener" +] - added
Input schema / properties / publicationAdded value: +{ + "description": "Bundle family id for any Jamf publication, e.g. \"technical-paper-laps\" or \"jamf-pro-release-notes\". Use this for the documents that are not one of the products in `product` — release notes, technical papers, courses, evaluation and configuration guides. Exactly one of `product` or `publication` is required. Call jamf_docs_list_products to see the available ids.", + "maxLength": 200, + "minLength": 1, + "type": "string" +} - changed
Input schema / properties / version / descriptionPrevious value: -"Specific version (defaults to latest)"New value: +"Specific version (e.g. \"11.13.0\"); defaults to latest" - added
Input schema / properties / version / patternAdded value: +"^(?:current|\\d+(?:\\.\\d+)*)$" - removed
Input schema / requiredRemoved value: -[ - "product" -] - added
Output schema / properties / localeNoteAdded value: +{ + "type": "string" +} - added
Output schema / properties / publicationIdAdded value: +{ + "type": "string" +} - changed
Output schema / requiredPrevious value: -[ - "product", - "productId", - "version", - "totalEntries", - "page", - "totalPages", - "hasMore", - "entries" -]New value: +[ + "product", + "version", + "totalEntries", + "page", + "totalPages", + "hasMore", + "entries" +]
- Changed
jamf_docs_glossary_lookup4 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH"New value: +"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN" - changed
Input schema / properties / language / enumPrevious value: -[ - "en-US", - "ja-JP", - "zh-TW", - "de-DE", - "es-ES", - "fr-FR", - "nl-NL", - "th-TH" -]New value: +[ + "en-US", + "ja-JP", + "zh-TW", + "de-DE", + "es-ES", + "fr-FR", + "nl-NL", + "th-TH", + "it-IT", + "pt-BR", + "zh-CN" +] - changed
Input schema / properties / product / descriptionPrevious value: -"Filter by product: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog"New value: +"Filter by product: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog, jamf-account, jamf-security-cloud, elevate, composer, jamf-parent, jamf-teacher, jamf-setup-reset, jamf-assessment, title-editor, jamf-infrastructure-manager, jamf-adcs-connector, jamf-pki-proxy, jamf-migrate, jamf-remote-assist, jamf-cloud-distribution-service, healthcare-listener" - changed
Input schema / properties / product / enumPrevious value: -[ - "jamf-pro", - "jamf-school", - "jamf-connect", - "jamf-protect", - "jamf-now", - "jamf-safe-internet", - "jamf-insights", - "jamf-rapididentity", - "jamf-trust", - "jamf-routines", - "self-service-plus", - "jamf-app-catalog" -]New value: +[ + "jamf-pro", + "jamf-school", + "jamf-connect", + "jamf-protect", + "jamf-now", + "jamf-safe-internet", + "jamf-insights", + "jamf-rapididentity", + "jamf-trust", + "jamf-routines", + "self-service-plus", + "jamf-app-catalog", + "jamf-account", + "jamf-security-cloud", + "elevate", + "composer", + "jamf-parent", + "jamf-teacher", + "jamf-setup-reset", + "jamf-assessment", + "title-editor", + "jamf-infrastructure-manager", + "jamf-adcs-connector", + "jamf-pki-proxy", + "jamf-migrate", + "jamf-remote-assist", + "jamf-cloud-distribution-service", + "healthcare-listener" +]
- Changed
jamf_docs_list_products1 field changed- added
Output schema / properties / publicationsAdded value: +{ + "items": { + "additionalProperties": false, + "properties": { + "app": { + "type": "string" + }, + "id": { + "type": "string" + }, + "locales": { + "items": { + "type": "string" + }, + "type": "array" + }, + "portal": { + "type": "string" + }, + "title": { + "type": "string" + }, + "utility": { + "type": "string" + }, + "versions": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "id", + "title", + "locales", + "versions" + ], + "type": "object" + }, + "type": "array" +}
- Changed
jamf_docs_search8 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH"New value: +"Documentation language/locale (default: en-US). Options: en-US, ja-JP, zh-TW, de-DE, es-ES, fr-FR, nl-NL, th-TH, it-IT, pt-BR, zh-CN" - changed
Input schema / properties / language / enumPrevious value: -[ - "en-US", - "ja-JP", - "zh-TW", - "de-DE", - "es-ES", - "fr-FR", - "nl-NL", - "th-TH" -]New value: +[ + "en-US", + "ja-JP", + "zh-TW", + "de-DE", + "es-ES", + "fr-FR", + "nl-NL", + "th-TH", + "it-IT", + "pt-BR", + "zh-CN" +] - changed
Input schema / properties / product / descriptionPrevious value: -"Filter by product: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog"New value: +"Filter by product: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog, jamf-account, jamf-security-cloud, elevate, composer, jamf-parent, jamf-teacher, jamf-setup-reset, jamf-assessment, title-editor, jamf-infrastructure-manager, jamf-adcs-connector, jamf-pki-proxy, jamf-migrate, jamf-remote-assist, jamf-cloud-distribution-service, healthcare-listener" - changed
Input schema / properties / product / enumPrevious value: -[ - "jamf-pro", - "jamf-school", - "jamf-connect", - "jamf-protect", - "jamf-now", - "jamf-safe-internet", - "jamf-insights", - "jamf-rapididentity", - "jamf-trust", - "jamf-routines", - "self-service-plus", - "jamf-app-catalog" -]New value: +[ + "jamf-pro", + "jamf-school", + "jamf-connect", + "jamf-protect", + "jamf-now", + "jamf-safe-internet", + "jamf-insights", + "jamf-rapididentity", + "jamf-trust", + "jamf-routines", + "self-service-plus", + "jamf-app-catalog", + "jamf-account", + "jamf-security-cloud", + "elevate", + "composer", + "jamf-parent", + "jamf-teacher", + "jamf-setup-reset", + "jamf-assessment", + "title-editor", + "jamf-infrastructure-manager", + "jamf-adcs-connector", + "jamf-pki-proxy", + "jamf-migrate", + "jamf-remote-assist", + "jamf-cloud-distribution-service", + "healthcare-listener" +] - changed
Input schema / properties / version / descriptionPrevious value: -"Filter by version (e.g., \"11.5.0\", \"10.x\")"New value: +"Filter by version (e.g., \"11.13.0\") or \"current\"" - added
Input schema / properties / version / patternAdded value: +"^(?:current|\\d+(?:\\.\\d+)*)$" - added
Output schema / properties / otherSourcesAdded value: +{ + "items": { + "additionalProperties": false, + "properties": { + "source": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "title", + "url", + "source" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / results / items / properties / otherVersionsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +}
2 tool updates
v4.3.1- Changed
jamf_docs_get_article3 fields changed- added
Output schema / properties / contentLocaleAdded value: +{ + "type": "string" +} - added
Output schema / properties / navigationAdded value: +{ + "additionalProperties": false, + "properties": { + "childCount": { + "type": "number" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "title": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "title", + "url" + ], + "type": "object" + }, + "type": "array" + }, + "parent": { + "additionalProperties": false, + "properties": { + "title": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "title", + "url" + ], + "type": "object" + }, + "self": { + "additionalProperties": false, + "properties": { + "title": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "title", + "url" + ], + "type": "object" + }, + "siblingCount": { + "type": "number" + }, + "siblings": { + "items": { + "additionalProperties": false, + "properties": { + "title": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "title", + "url" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "self", + "siblings", + "children", + "siblingCount", + "childCount" + ], + "type": "object" +} - added
Output schema / properties / versionStatusAdded value: +{ + "enum": [ + "latest", + "superseded" + ], + "type": "string" +}
- Changed
jamf_docs_get_toc2 fields changed- added
Output schema / properties / entries / items / properties / depthAdded value: +{ + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - changed
Output schema / properties / entries / items / requiredPrevious value: -[ - "title", - "url" -]New value: +[ + "title", + "url", + "depth" +]
6 tool updates
v4.0.6- Changed
jamf_docs_batch_get_articles2 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
jamf_docs_get_article5 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Input schema / properties / contentId / patternPrevious value: -"^[a-zA-Z0-9_~\\-]+$"New value: +"^[a-zA-Z0-9_~-]+$" - changed
Input schema / properties / mapId / patternPrevious value: -"^[a-zA-Z0-9_~\\-]+$"New value: +"^[a-zA-Z0-9_~-]+$" - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / properties / tokenCountAdded value: +{ + "type": "number" +}
- Changed
jamf_docs_get_toc8 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Input schema / properties / product / descriptionPrevious value: -"Product ID: jamf-pro, jamf-school, jamf-connect, jamf-protect"New value: +"Product ID: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog" - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / properties / mapIdAdded value: +{ + "type": "string" +} - added
Output schema / properties / paginationNoteAdded value: +{ + "type": "string" +} - added
Output schema / properties / productIdAdded value: +{ + "type": "string" +} - added
Output schema / properties / versionNoteAdded value: +{ + "type": "string" +} - changed
Output schema / requiredPrevious value: -[ - "product", - "version", - "totalEntries", - "page", - "totalPages", - "hasMore", - "entries" -]New value: +[ + "product", + "productId", + "version", + "totalEntries", + "page", + "totalPages", + "hasMore", + "entries" +]
- Changed
jamf_docs_glossary_lookup3 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Input schema / properties / product / descriptionPrevious value: -"Filter by product: jamf-pro, jamf-school, jamf-connect, jamf-protect"New value: +"Filter by product: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog" - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
jamf_docs_list_products2 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
jamf_docs_search6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Input schema / properties / product / descriptionPrevious value: -"Filter by product: jamf-pro, jamf-school, jamf-connect, jamf-protect"New value: +"Filter by product: jamf-pro, jamf-school, jamf-connect, jamf-protect, jamf-now, jamf-safe-internet, jamf-insights, jamf-rapididentity, jamf-trust, jamf-routines, self-service-plus, jamf-app-catalog" - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / properties / filtersAdded value: +{ + "additionalProperties": false, + "properties": { + "docType": { + "type": "string" + }, + "language": { + "type": "string" + }, + "product": { + "type": "string" + }, + "topic": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / limitAdded value: +{ + "type": "number" +} - added
Output schema / properties / paginationNoteAdded value: +{ + "type": "string" +}
TDQS
Scored across 6 tools
Each tool occupies a distinct role in the docs workflow: catalogue listing, search, single fetch, batch fetch, TOC browsing, and glossary lookup. The only mild overlap is between jamf_docs_list_products (catalogue of products/publications/filters) and jamf_docs_get_toc (navigation structure), but the descriptions explicitly clarify that one is discovery metadata and the other is document hierarchy. jamf_docs_get_article vs jamf_docs_batch_get_articles is unambiguous given the batch's explicit concurrency/bulk framing.
All tools share a clear jamf_docs_ prefix and are snake_case, which is strong. Most follow verb_noun (list_products, get_article, get_toc), but glossary_lookup inverts to noun_verb and batch_get_articles inserts a modifier prefix, so it is not perfectly uniform.
Six tools is well-scoped for a documentation server: discovery, search, retrieval (single and bulk), structure browsing, and glossary each earn their place. No redundant or filler tools are present.
The doc lifecycle is well covered: discover products/publications, list versions via list_products or error hints, browse TOC, search, fetch single or batch articles, and look up glossary terms. Minor gaps include no dedicated version-listing or category-browsing operation, but agents can work around these via list_products and the TOC.
Maintenance
Related MCP Connectors
Tailor Platform for AI assistants: search, list and read the platform documentation.
Search and query nTop's knowledge base and engineering guides from AI applications.
The documentation, as a tool your agent can call: 950+ AI-dev guides. Search + fetch tools.
Versioned documentation registry and semantic search for AI tools and coding assistants.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to search and fetch documentation content from Adobe Experience League, allowing natural language queries to retrieve Adobe product documentation and articles.-
- AlicenseBqualityFmaintenanceProvides AI assistants with access to Apple's Human Interface Guidelines and technical API documentation across all Apple platforms (iOS, macOS, watchOS, tvOS, visionOS), enabling unified search of design principles and implementation details.23119 npm21MIT
- AlicenseAqualityDmaintenanceProvides access to Apple's official developer documentation, frameworks, APIs, and WWDC session transcripts across all Apple platforms. It enables AI assistants to search technical guides, sample code, and platform compatibility information using natural language queries.181,132 npm1,381MIT
- AlicenseAqualityDmaintenanceEnables AI agents to search and retrieve jam-nodes documentation, including node info, API references, and guides, via MCP tools without loading everything into context.51MIT