| name | iconclass-mcp |
| version | 0.4.2 |
| description | Companion vocabulary layer to rijksmuseum-mcp+: maps art-subject concepts to Iconclass notation codes (~1.3M codes across 13 languages) and checks which loaded collections have artworks tagged with them. Use this skill whenever the user mentions Iconclass, iconography, subject classification, what an artwork depicts, or wants to search/browse art subjects โ even if they don't name the server. Codes discovered here flow directly into rijksmuseum-mcp+'s search_artwork(iconclass=...).
|
Iconclass MCP Research Skill
Core Mental Model
This server is the vocabulary layer โ it helps you find and understand Iconclass notation codes. Its companion server, rijksmuseum-mcp+, is the collection layer that searches actual Rijksmuseum artworks. The two servers are designed to work together. The canonical workflow is:
DISCOVER -> NARROW -> RESOLVE -> FIND ARTWORKS -> HAND OFF
(search) (browse) (resolve) (find_artworks) (rijksmuseum-mcp+)
The final step โ handing notation codes to search_artwork(iconclass: [...]) on rijksmuseum-mcp+ โ is the expected outcome of most workflows. When rijksmuseum-mcp+ is available, prefer passing notation codes to it directly rather than presenting them as plain text for the user to act on. If it is not available, that's fine โ see the fallback guidance below.
For simple single-concept queries ("show me paintings of dogs"), rijksmuseum-mcp+'s subject parameter can sometimes find artworks directly without needing notation codes โ it searches the same Iconclass label vocabulary. The full Iconclass workflow (search โ browse โ handoff with iconclass:) is most valuable for compound queries, cross-branch discovery, or when the user wants to understand the taxonomy itself.
Iconclass is a retrieval tool, not a descriptive language. A notation's meaning comes from its position in the hierarchy, not just its label. Complex artworks carry many codes (often 30+) across different branches because a single image contains multiple subjects โ a scene, its setting, its actors, their attributes, symbolic objects. The goal is not to find the one right code but to identify the set of codes that carve out the search space you need.
Most of the ~40K base notations are "theoretical" โ they exist in the taxonomy but no loaded collection has tagged artworks with them. Check the collections array before handing a code to a collection server. An empty array means no loaded collection has artwork-count data for that notation; if you specifically need Rijksmuseum coverage, look for rijksmuseum. The find_artworks tool returns per-notation artwork counts by loaded collection.
Never truncate discovery queries. When searching for notation codes, use the default maxResults (25) or higher โ never set a lower value. You need to see enough of the result set, including collection-presence markers, to evaluate which codes are useful. Cutting results short means you miss relevant notations and can't make informed handoff decisions.
Companion Server: rijksmuseum-mcp+
This server's notation codes are the input to rijksmuseum-mcp+'s search_artwork(iconclass: [...]) parameter. The handoff is direct:
- Single notation:
search_artwork(iconclass: "73D6") โ finds all Rijksmuseum artworks tagged with "the Crucifixion of Christ"
- Multiple notations (AND):
search_artwork(iconclass: ["11H(FRANCIS)32", "25F3"]) โ finds artworks tagged with both codes
- Combined with other filters:
search_artwork(iconclass: "73D641", type: "painting") โ paintings of the crucified Christ with Mary and John
The iconclass parameter accepts exact notation codes (language-independent). These are the same codes returned by this server's search, browse, resolve, and search_prefix tools. Note that rijksmuseum-mcp+'s subject parameter is different โ it searches Iconclass label text (primarily Dutch/English), not notation codes.
Tool Selection Guide
| Question type | Start here |
|---|
| "What's the Iconclass code for X?" โ known term | search with query |
| "Find notations about X" โ conceptual / atmospheric | search with semanticQuery |
| "What subjects exist under X?" โ exploring a branch | browse with depth: 2 |
| "What does notation 73D82 mean?" | resolve with the notation |
| "What's related to this notation?" | browse โ shows children, cross-refs, path |
| "List all key variants of 25F23" | expand_keys |
| "Everything under 'the Crucifixion of Christ'" | search_prefix with 73D6 |
| "Find 'reading' within Virgin Mary subjects" | search with query: "reading", parentNotation: "11F" |
| "Which notations have artworks in a collection?" | search with collectionId (e.g. "rijksmuseum") |
| "Which notations have artworks at all (any collection)?" | search with onlyWithArtworks: true |
| "How many artworks depict X?" | find_artworks with notation(s) from a prior search |
| "Show me artworks about X" | Full workflow: search โ find_artworks โ search_artwork(iconclass: ...) on rijksmuseum-mcp+ |
| "Show me artworks of [a common animal]" | Start global (no parentNotation) โ the animal may not be in 25F*. See Workflow 3 โ Searching for a specific animal. |
Notation Syntax
Iconclass notations encode hierarchy left-to-right. Understanding the syntax helps you read results and construct queries.
Base notations use alphanumeric codes: 7 (Bible) โ 73 (New Testament) โ 73D (Passion of Christ) โ 73D6 (the Crucifixion of Christ) โ 73D64 (crucified Christ with particular persons under the cross) โ 73D641 (crucified Christ with Mary and John on either side; Holy Rood).
Named notations add a parenthesised qualifier for specific entities: 11H(FRANCIS) (St. Francis), 25F26(WOMBAT) (wombat). The name is part of the notation โ 11H(FRANCIS) and 11H(JEROME) are siblings under 11H(...) (male saints). Named notations for female saints use 11HH(...).
Key-expanded notations add modifiers in (+N) suffixes: 25F23(+46) means "beasts of prey, sleeping." Key codes are standardised across the system โ (+46) always means "sleeping" regardless of the base notation. But be careful: the (+4...) group concerns artistic production and works of art as objects (stages of creation, damage, restoration), not the depicted condition of things within a scene. 48C7323(+42) means "lute as a work of art being damaged," not "a lute with a broken string in a painting." This is a common misclassification trap.
When using expand_keys, pass the base notation โ 25F23, not 25F23(+46). Named notations like 25F23(LION) are not base notations either; use 25F23 to expand keys for all beasts of prey, lion included.
Labels Reflect Iconography, Not Modern Taxonomy
Iconclass was designed in the 1970sโ80s as an iconographic retrieval system โ a vocabulary for art subjects, not a scientific or scholarly taxonomy. Its category labels often encode pre-modern European perception of the subject matter: how artists and viewers grouped things visually, functionally, or symbolically, rather than how modern specialists classify them. This matters when reading results and presenting them to users.
Concrete cases:
25F26 "rodents" contains hares and rabbits (lagomorphs, split from rodents by Gidley in 1912) and even wombats (Australian marsupials). The category groups small-to-medium quadrupeds as pre-Linnaean bestiaries did, not by modern clade.
- The real salamander has no entry in the naturalistic tree at all. The only salamander notation is
25FF412 "salamander (fabulous animal); salamander as spirit of fire" โ in the fabulous tree. 25F5 amphibians has no (SALAMANDER) variant. A client looking for salamander images must use 25FF412 even when the painting shows an ordinary amphibian: the code is labelled "fabulous" but it is the only code the catalogue offers.
- Many common animals have no real-animal notation at all. Horse, goat, sheep, cattle, donkey, reindeer, and rooster are all absent from
25F*. They exist in the catalogue only through their functional roles โ husbandry (47I2*), transport and traction (46C13/14*), saint attributes (11H(GEORGE), 11H(ELOI), 11H(PETER)), mythology (25FF24(PEGASUS)), literature (82B(BAIARDO)), and the fabulous tree more broadly. 25F24 "hoofed animals" in particular contains only wild and exotic species (antelope, camel, giraffe, rhinoceros, zebra) โ the familiar European domesticated quadrupeds are elsewhere. This is not an accident; it reflects Iconclass's working definition of what counts as a "naturalistic animal picture."
- Real vipers and fishes known via the bestiary tradition (aspic, cerastes, remora, sea-dragon) appear only in
25FF* (fabulous), despite being real species. They entered the catalogue through their medieval literary identity rather than their zoology.
- Geographical and ethnographic labels (in branches like
32 and 47) often use historical exonyms, colonial-era region names, or broad continental groupings that would not pass muster in a contemporary atlas or ethnographic study.
- Religious and mythological branches classify figures by the hagiographic or literary tradition in which they were depicted, not by historical-critical scholarship โ apocryphal saints sit alongside canonical ones without distinction.
The practical implications:
- A label is an index term, not a definition.
25F26(WOMBAT) means "the notation we use to tag images of wombats," which Iconclass happens to have filed under its "rodents" heading. It does not assert that wombats are rodents.
- Handoff still works. The taxonomy quirks don't affect retrieval โ
search_artwork(iconclass: "25F26(WOMBAT)") is the correct way to ask a collection server for wombat images when that collection has tagged them. Notation codes are stable identifiers regardless of whether the label tree reflects current scholarship.
- Flag the mismatch when presenting results to users. If a user asks about rabbits and you return notations prefixed "rodents:", add a brief note that the Iconclass label reflects older classification, not modern taxonomy. Silently echoing the label can mislead users who read it as a scientific claim.
- Don't "correct" the notation. There is no alternative code to use โ
25F26(HARE) is the tagged notation, full stop. Work with it and annotate.
When in doubt, resolve the notation and check its hierarchy path โ the path shows you which pre-modern conceptual grouping Iconclass has placed the subject in, which is usually what explains a surprising label.
FTS Query Patterns
The keyword search (query) uses FTS5 across labels (13 languages) and keywords (11 languages). Understanding its behaviour avoids wasted tool calls.
Inflected forms often work because the Iconclass keyword data includes variants โ "crucified" finds "crucifixion" (675 matches). But spelling variants do not โ "odour" and "odor" are separate words and won't cross-match. When in doubt, try both spellings or fall back to semanticQuery.
Multi-word queries try phrase match first (adjacent words), then fall back to AND-ed individual terms if the phrase returns zero results. "Marriage at Cana" finds notations containing both "Marriage" and "Cana" even if they're not adjacent.
Single words are usually best. FTS matches whole words against the Iconclass vocabulary, so a single specific word ("salamander", "crucifixion", "lute") has the highest recall. Multi-word queries are useful when a single word is too broad โ "broken string" to distinguish from intact string instruments, or "Last Supper" to avoid matching other uses of "supper."
When FTS fails, switch to semantic search. If the exact vocabulary term is unknown โ or you're searching by concept rather than keyword โ use semanticQuery. It finds notations by meaning: "domestic animals" finds dogs, cats, horses even though none contain that exact phrase. Semantic search bridges the gap between your language and Iconclass's vocabulary.
Non-English queries work. FTS covers all 13 languages. Dutch "kruisiging", German "Kreuzigung", and French "crucifixion" all find the same notation.
Critical Parameter Distinctions
browse vs expand_keys for key variants
Both can show key-expanded variants (e.g. 25F23(+46) "beasts of prey, sleeping"), but they serve different purposes:
browse with includeKeys: true: quick preview of key variants alongside the entry's children, path, and cross-refs. Use for orientation โ "what modifiers exist for this notation?"
expand_keys: paginated list of all key variants with full metadata. Use when you need the complete inventory โ some base notations have 200+ variants and browse only shows the first 25.
When working with key expansions, remember that the (+4...) group is about artistic production (damage, restoration, stages of creation), not depicted object condition โ see Notation Syntax.
search with parentNotation vs search_prefix
Both restrict to a subtree, but they answer different questions:
search(query=..., parentNotation="11F"): keyword search within a subtree โ "find notations about 'reading' under Virgin Mary." Combines text relevance with hierarchical scoping.
search_prefix(notation="11F"): enumerate all notations starting with a prefix, ordered alphabetically. No text search โ pure hierarchy traversal. Use when you want the full inventory of a branch. Supports collectionId to filter to notations with artworks in a specific loaded collection.
If parentNotation returns zero results, the concept may exist in a different branch. Try removing the scope for a global search, or broadening to a parent prefix (e.g. "11" instead of "11F").
Key Workflows
1. Discover a Notation Code
Start with keyword search. If the term is unknown or the concept is atmospheric/interpretive, use semantic search.
# Known term
search(query: "crucifixion")
# -> 73D6 (rijksmuseum) "the Crucifixion of Christ" [7 > 73 > 73D]
# Unknown vocabulary โ concept search
search(semanticQuery: "domestic animals")
# -> 34B1 "pets, domestic animals" [3 > 34 > 34B]
2. Explore a Hierarchy Branch
Use browse with depth: 2 for narrative exploration โ it returns the entry, its children, and their children in one call, avoiding the sequential browse-per-child pattern that would cost 8+ tool calls on a branch like St. Francis.
browse(notation: "73D6", depth: 2)
# -> 73D6 "the crucifixion of Christ: Christ's death on the cross; Golgotha"
# 73D64 "crucified Christ, with particular persons under the cross"
# 73D641 "crucified Christ with Mary and John on either side; Holy Rood"
# 73D642 ...
# 73D65 ...
# ...
Wide branches (e.g. male saints by name under 11H(...), 183 children) are capped at 25 children per parent to protect your context window. The response shows totalChildren so you know when truncation occurred.
Use depth: 3 only on narrow branches where you can see the full structure. For wide branches like 11H(...), browse at depth 1 first to see the top-level names, then drill into specific children at depth 2.
3. Cross-Branch Discovery
The same concept can appear in multiple Iconclass branches because the system classifies by context, not just identity. A dog might be:
34B11 โ pets, domestic animals: dog (zoological classification)
11H(BERNARD) โ St. Bernard with a white dog among his possible attributes (saint iconography)
25FF21 โ fabulous animals ~ domestic animals (fabulous-animal context)
Use keyword or semantic search to discover all branches, then resolve to compare them side by side:
search(query: "dog", maxResults: 25)
# -> multiple notations across branches 11, 25, 34, 46...
resolve(notation: ["34B11", "11H(BERNARD)", "25FF21"])
# -> full metadata for comparison โ paths, keywords, collection presence
Searching for a specific animal โ the animal tree is a cultural index, not a biological one
Cross-branch presence is the rule for animals, not the exception. Iconclass indexes animals by their culturally dominant role, and for many common species the 25F* "real-animal tree" notation you would expect simply does not exist. A client asking "show me artworks depicting horses" cannot start with 25F24 โ there is no 25F24(HORSE). Real horses live only in transport, saint attributes, mythology, and literature.
Three patterns to recognise:
- Domesticated animals are usually outside
25F*. Horse, goat, sheep, cattle, donkey, reindeer, and rooster have no entries under real animals. Look in 47I2* husbandry, 46C13/14* transport and traction, 11H(*) saint attributes, 25FF* fabulous variants, 9X classical mythology, 82B(*) literary characters.
- Bestiary-famous real animals may live only in
25FF*. Salamander, aspic, cerastes (both real vipers), remora, sea-dragon โ all real species โ appear only in the fabulous tree. Do not skip 25FF* just because the target animal is biologically real.
- Wild/exotic animals are reliably in
25F*. Antelope, bison, camel, giraffe, rhinoceros, zebra, wombat, elk, oryx, elephant, monkey, most birds and invertebrates โ these are in the naturalistic tree as expected. 25F3 birds is the cleanest branch in the whole catalogue.
Search strategy for a specific animal:
- Start global, not scoped.
search(query: "animal-name", maxResults: 25) โ do not pass parentNotation: "25F". A scoped search hides the cross-branch reality.
- Read the branches, not just the labels. The hierarchy path on each result tells you which cultural role the notation captures. For horse you will see
46C13* (transport), 11H(GEORGE) (saint), 25FF24(PEGASUS) (myth), etc.
- Use
find_artworks counts to choose. When an animal appears in several branches, a collection usually tags most artworks with one canonical notation. The one with the strongest coverage in your target collection is the best handoff code. A 25F* notation with no target-collection counts is a strong signal that the collection may use a different branch's code for that animal.
- For compound queries, combine across branches. "Artworks of St. George with a horse" is
search_artwork(iconclass: ["11H(GEORGE)", ...]) where the second code is whichever transport/saint horse notation actually has coverage โ not 25F24(HORSE), which does not exist.
When presenting results to users, flag the pattern honestly. A user who asked for horse images should be told the animal tree doesn't cover horses and that the catalogue indexes them by role; silently returning only 11H(GEORGE) results without that context can mislead.
4. Scoped Search Within a Subtree
When you know the branch but need to find a specific concept within it, use parentNotation to avoid drowning in global results:
# "reading" within New Testament (73)
search(query: "reading", parentNotation: "73")
# -> 73A51 "Mary alone reading", 73B732 "Mary teaches the Christ-child to read"
# "crown" within saints (11H)
search(query: "crown", parentNotation: "11H")
# -> notations about crowned saints, martyrs' crowns, etc.
If a scoped search returns zero results, the concept may live in a different branch than expected. "reading" under 11F (Virgin Mary) returns nothing โ those notations are under 73 (New Testament narrative). Remove the scope and search globally to find where the concept actually lives.
5. Querying with Multiple Codes
Complex artworks carry codes from multiple branches because a single image contains overlapping subjects: a scene, its actors, their attributes, symbolic objects, the setting. When searching for artworks of a specific subject, you can exploit this by combining codes from different branches. A search for artworks of St. Francis preaching to birds might use:
# Scene
search(query: "Francis", parentNotation: "11H")
# -> 11H(FRANCIS)32 "St. Francis preaching to the birds"
# Animals
search(query: "birds", parentNotation: "25F")
# -> 25F3 "birds"
# Setting
browse(notation: "25H1", depth: 2)
# -> landscape subcategories
When passed to rijksmuseum-mcp+, these codes AND-combine โ search_artwork(iconclass: ["11H(FRANCIS)32", "25F3"]) finds artworks tagged with both codes. This is how you express compound iconographic queries.
When no notation exactly captures a nuanced concept (e.g., a broken lute string as a vanitas symbol), use the closest codes (11R7 vanitas symbols + 48C7323 lute) and note the interpretive nuance separately. Verify the key's actual meaning before using key expansions (see Notation Syntax above).
6. Check Artwork Counts
After discovering notation codes via search or browse, use find_artworks to check artwork counts in the loaded collection overlays. This answers "how many artworks in the available collections use this subject?" โ essential for gauging a notation's practical usefulness before handing it to rijksmuseum-mcp+ or another collection server.
# Single notation
find_artworks(notation: "73D6")
# -> 73D6 "the crucifixion of Christ: Christ's death on the cross; Golgotha"
# Rijksmuseum, Amsterdam: matching artworks
# Batch: compare counts across multiple notations (up to 25)
find_artworks(notation: ["34B11", "25F23", "11H(FRANCIS)32"])
# -> per-notation breakdown with per-collection artwork counts
When to use find_artworks vs collections:
collections (returned by search, browse, resolve) gives a quick signal โ "does any loaded collection have artworks for this code?" Useful for filtering during discovery.
find_artworks gives exact artwork counts by collection. Use it when you need to know how many artworks are tagged with a notation, or when comparing coverage across notations before handoff.
Practical patterns:
The lang parameter controls the language of notation labels in the response (default: "en"). Some collection overlays may include link-out URL templates; if a collection has no template, find_artworks returns counts without a URL. find_artworks also returns a ready-to-use artResearchUrl for each notation โ a PHAROS-consortium aggregator link covering that notation and its narrower/key-expanded descendants โ offer it to the user as a general web fallback.
7. Cross-Server Handoff to rijksmuseum-mcp+
This is the terminal step of most workflows. Once you have notation codes with confirmed artwork counts, pass them directly to rijksmuseum-mcp+:
# Step 1: discover the code
search(query: "Jerome")
# -> 11H(JEROME) (rijksmuseum) "the monk and hermit Jerome (Hieronymus)"
# Step 2: check artwork counts
find_artworks(notation: "11H(JEROME)")
# -> per-collection artwork counts
# Step 3: hand off to rijksmuseum-mcp+
search_artwork(iconclass: ["11H(JEROME)"])
# -> Rijksmuseum artworks depicting St. Jerome
Combining iconclass with other filters on rijksmuseum-mcp+:
# Paintings only
search_artwork(iconclass: ["11H(JEROME)"], type: "painting")
# By a specific artist
search_artwork(iconclass: ["11H(JEROME)"], creator: "Rembrandt van Rijn")
# Multiple subjects (AND)
search_artwork(iconclass: ["11H(JEROME)", "25F23"])
# -> artworks tagged with BOTH St. Jerome AND beasts of prey
When rijksmuseum-mcp+ is available and the user's goal involves seeing artworks, the natural next step is to call search_artwork with the notation codes you've found. The two servers are companions โ notation codes flow from this server to that one directly.
When rijksmuseum-mcp+ is not available
If search_artwork is not available (the server is not connected), present the notation codes you've found with their collection coverage, artwork counts, and hierarchy context โ this is more useful than bare codes alone. If find_artworks returns link-out URLs for a loaded collection, include them; otherwise, offer the artResearchUrl field returned by find_artworks as a broader web fallback.
To enable direct artwork search in future conversations, the user can install the companion server rijksmuseum-mcp+ from github.com/kintopp/rijksmuseum-mcp-plus.
Known Limitations
| Issue | Workaround |
|---|
| British/American spelling โ "odour" vs "odor" | Try both spellings. semanticQuery handles this automatically. |
| Wide branches truncated at 25 per parent | Use search_prefix to enumerate all notations, or paginate with offset. |
| Resolve batch limit of 25 | Use search for discovery, resolve only for the 3โ5 notations you need full metadata on. |
parentNotation returns 0 but concept exists | The concept may live in a different branch. Remove the scope and search globally. |
| Key expansion labels can mislead | Verify a key's meaning in context. The (+4...) group is about artistic production, not depicted object condition. See Notation Syntax. |
| Category labels reflect pre-modern iconography, not modern taxonomy | Treat labels as index terms, not scientific definitions. Flag mismatches to users (e.g. hares under "rodents"). See Labels Reflect Iconography, Not Modern Taxonomy. |
Common animals (horse, goat, rooster, salamander) have no notation in 25F* | Search globally, not scoped to 25F*. The animal's code is in husbandry, transport, saints, mythology, literature, or the fabulous tree. See Workflow 3 โ "Searching for a specific animal." |
find_artworks batch limit of 25 | Sufficient for most workflows โ you should have narrowed to a shortlist before calling. |
| Artwork-count overlays are collection-specific | Check the top-level collections field to see which overlays are loaded. Coverage changes when the sidecar database is updated. |
find_artworks returns "no collections" | The notation has no counts in the loaded overlays, or the input notation may not exist. Use resolve to verify uncertain codes, then try a parent or sibling notation. |
Output Conventions
- Show notation codes (e.g.
73D82) โ they are the stable identifiers across both servers and the handoff format to rijksmuseum-mcp+
- Include artwork counts when available โ they signal whether a code is useful for artwork retrieval
- Show hierarchy paths (e.g.
7 > 73 > 73D > 73D8) โ they help the user understand where a notation sits in the classification system
- When presenting multiple notations, lead with highest artwork counts โ these are the most practically useful codes
- Distinguish between what was found via keyword search vs semantic search โ the confidence levels differ
- When the user's goal involves artworks, the workflow is most helpful when it reaches actual artworks on rijksmuseum-mcp+ rather than ending at notation codes