Skip to main content
Glama
EezyMAcc

Tattoo Feed

by EezyMAcc

Tattoo Feed

An MCP (Model Context Protocol) server that lets an LLM client (e.g. Claude Desktop) browse and curate posts from a hand-picked list of Instagram tattoo artists, via Instagram's Business Discovery API.

You point it at the artists you follow, and from your chat client you can pull a merged feed, discover one post at a time, bookmark the ones you like, and record notes about your taste so a future session remembers them.


Architecture

A deliberate two-layer split so a future GUI can reuse the logic without a rewrite:

  • core (src/tattoo_feed/ excluding server/) — all real logic: domain models, typed errors, JSON-file repositories, the Graph API client, image processing, and the services that orchestrate them. Knows nothing about MCP.

  • server (src/tattoo_feed/server/) — a thin FastMCP adapter that exposes core as MCP tools. Holds no business logic.

src/tattoo_feed/
  config.py            # lazy env config (IG_ACCESS_TOKEN, IG_USER_ID)
  models.py            # Pydantic v2 value objects
  errors.py            # typed error hierarchy
  imaging.py           # preview downscale + EXIF strip
  repositories/        # Repository ABC + JSON-file stores (atomic writes)
  graph/client.py      # Business Discovery client
  services/            # FeedService, ArtistService, InspirationService, PreferenceService
  server/app.py        # FastMCP tools + stdio entrypoint

Related MCP server: theo-van-gogh-mcp

Setup

Requirements: Python 3.12 and uv.

uv sync                       # create the venv and install pinned deps
cp .env.example .env          # then edit .env with your real credentials

Environment variables

Variable

Meaning

IG_ACCESS_TOKEN

A long-lived Instagram Graph API access token.

IG_USER_ID

The Instagram Business/Creator account id that owns the token.

TATTOO_FEED_DATA_DIR

Optional. Where the JSON stores live (default ./data).

.env is gitignored and must never be committed. Only .env.example (with placeholders) is in the repo.

Getting credentials is a one-time manual step on Meta's side: create a Meta app, connect an Instagram Business/Creator account, and mint a long-lived access token with Business Discovery permission. Both the querying account and the artists you look up must be professional accounts.


Running

Locally (stdio)

uv run python -m tattoo_feed.server.app

The server speaks the MCP stdio protocol, so you normally don't run it by hand — you register it with an MCP client. For Claude Desktop, add to its config:

{
  "mcpServers": {
    "tattoo-feed": {
      "command": "uv",
      "args": ["run", "python", "-m", "tattoo_feed.server.app"],
      "cwd": "/absolute/path/to/tattoo-feed",
      "env": {
        "IG_ACCESS_TOKEN": "your-token",
        "IG_USER_ID": "your-business-user-id"
      }
    }
  }
}

In Docker

A dev image (Dockerfile) bundles Python, uv, Node, and the toolchain. Build and open a shell with only this folder mounted to /workspace:

docker build -t tattoo-feed-dev .
./run-loop.sh        # mounts $PWD to /workspace, nothing else on your machine

Inside the container you have the full gate and can run the server exactly as above. The volume mount means anything written under /workspace lands back in this folder on your host.


The tools (MCP surface)

Tool

What it does

list_artists

List tracked artists.

add_artist(handle)

Validate the handle is a reachable professional account, then track it.

remove_artist(handle)

Stop tracking a handle.

get_feed(limit_per_artist=10)

Merged, newest-first feed. Metadata + permalinks only (no images).

next_inspiration()

One not-yet-seen post, marked seen, with a rendered preview image.

save_to_inspiration(post_id, notes=None)

Bookmark a post into the saved collection.

list_inspiration()

The saved collection, in save order.

remove_from_inspiration(post_id)

Remove a saved item.

reset_seen()

Clear the seen-set so inspiration starts fresh.

record_preference(observation)

Persist a taste note (propose-then-confirm, see below).

get_preference_summary()

All recorded preferences, to reload taste in a fresh session.


