MCP server exposing the Sony camera (so-dsc) as tools. Stdio MCP server that proxies to an existing Flask API for camera control, liveview, shooting, and content browsing.
Strong tool naming (verb_noun pattern throughout) and comprehensive descriptions (avg 180 chars, well within 10-1024 range). All 23 tools have clear, actionable docstrings explaining WHAT, WHEN, and prerequisites. Input schemas present for all tools with proper type definitions. However, output schemas are undocumented (tools return JSON strings or Images without declared field structure), and error handling lacks recovery guidance. No tool annotations (readOnlyHint/destructiveHint/idempotentHint) despite clear risk levels. Parameter descriptions are solid but some lack format/range constraints (e.g., set_iso accepts 'string' with no enum of valid values, set_shutter accepts free-form strings like '1/250' without validation hints).
Download a camera-side picture (full resolution from SD card) to the host's downloads/ directory. Pass the `originalUrl` from a list_camera_pictures item. Returns the saved local path and size. Use list_saved_pictures + get_saved_picture afterwards to read it back as an Image.
Return the latest live preview JPEG (~640x424, ~35KB on RX100M5A). Use this to *see* what the camera is currently aimed at — e.g. to judge composition or exposure before triggering a shot.
Fetch a saved picture by name (from list_saved_pictures) as an Image. Useful for the AI to review what was just shot.
Report current camera state: liveview running, last frame age, mode, available APIs, battery, recording status. Use this first when planning a shoot to know what controls are exposed.
Half-press (or release) the shutter button. Use on=True to make the camera focus at the body's currently-selected Focus Area, on=False to release. Useful as a "lock focus" before take_picture in tricky AF situations. Note: setTouchAFPosition is *not* supported on RX100M5A Smart Remote Control v2.1.7 — AF *position* is set on the camera body.
Output schemas undocumented. Tools return JSON strings or Image objects without declaring field structure (e.g., get_status returns JSON but no schema for status object fields, list_camera_pictures returns JSON without documenting 'originalUrl', 'thumbnailUrl', 'largeUrl' structure). LLMs cannot plan downstream calls or extract data reliably.
Free-form string parameters lack validation constraints. set_iso, set_shutter, set_fnumber accept arbitrary strings without enums or format hints. Descriptions mention examples ('AUTO', '100', '1/250') but no formal constraints. LLMs will hallucinate invalid values.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 58 | 2026-07-28+ | v2 |
List pictures stored on the camera SD card. Requires the camera body to be in **Send-to-Smartphone mode** (avContent service must be advertised). If the response contains a `note` saying avContent isn't available, ask the user to switch the in-camera app on the camera body to 'スマートフォンに送る', then call refresh_services and retry. Each item has an `originalUrl` that can be passed to download_camera_picture for full-resolution download, plus a `thumbnailUrl` and `largeUrl` for previews.
List pictures saved on the host (downloads/ directory). These are postviews from take_picture or burst, plus any manually downloaded originals via download_camera_picture.
Force a full reconnect to the camera. Use after a power-cycle or when get_status reports stale data (idle_seconds growing, frames not advancing). Idempotent.
Re-fetch the camera's DD.xml service list. Lightweight — does NOT tear down liveview. Call this when the user has switched in-camera apps on the camera body (Smart Remote ↔ Send to Smartphone). After a switch to Send to Smartphone, `avContent` appears and the list_camera_pictures / download_camera_picture tools start working; after a switch back, the `camera` service comes back and shooting tools work again.
Exposure compensation in 1/3 EV steps (typical range: -9 to +9, = -3.0 to +3.0 EV).
Set aperture (f-number) as a string like "5.6". Only honored in Aperture-priority or Manual mode.
Set ISO. Pass a string the camera advertises — typically "AUTO", "100", "200", ..., "12800". Use get_status → available_apis + getEvent state to confirm what the camera will accept.
Set shutter speed. Strings like "1/250", "1/4", "2", "BULB".
Switch white balance to Auto WB.
Lock white balance to a specific color temperature in kelvin (e.g. 5500 for daylight, 3200 for tungsten). Camera typically accepts multiples of 100 in 2500..9900.
Open the shutter for bulb exposure. Camera must be in Manual exposure mode with shutter speed = "BULB". Pair with stop_bulb.
Start continuous (burst) shooting. Camera must already be in still shoot mode with continuous drive set on the body. Stop with stop_burst. Returns immediately while the camera keeps shooting.
Start recording a movie to the camera's SD card (NOT to the host). Requires the camera dial to be on the movie position on RX100M5A — `setShootMode` is not exposed in Smart Remote, so the physical dial controls this. Once started, get_status → event.cameraStatus.cameraStatus reports "MovieRecording". Pair with stop_movie_rec. The full movie file is reachable later via Send-to-Smartphone mode (UPnP) or a direct SD-card read.
Close the bulb shutter.
Stop a running burst. Returns the list of postview URLs (one per frame the camera captured). Pull individual ones via get_liveview_frame won't work — use the URLs as-is or wait and use list_saved_pictures after the camera has finished writing them.
Stop in-progress movie recording. Returns a postview URL (small JPEG thumbnail of the just-finished clip). The actual movie file stays on the camera SD card.
Trigger the shutter and return the postview JPEG (down-sampled to ~1616x1080). The full-resolution original is kept on the camera SD card and is reachable via the in-camera "Send to Smartphone" mode if you need it later. save=True (default): the postview is also saved on the host under downloads/. False: only return the image, don't persist.
Zoom the lens. direction: "in" (telephoto) or "out" (wide). movement: "1shot" (one click), "start" (continuous, hold until "stop"), "stop" (release continuous zoom).
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk levels. Tools marked IRREVERSIBLE (take_picture, start_burst, start_bulb, start_movie_rec) and WRITE (reconnect, refresh_services, etc.) lack formal annotations. Agents cannot distinguish safe reads from destructive writes.
Error handling lacks recovery guidance. No tool documents what errors are retryable, user-fixable, or fatal. Descriptions mention prerequisites (e.g., 'avContent service must be advertised') but no error responses guide the agent on what to do if missing. Agents will retry blindly or give up.
Pagination not documented for list_camera_pictures. Tool accepts offset/count but no response schema documents total count or next_cursor. Large result sets could exhaust context without clear pagination semantics.