agentleFS
creative-namcreative-nam/media-gen-mcp/AGENTS.md

media-gen-mcp

AGENTS.md0 starsChanged 3 months agoUnlicenseView on GitHub

media-gen-mcp is a personal MCP server that exposes image and video generation tools to OpenCode. It wraps multiple AI media providers (Agnes AI, Google Gemini, more later) behind one interface, so choosing a provider is a config/runtime decision, not a code change per provider. Read ARCHITECTURE.md before making any structural change, and check progress-tracker.md for current status and past incidents before starting work. ARCHITECTURE.md governs what the system looks like, right now — provider interface, trust-level wrapping, job persistence, module…

  • Reads credentials
  • Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.

    Of the AGENTS.md files we read, the 31,542 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

  • In this repository4 other files it gives its agents.

The file

We split this AGENTS.md into the rules it gives an agent

10 rules. About 0 are common, 4 are distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Never log, print, or write API keys anywhere — including error messages and test fixtures.

    line 20
  2. Distinctive:

    Every provider, trusted or not, still gets the generic hardening: timeout, size cap, content-type check, safe filename generation.

    line 24
  3. Distinctive:

    Don't add a new dependency without flagging it first — this is a personal, free-tier project.

    line 25
  4. Distinctive:

    Don't guess at a provider's response shape.

    line 26
  5. Very specific:

    Never assume the MCP server's own process cwd is the user's project directory (see ARCHITECTURE.md for why) — always go through the …

    line 27
  6. Distinctive:

    Prefer small, focused unit tests with fixture data over broad integration tests.

    line 37
  7. Very specific:

    Run pytest before considering any milestone complete.

    line 41
  8. Very specific:

    When the user types /graphify, use the installed graphify skill or instructions before doing anything else.

    line 73
  9. Very specific:

    If graphify-out/wiki/index.md exists, use it for broad navigation instead of raw source browsing.

    line 78
  10. Very specific:

    Read graphify-out/GRAPH_REPORT.md only for broad architecture review or when query/path/explain do not surface enough context.

    line 79

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

AGENTS.md

Project

media-gen-mcp is a personal MCP server that exposes image and video generation tools to OpenCode. It wraps multiple AI media providers (Agnes AI, Google Gemini, more later) behind one interface, so choosing a provider is a config/runtime decision, not a code change per provider.

Read ARCHITECTURE.md before making any structural change, and check progress-tracker.md for current status and past incidents before starting work. ARCHITECTURE.md governs what the system looks like, right now — provider interface, trust-level wrapping, job persistence, module layout, tool schemas. progress-tracker.md governs what's been done, what's open, and what's already gone wrong once — read it so you don't re-discover a lesson the hard way. This file (AGENTS.md) governs how you work, independent of both.

Stack

  • Python, mcp SDK for the protocol layer
  • httpx for outbound HTTP calls (Agnes)
  • official google-genai SDK for Gemini
  • pydantic for response schema validation
  • python-dotenv for local secrets
  • pytest for tests

Hard rules

  • Never log, print, or write API keys anywhere — including error messages and test fixtures. Secrets live only in .env (gitignored), read via environment variables.
  • Machine-specific identifiers leak too — absolute paths under a user's home directory, usernames, local tool-install locations. These aren't secrets in the credential-unlocks-access sense, but they're a real leak class on their own, and they've been found twice in this project in files that don't look like "config" at a glance: a tool's cache directory (graphify-out/.graphify_python) and an agent hook-command file (.claude/settings.json). Don't assume machine paths only hide in obvious places.
  • When a leak-shaped problem is found once, don't just fix that instance — check whether the same pattern exists elsewhere before considering it closed. In this project the second machine-path leak was found by accident, unrelated to what was being worked on, and it prompted a full history sweep (git filter-repo) rather than a single-file fix. That full-sweep response is the default for this shape of discovery, not the exception.
  • Any provider marked untrusted in config.yaml goes through the full ResponseValidator path, no exceptions and no "temporarily skip it to get something working" — wire it through the validator from the start.
  • Every provider, trusted or not, still gets the generic hardening: timeout, size cap, content-type check, safe filename generation. This isn't optional just because a provider is marked trusted.
  • Don't add a new dependency without flagging it first — this is a personal, free-tier project; keep the footprint small.
  • Don't guess at a provider's response shape. If Agnes's actual response format for a given endpoint isn't confirmed by a real call, say so and ask, rather than inventing a plausible-looking schema.
  • Never assume the MCP server's own process cwd is the user's project directory (see ARCHITECTURE.md for why) — always go through the explicit project_dir argument.
  • For untrusted providers, _extract_image_bytes reads a raw dict, not the validated Pydantic model — validation and extraction are two separate passes over the same data, not one enforcing the other structurally. Every field extraction touches must be explicitly required and type-checked in that provider's schema (confirmed by audit for Agnes/Cloudflare/HuggingFace as of Milestone 5). If you add a new provider, add a field to extraction, or change a schema, re-verify this by hand — nothing enforces it automatically.

Testing