Design decisions

  • Two-layer split (core / server). MCP concepts never leak into core; business logic never leaks into server. This is what makes a phase-2 GUI a bolt-on rather than a rewrite.

  • JSON-file persistence behind a Repository interface. Simple, inspectable, and swappable. Writes are atomic (temp file + os.replace) so a crash mid-write can never corrupt a store.

  • Pydantic v2 frozen models for everything crossing a boundary, so external data is validated once and treated as immutable values thereafter.

  • Typed error hierarchy (TattooFeedError and friends). Every external failure maps to a typed error; nothing raises bare exceptions across a boundary, so the client always gets a readable message instead of a stack trace.

  • Lazy credentials. The server boots and lists its tools with no network and no real credentials; the token is only read when a tool actually calls Instagram.

  • Hermetic tests. All Instagram HTTP is mocked with respx; there are zero live network calls in the test suite. (mypy --strict, ruff, and a 90% coverage floor are enforced.)

  • Images only where they earn their context. Only next_inspiration returns a rendered image — the one-at-a-time conversational moment. get_feed stays metadata-only to keep the context window light.


Limitations (by design)

  • No video. Video posts are filtered out entirely at the Graph-client layer and never enter the feed, inspiration, or stores.

  • Carousels show the first image only. Multi-image expansion is out of scope.

  • Manual token refresh. There is no automatic token refresh. When the token expires, tools fail with a clear TokenExpiredError telling you to mint a new long-lived token and update IG_ACCESS_TOKEN.

  • Preview sizing is fixed. Previews are capped at 640px on the long edge, aspect ratio preserved, never upscaled, re-encoded as JPEG quality 85.

  • record_preference is propose-then-confirm. The tool persists whatever it is given; the discipline of proposing the observation to you and getting your explicit confirmation before the tool is called lives in the tool's description, so the calling assistant honours it.

  • No write access to Instagram. No posting, commenting, or messaging — this is strictly read-and-curate.


Posts belong to the artists who made them. This tool is for personal discovery and curation, not redistribution:

  • Previews are downscaled copies (≤640px, EXIF stripped), not full-resolution downloads.

  • Every image and saved item carries the artist's handle and the post's permalink, so attribution travels with the content and you can always open the original on Instagram.

  • Respect each artist's rights: don't repost or reuse their work without permission.


Development

The full gate (must all exit 0):

uv run ruff format --check .
uv run ruff check .
uv run mypy --strict src
uv run pytest -q --cov=src/tattoo_feed --cov-report=term-missing --cov-fail-under=90

License

MIT — see LICENSE.

Available Tools

11 tools
add_artistA

Track a new artist by Instagram handle.

The handle must resolve to a reachable professional (Business/Creator) account; otherwise a clear error is returned.

ParametersJSON Schema
NameRequiredDescriptionDefault
handleYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
handleYes
ig_user_idNo
added_atNo

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full behavioral burden. It discloses the prerequisite (professional account) and error behavior, but lacks details on side effects, permissions, or success return format. The output schema exists but is not described.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the action, and every sentence provides necessary information without fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has one parameter and an output schema, the description adequately covers the purpose, required condition, and error behavior. The rule states that if output schema exists, description need not explain return values, so completeness is high.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema description coverage at 0%, the parameter 'handle' has no schema-level description. The tool description adds meaning by stating it must be an Instagram handle for a professional account, which compensates well for the lack of schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action 'Track a new artist' with the method 'by Instagram handle', and it distinguishes from sibling tools like list_artists or remove_artist.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description specifies that the handle must resolve to a professional Business/Creator account, otherwise an error is returned. This provides clear usage conditions, though it does not explicitly list when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_feedA

Return recent posts from all tracked artists, newest first.

Returns metadata and permalinks only (no images) to keep context light.

ParametersJSON Schema
NameRequiredDescriptionDefault
limit_per_artistNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description discloses key behaviors: ordering (newest first) and content limitations (no images). No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences with the main purpose front-loaded and no unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While the output schema exists and the description covers return type, the lack of parameter documentation leaves a gap for a simple tool with one optional parameter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, 'limit_per_artist', is not described in the description. Schema coverage is 0%, so the description should compensate but fails to mention the parameter at all.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns recent posts from all tracked artists, newest first, distinguishing it from sibling tools that manage artists or preferences.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description specifies that only metadata and permalinks are returned (no images), guiding the agent on what to expect, though it does not explicitly state when to use it over alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_preference_summaryA

Return every recorded taste preference, so a fresh session can reload it.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, but description only states purpose and use case; lacks disclosure of authentication needs, rate limits, or other behavioral aspects beyond read-only nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, efficient, no redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple zero-parameter tool with output schema, the description adequately covers purpose and a use case; could clarify the term 'taste preference' but minor.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters in input schema, so baseline is 4; description does not need to add parameter info.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the action ('Return') and resource ('every recorded taste preference'), distinguishing it from sibling tools like record_preference which are writes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implied usage from 'so a fresh session can reload it' provides context, but no explicit guidance on when not to use or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_artistsA

