MCP media_import: test the paths schema and param mapping; update docs/agents.md (#499)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8454634fb8
commit
e0d2c9c73b
|
|
@ -151,6 +151,18 @@ pub struct MediaImportParams {
|
|||
pub image_sequence: Option<bool>,
|
||||
}
|
||||
|
||||
/// `file.import` params for a `media_import` call.
|
||||
fn media_import_params(p: MediaImportParams) -> Value {
|
||||
let mut params = json!({"paths": p.paths});
|
||||
if let Some(bin) = p.bin {
|
||||
params["bin"] = json!(bin);
|
||||
}
|
||||
if let Some(seq) = p.image_sequence {
|
||||
params["imageSequence"] = json!(seq);
|
||||
}
|
||||
params
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, JsonSchema)]
|
||||
pub struct ElementsParams {
|
||||
/// Only element ids starting with this prefix (e.g. `timeline.clip.`).
|
||||
|
|
@ -394,14 +406,7 @@ impl FilmcraftMcp {
|
|||
annotations(read_only_hint = false, destructive_hint = false, idempotent_hint = false, open_world_hint = false)
|
||||
)]
|
||||
async fn media_import(&self, Parameters(p): Parameters<MediaImportParams>) -> Result<CallToolResult, McpError> {
|
||||
let mut params = json!({"paths": p.paths});
|
||||
if let Some(bin) = p.bin {
|
||||
params["bin"] = json!(bin);
|
||||
}
|
||||
if let Some(seq) = p.image_sequence {
|
||||
params["imageSequence"] = json!(seq);
|
||||
}
|
||||
wrap(self.run("file.import", params).await)
|
||||
wrap(self.run("file.import", media_import_params(p)).await)
|
||||
}
|
||||
|
||||
#[tool(
|
||||
|
|
@ -753,6 +758,21 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// #499: `media_import` takes `paths` (a required array), and forwards `bin` / `image_sequence` to `file.import`.
|
||||
#[test]
|
||||
fn media_import_schema_and_params() {
|
||||
let m = FilmcraftMcp::headless(Session::default());
|
||||
let def = m.tool_router.get("media_import").unwrap();
|
||||
let schema = Value::Object((*def.input_schema).clone());
|
||||
assert_eq!(schema["properties"]["paths"]["type"], "array", "{schema}");
|
||||
assert!(schema["required"].as_array().unwrap().iter().any(|r| r == "paths"), "{schema}");
|
||||
let p: MediaImportParams = serde_json::from_value(json!({"paths": ["/a.png"], "bin": 7, "image_sequence": true})).unwrap();
|
||||
assert_eq!(media_import_params(p), json!({"paths": ["/a.png"], "bin": 7, "imageSequence": true}));
|
||||
let p: MediaImportParams = serde_json::from_value(json!({"paths": ["/a.wav"]})).unwrap();
|
||||
assert_eq!(media_import_params(p), json!({"paths": ["/a.wav"]}));
|
||||
assert!(serde_json::from_value::<MediaImportParams>(json!({"text": "/a.wav"})).is_err());
|
||||
}
|
||||
|
||||
fn demo() -> Session {
|
||||
let mut s = Session::default();
|
||||
s.execute("file.openDemoProject", json!({})).unwrap();
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ claude mcp add filmcraft -- filmcraft-cli mcp
|
|||
| `render_preview` | both | same as `render_frame` |
|
||||
| `project_inspect` | both | bins and items with ids, types, durations; active sequence |
|
||||
| `sequence_inspect` | both | the active sequence: tracks, clips (`start` / `end` and `sourceIn` / `sourceOut` in ticks, frames, `speed`, `reverse`: the clip plays its `sourceIn` to `sourceOut` stretch backward, `gainDb`), effects, transitions, markers (name and `comment`), playhead, selection |
|
||||
| `media_import` | both | import files by absolute path (`text`, one path per line) |
|
||||
| `media_import` | both | import files by absolute path (`paths`, an array; optional `bin`, `image_sequence`) |
|
||||
| `render_frame` | both | PNG of the program frame at `seconds` (headless renders; bridge screenshots the Program monitor). Read-only: the playhead and selection are left as they were |
|
||||
| `ui_inspect` | bridge | UI state: tool, workspace, panels, zoom, playback, fps |
|
||||
| `ui_elements` | bridge | on-screen interactive elements with id, label and rect (`prefix` filter) |
|
||||
|
|
|
|||
Loading…
Reference in New Issue