Manual testing alone doesn't count — every unit of work needs automated tests before it's considered done:

  • Raw provider parsing: for each provider, test the raw → validated path against a realistic valid response and several malformed ones (missing fields, wrong types, empty body, non-200 status, non-JSON body, oversized payload). Malformed input should fail predictably — a typed exception, never an unhandled crash.
  • Registry resolution: explicit provider argument wins; falls back to the configured default for that media type; raises a clear error when no configured provider supports the requested media type. Same pattern for accounts: explicit account wins, falls back to that provider's default account, clear error on an unknown account name.
  • Job store: a video job persists correctly across a save/reload cycle (simulates the server restarting mid-job).
  • Prefer small, focused unit tests with fixture data over broad integration tests. Don't call real provider APIs from the test suite — fixtures and mocks only, so tests are free and repeatable.
  • A test isn't done until you've confirmed it can fail. When a test or fixture changes to cover new/changed behavior, briefly revert the behavior it's meant to check (or comment out the relevant logic) and confirm the test actually fails. If it still passes, the assertion isn't testing what you think it is — fix it before moving on.
  • Watch for "checks the label, not the behavior." This exact shape of bug happened twice in this project: the trust-level wrapper regression (a test only confirmed each wrapper worked in isolation, never that trust_level actually changed behavior between them) and the account-resolution bug (a test resolved an account and only asserted the name echoed back, never that different credentials were actually used). Both times, the test read as reasonable and passed cleanly, and both times a real, functional bug hid behind it for a while. When two things are meant to behave differently (two trust levels, two accounts, two providers, anything with a distinguishing property that matters), the test needs to prove they actually diverge on the same input — not just that each one individually does something plausible.

Run pytest before considering any milestone complete.

Definition of done (per unit of work)

A unit of work isn't done until all of these are true:

  1. Code runs without errors for the intended path.
  2. A manual smoke test succeeds (real call, or a realistic mock if a real call would burn provider quota for no reason).
  3. Automated tests exist for the new logic and pass.
  4. It matches ARCHITECTURE.md. If you diverge from the design for a good reason, say what changed and why before moving on — don't drift silently.
  5. progress-tracker.md reflects it: the item has moved from In Progress to Completed, Next Up is updated if this changes what's next, and any incident is logged (per Build order / progress tracking below).
  6. The work is actually committed — not just described as done in a report. If a task's scope is narrower than everything currently uncommitted in the working tree (e.g. an unrelated prior fix is sitting there too), commit them separately, each with its own message, rather than lumping unrelated changes into one commit or leaving anything uncommitted "for later." A report that says something is done is not a substitute for it being committed.
  7. Every report states plainly whether it reflects completed, verified work or a plan awaiting approval — don't leave this implicit. This matters most exactly when a plan looks thorough and well-reasoned enough that "approved, proceed" and "done" start to feel interchangeable in conversation. They aren't. A plan that's been approved but not yet executed is not a completed unit of work, no matter how good the plan was.

Build order / progress tracking

Current status and the milestone/task list live in progress-tracker.md, not this file and not ARCHITECTURE.md. Don't start later work before the current task meets the definition of done above.

When you hit a real bug, a design assumption that turned out wrong, or anything that changed direction mid-task — log it in progress-tracker.md's Incidents section as you go, not just in your final report. If the incident led to an actual design change, the resulting current-state fact goes in ARCHITECTURE.md (terse, no story); the fuller story of what happened and why stays in progress-tracker.md. Don't duplicate the full narrative into both files.

Describe issues in progress-tracker.md self-containedly — never by a number or label from an external or gitignored document (e.g. a review tool's own findings file). That file may not be committed, may not persist, and won't mean anything to a future reader or session without it. State what the actual problem is, in this file, every time.

Commits

One commit per completed unit of work (or sub-step, if a unit is large enough to warrant breaking it up). Keep commits small enough to revert cleanly if something goes sideways.

When a task's instructions say to commit "everything else" or similar, that means everything belonging to that task — not everything currently sitting modified in the working tree. If an unrelated file is staged or modified for a different reason, flag it and ask rather than folding it into the current commit. (This happened once already: an unrelated AGENTS.md process-rule change got bundled into a registry-correctness commit. Left as-is that time since it was low-risk, but it shouldn't become the default interpretation.)

graphify

This project has a knowledge graph at graphify-out/ with god nodes, community structure, and cross-file relationships.

When the user types /graphify, use the installed graphify skill or instructions before doing anything else.

Rules:

  • For codebase questions, first run graphify query "<question>" when graphify-out/graph.json exists. Use graphify path "<A>" "<B>" for relationships and graphify explain "<concept>" for focused concepts. These return a scoped subgraph, usually much smaller than GRAPH_REPORT.md or raw grep output.
  • Dirty graphify-out/ files are expected after hooks or incremental updates; dirty graph files are not a reason to skip graphify. Only skip graphify if the task is about stale or incorrect graph output, or the user explicitly says not to use it.
  • If graphify-out/wiki/index.md exists, use it for broad navigation instead of raw source browsing.
  • Read graphify-out/GRAPH_REPORT.md only for broad architecture review or when query/path/explain do not surface enough context.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.