Add immich.search.ocr tool for Immich 2.2+ OCR text search#7
Add immich.search.ocr tool for Immich 2.2+ OCR text search#7benjaminfrombe wants to merge 2 commits into
Conversation
Exposes the new OCR text-in-image filter that Immich 2.2 added to the
/api/search/smart endpoint as a dedicated MCP tool, so the model can
discover OCR search as a distinct capability from CLIP semantic search.
- Add Ocr property to SmartSearchRequest (maps to the server-side
BaseSearchSchema.ocr string field).
- Make Query nullable so the serializer omits it when only OCR is set
(DefaultIgnoreCondition = WhenWritingNull).
- New SearchTools.OcrSearch tool with the same filter set as SmartSearch
(paging, type, dates, location, camera, persons).
- Tests: verify payload contains the ocr field and not query; verify
empty-text validation error.
Verified against a live Immich v2.7.5 server that {\"ocr\":\"...\"} on
/api/search/smart is the correct shape.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
The smart endpoint requires a `query` (CLIP) or `queryAssetId`, so passing
only `ocr` returns 400 "Either `query` or `queryAssetId` must be set".
The metadata endpoint accepts the same `ocr` filter (defined on
BaseSearchSchema) and has no such requirement. Verified live against
Immich v2.7.5: POST /api/search/metadata with {"ocr":"Portefeuille"}
returns matched assets without any query.
Move the Ocr property from SmartSearchRequest to MetadataSearchRequest
and revert SmartSearchRequest.Query to its original non-nullable
default. OcrSearch tool now calls SearchMetadataAsync with WithExif=true
to match the existing MetadataSearch behaviour.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
barryw
left a comment
There was a problem hiding this comment.
Thanks for this — nice clean feature addition that follows the existing patterns well.
A few things to address:
-
PR description is misleading — The body says this "hits
POST /api/search/smartwith theocrfilter", but the code actually routes throughSearchMetadataAsyncwhich hitsPOST /api/search/metadata. The code is correct (OCR is a metadata search field in Immich's API), but the description should be updated to avoid confusing future readers. -
Tool name should use underscores — The tool is registered as
immich.search.ocrwith dots. We're moving to underscores for Claude Desktop compatibility (see PR #8 / #5), so this should beimmich_search_ocr. Ideally this PR lands after the rename PR so everything stays consistent.
Code and tests look good otherwise — the validation, pagination, and response shaping all match the existing search tools.
Summary
immich.search.ocrthat hitsPOST /api/search/smartwith theocrfilter only (Immich 2.2+ OCR-in-image text index).Ocrfield onSmartSearchRequestand makesQuerynullable so the serializer omits it when only OCR is set.Why a separate tool
Keeps CLIP semantic search and OCR text search discoverable as distinct capabilities for the model. Both still go through
/api/search/smart, so the underlying client stays unchanged.Test plan
dotnet testpasses (36/36) on .NET 10 SDK{"ocr":"..."}is the correct payload shape (server-sideBaseSearchSchema.ocr: z.string().optional()).🤖 Generated with Claude Code