List the tattoo artists currently being tracked.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It only states the function and does not disclose any behavioral traits such as read-only nature, pagination, order, or limits. The tool is simple, but transparency is minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no wasted words. It is front-loaded with the action and resource.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has zero parameters and an output schema exists, the description is adequate for simple listing. It could mention the return type but the output schema covers that. Slightly above average completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has no parameters, so schema description coverage is 100%. Per guidelines, baseline is 4. Description adds no parameter info but none is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('List') and the resource ('tattoo artists currently being tracked'). It distinguishes from sibling tools like add_artist and remove_artist by focusing on retrieval.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives (e.g., get_feed or search queries). The description simply states what it does without context on prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_inspirationA

List saved inspiration items, in the order they were saved.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. States ordering but lacks details on side effects, pagination, or data scope. Adequate but minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence with clear verb and context. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Simple tool with zero parameters and output schema present. Description provides essential function and ordering, sufficient given other schemas.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters, so schema coverage is 100%. Baseline set at 4; description adds no param info as none exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool lists saved inspiration items in saved order. Differentiates from siblings like 'list_artists' and 'get_feed' by specifying resource and ordering.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool vs alternatives like 'next_inspiration' or 'get_feed'. Simple listing assumed, but explicit context missing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

next_inspirationA

Show one not-yet-seen post for inspiration, then mark it seen.

Returns a rendered preview image (downscaled, EXIF-stripped) alongside the
artist handle and permalink. Calling repeatedly walks through unseen posts;
use reset_seen to start over.
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses that it marks the post as seen, returns a downscaled and EXIF-stripped preview, and that repeated calls walk through unseen posts. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences, front-loading the main action and purpose without extraneous information. Every sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters, an output schema, and sibling tools listed, the description fully covers the tool's behavior, return value, and relationship to reset_seen. Complete for the available information.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist, so the baseline is 4. The description adds no parameter-specific information, which is acceptable given zero parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool shows one not-yet-seen post, marks it seen, and returns a preview with artist handle and permalink. It distinguishes from siblings like reset_seen and list_inspiration by explaining the sequential browsing behavior.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly mentions using reset_seen to start over, and implies sequential use for walking through unseen posts. However, it does not comprehensively cover when not to use this tool or alternative contexts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

record_preferenceA

Record a note about the user's tattoo taste.

IMPORTANT: Before calling this tool, propose the observation to the user in
your own words and obtain their explicit confirmation. Only call it once the
user has agreed the observation is accurate. This captures taste (e.g.
"prefers fine-line botanical work"), which is distinct from saving a
specific image with save_to_inspiration.
ParametersJSON Schema
NameRequiredDescriptionDefault
observationYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
idNo
observationYes
created_atNo

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description must disclose behavior. It notes the tool requires user confirmation and captures taste vs images, but does not indicate whether previous preferences are overwritten or appended, or if there are limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, front-loaded with an important usage warning in bold, and every sentence adds value. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one parameter and an output schema (not shown), the description covers the key context: user confirmation need, distinction from image saving, and parameter example. Could mention return value behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter 'observation' has 0% schema description coverage, so the description adds value by providing an example ('prefers fine-line botanical work') and explaining it captures taste, which goes beyond the plain string type.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool records a note about the user's tattoo taste, with a specific example. It distinguishes from save_to_inspiration, though 'taste' could be more precisely defined.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs the agent to propose the observation to the user and obtain confirmation before calling. Also contrasts with save_to_inspiration, providing clear when-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remove_artistB

Stop tracking the artist with the given handle.

ParametersJSON Schema
NameRequiredDescriptionDefault
handleYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description must disclose all behavioral traits. It only says 'Stop tracking' without explaining side effects, permissions, or error conditions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, efficient, front-loaded with verb. Could add a bit more detail without losing conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Minimal but adequate for a simple tool with one parameter and output schema. Lacks context about idempotency or return behavior, but sufficient for basic selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the description merely mentions 'the given handle' without elaborating what a handle is or how it should be formatted. Does not compensate for schema gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the action ('Stop tracking') and resource ('artist with the given handle'), distinguishing it from sibling tools like 'add_artist'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives (e.g., when to remove vs. add or list artists). Agent must infer usage from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remove_from_inspirationB

