Skip to content

Fix #1220: support media lookup by filename or URL in MCP abilities - #1223

Closed
faisalahammad wants to merge 5 commits into
wp-media:developfrom
faisalahammad:fix/1220-mcp-media-identifier
Closed

Fix #1220: support media lookup by filename or URL in MCP abilities#1223
faisalahammad wants to merge 5 commits into
wp-media:developfrom
faisalahammad:fix/1220-mcp-media-identifier

Conversation

@faisalahammad

Copy link
Copy Markdown
Contributor

Description

Fixes #1220

The three MCP media actions (imagify/optimize-media, imagify/restore-media, imagify/get-media-status) required a numeric media_id. Callers usually know an image by its filename or URL, so this adds two optional inputs, media_filename and media_url. A new MediaResolver helper turns any of the three identifiers into a single attachment ID. When a filename matches more than one attachment, the action returns a clear error asking for media_id.

Type of change

  • New feature (non-breaking change which adds functionality).

Detailed scenario

What was tested

Automated unit tests cover the resolver and all three abilities. The resolver has 14 tests (45 assertions) covering numeric media_id, URL resolution, filename basename match, ambiguous match, no match, and missing identifier. Each ability's execute gained tests for the filename path, the ambiguity error, and the missing-identifier error. Integration tests assert the new schema fields register on all three abilities. Static analysis (phpstan) is clean on the changed files and phpcs passes on the changed files.

How to test

  1. Install the plugin and connect a valid Imagify API key.
  2. Open the MCP server and call imagify/optimize-media with media_filename set to a file in the Media Library (for example hero.jpg).
  3. Repeat with media_url set to the attachment URL.
  4. Confirm both resolve to the same image as passing media_id.
  5. Call the same action with a filename that exists more than once in the library and confirm it returns an error that names the ambiguity.
  6. Call with no identifier at all and confirm it returns a clear error.

Result: media resolves by filename or URL, and missing or ambiguous input fails with an explicit message.

Affected Features & Quality Assurance Scope

The three MCP media abilities are extended with new optional inputs. Existing media_id behavior is unchanged. The Media Library upload flow and manual optimization are not touched.

Technical description

Documentation

classes/Abilities/MediaResolver.php is a static helper with one method, resolve_id( array $args ). It checks media_id first, then media_url via attachment_url_to_postid(), then media_filename via a WP_Query on the _wp_attached_file meta with a basename match. The filename query is capped at five results so the ambiguity check stays bounded. First match wins; more than one match returns a WP_Error with a message asking for media_id. Each ability calls the resolver at the top of execute() and folds the resolved ID into the existing flow. docs/api/mcp.md documents the new inputs and the resolution rule.

New dependencies

None. Uses WordPress core functions (attachment_url_to_postid, WP_Query) already available.

Risks

The filename query uses a LIKE on postmeta, which is an index hit. It runs only on a one-shot MCP call and is capped at five results, so the cost is bounded. Removing media_id from the required list means a caller can send no identifier; the resolver returns a clear missing-identifier error instead of failing silently.

Mandatory Checklist

Code validation

  • I validated all the Acceptance Criteria. If possible, provide screenshots or videos.
  • I triggered all changed lines of code at least once without new errors/warnings/notices.
  • I implemented built-in tests to cover the new/changed code.

Code style

  • I wrote a self-explanatory code about what it does.
  • I protected entry points against unexpected inputs.
  • I did not introduce unnecessary complexity.
  • Output messages (errors, notices, logs) are explicit enough for users to understand the issue and are actionnable.

Unticked items justification

Manual validation was limited to automated tests because the MCP server needs a running WordPress site with a valid API key. The resolver and each ability path are covered by unit tests, and schema registration is covered by integration tests.

Additional Checks

  • In the case of complex code, I wrote comments to explain it.
  • When possible, I prepared ways to observe the implemented system (logs, data, etc.)
  • I added error handling logic when using functions that could throw errors (HTTP/API request, filesystem, etc.)

When Imagify is installed via Composer as a dependency (e.g. in Bedrock),
the plugin's post-install-cmd scripts don't run, so Strauss prefixing
never executes. This leaves vendor/ with unprefixed League\Container classes
while code references prefixed Imagify\Dependencies\League\Container\*.

Fix: Add class_alias fallbacks in inc/main.php to map unprefixed classes
to prefixed namespace when needed. Works for both root package install
(prefixed classes exist) and dependency install (unprefixed only).

Fixes wp-media#1073
…lities

The three MCP media actions required a numeric media_id, but callers
usually know an image by its filename or URL. Add a MediaResolver that
resolves media_id, media_filename, or media_url to a single attachment
ID, with a clear error when the match is missing or ambiguous. media_id
is now optional in optimize-media, restore-media, and get-media-status.
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 17 complexity · 0 duplication

Metric Results
Complexity 17
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@Miraeld

Miraeld commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Thanks for taking this on @faisalahammad, and sorry for the slow reply.

I am going to close this one in favour of #1225, which takes the same approach — optional
media_filename / media_url inputs on the three media abilities, resolved by a shared helper. Your
framing of the problem was the right one and it shaped that PR, so credit where it is due.

Two things I could not carry over, for the record:

  1. inc/main.php. The use Imagify\Dependencies\League\Container\Container; import was removed
    and replaced with a class_alias fallback. That made imagify_init() fatal with
    Class "Container" not found, which is what turned every PHPUnit job on this PR red. It also is
    not related to Support media lookup by filename for MCP media actions #1220 — Strauss prefixing is handled by the build, so this looks like a workaround
    for a local composer install rather than something the repo needs.

  2. The filename lookup. _wp_attached_file LIKE %hero.jpg% also matches my-hero.jpg and
    hero.jpg.bak, so asking to optimize or restore hero.jpg could act on a different file. Closes #1220: support media lookup by filename or URL in MCP media abilities #1225
    keeps the LIKE to narrow candidates but then filters on an exact, case-insensitive basename()
    match, and there is a regression test pinning that specific case.

#1225 also drops the set_query_factory() test seam in favour of integration tests against a real
WP_Query, and resolves next-gen/thumbnail URLs (hero-300x200.jpg.webp) back to the original
attachment.

Really do appreciate the contribution — please keep them coming.

@Miraeld Miraeld closed this Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support media lookup by filename for MCP media actions

2 participants