Remove a saved inspiration item by post id.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description bears full responsibility for behavioral disclosure. It states 'Remove' but omits details such as permanence, error handling for invalid post_id, permissions required, or side effects. This is insufficient for a deletion operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence with no superfluous words. It delivers the core information efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple removal tool with one parameter, the description is minimally adequate. An output schema exists but is not described. The lack of behavioral details (e.g., confirmation, reversibility) leaves some gaps, but the core functionality is communicated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It only says 'by post id,' adding no meaning beyond the parameter name. It doesn't specify format, constraints, or behavior when post_id is missing or invalid.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Remove'), the resource ('saved inspiration item'), and the identifier ('by post id'). It effectively distinguishes the tool from siblings like 'save_to_inspiration' and 'list_inspiration'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. There is no mention of prerequisites, when not to use it, or trade-offs compared to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reset_seenA

Clear the seen-set so next_inspiration starts fresh.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It clearly states the tool mutates state by clearing a seen-set. For a zero-parameter tool, this is sufficient, though it could mention side effects like affecting other tools.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence with no wasted words. It is front-loaded with the action and purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity (0 params, no output schema details needed), the description is adequate. However, it could mention prerequisites or irreversible nature for completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has no parameters, and schema coverage is 100% (not applicable). Baseline for zero parameters is 4, and the description adds no additional parameter information, which is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Clear') and resource ('seen-set') and explicitly states the effect on 'next_inspiration'. It clearly distinguishes this tool from siblings like 'next_inspiration' and 'list_inspiration'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage (to start fresh with 'next_inspiration') but does not explicitly state when not to use it or mention alternatives. Context is clear but lacks exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_to_inspirationC

Bookmark a post (by id, from the current feed) into saved inspiration.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_idYes
notesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
post_idYes
artist_handleYes
image_urlYes
permalinkYes
timestampYes
notesNo
saved_atNo

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose behavioral traits. It mentions 'bookmark' implying a write operation, but does not state side effects, restrictions (e.g., duplicate handling), or whether notes are saved. The return value is not mentioned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, front-loaded with the action. However, it is too brief and omits important details, making it incomplete rather than concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having an output schema (as per context signals), the description lacks context on what the tool returns or any failure cases. For a simple tool with two parameters, more completeness is expected.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, yet the description adds no meaning for the parameters. 'post_id' and 'notes' are not explained beyond their names. The purpose of 'notes' and how 'post_id' relates to the feed are unclear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Bookmark'), the resource ('a post by id, from the current feed'), and the destination ('into saved inspiration'). It distinguishes the tool from related siblings like 'remove_from_inspiration' and 'list_inspiration'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the post must be from the current feed, but does not explicitly state when to use this tool versus alternatives like 'add_artist' or 'reset_seen'. No 'when not to use' guidance is provided.

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.

  1. 11 tool updatesv0.1.0
    • First observedadd_artist
    • First observedget_feed
    • First observedget_preference_summary
    • First observedlist_artists
    • First observedlist_inspiration
    • First observednext_inspiration
    • First observedrecord_preference
    • First observedremove_artist
    • First observedremove_from_inspiration
    • First observedreset_seen
    • First observedsave_to_inspiration

TDQS

A3.7/5.0

Scored across 11 tools

Disambiguation4/5

Tools generally have distinct purposes, but 'get_feed' and 'next_inspiration' both involve browsing posts from tracked artists, with 'next_inspiration' showing one unseen post at a time while 'get_feed' returns all recent posts. This could confuse an agent about which to use for browsing.

Naming Consistency5/5

All tool names follow a consistent verb_noun snake_case pattern, such as 'add_artist', 'list_inspiration', 'save_to_inspiration'. Even 'next_inspiration' with a non-standard verb is still in snake_case and fits the pattern.

Tool Count5/5

With 11 tools, the server provides a well-scoped set for tracking artists, managing inspiration, and recording preferences. Each tool has a clear role without redundancy or excessive overlap.

Completeness4/5

The tool set covers core workflows: artist management (add/list/remove), feed browsing, inspiration management, and preference recording. However, there is no tool to delete or update a recorded preference, which is a minor gap.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server that lets AI assistants manage an art catalogue — find paintings, post to social media, upload to galleries, schedule posts, and update metadata.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    A production-ready MCP server that gives an LLM agent standalone-equivalent control over a Mineflayer Minecraft bot — movement, mining, crafting, inventory, combat, containers, chat, and much more — exposed as 110 strongly-typed tools across 23 groups, with full bot lifecycle management and dual (poll + push) event streaming.
    50 npm
    2
    MIT