urma-mcp 0.1.0-rc.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +156 -288
  2. package/dist/src/acquisition/frames.d.ts +1 -1
  3. package/dist/src/acquisition/frames.js +113 -11
  4. package/dist/src/acquisition/frames.js.map +1 -1
  5. package/dist/src/acquisition/media.d.ts +2 -2
  6. package/dist/src/acquisition/media.js +632 -37
  7. package/dist/src/acquisition/media.js.map +1 -1
  8. package/dist/src/acquisition/overview.d.ts +1 -1
  9. package/dist/src/acquisition/singleflight.js +2 -0
  10. package/dist/src/acquisition/singleflight.js.map +1 -1
  11. package/dist/src/acquisition/storyboard.d.ts +1 -1
  12. package/dist/src/acquisition/transcript.d.ts +1 -1
  13. package/dist/src/acquisition/transcript.js +1 -1
  14. package/dist/src/acquisition/transcript.js.map +1 -1
  15. package/dist/src/acquisition/video-timing.d.ts +8 -4
  16. package/dist/src/acquisition/video-timing.js +60 -24
  17. package/dist/src/acquisition/video-timing.js.map +1 -1
  18. package/dist/src/cli/doctor.js +15 -43
  19. package/dist/src/cli/doctor.js.map +1 -1
  20. package/dist/src/core/diagnostics.d.ts +1 -2
  21. package/dist/src/core/diagnostics.js +1 -2
  22. package/dist/src/core/diagnostics.js.map +1 -1
  23. package/dist/src/core/frame-schedule.d.ts +2 -2
  24. package/dist/src/core/frame-schedule.js +2 -2
  25. package/dist/src/core/frame-schedule.js.map +1 -1
  26. package/dist/src/core/ids.d.ts +0 -1
  27. package/dist/src/core/ids.js +0 -1
  28. package/dist/src/core/ids.js.map +1 -1
  29. package/dist/src/distribution/download.js +63 -15
  30. package/dist/src/distribution/download.js.map +1 -1
  31. package/dist/src/distribution/host-registration.js +18 -1
  32. package/dist/src/distribution/host-registration.js.map +1 -1
  33. package/dist/src/distribution/installer.js +4 -4
  34. package/dist/src/distribution/installer.js.map +1 -1
  35. package/dist/src/distribution/integrity.d.ts +2 -2
  36. package/dist/src/distribution/integrity.js +2 -2
  37. package/dist/src/distribution/manifest.js +15 -13
  38. package/dist/src/distribution/manifest.js.map +1 -1
  39. package/dist/src/distribution/platform.js +43 -7
  40. package/dist/src/distribution/platform.js.map +1 -1
  41. package/dist/src/distribution/qualification.js +66 -11
  42. package/dist/src/distribution/qualification.js.map +1 -1
  43. package/dist/src/distribution/runtime.js +2 -1
  44. package/dist/src/distribution/runtime.js.map +1 -1
  45. package/dist/src/evidence/service.d.ts +1 -1
  46. package/dist/src/evidence/service.js +7 -4
  47. package/dist/src/evidence/service.js.map +1 -1
  48. package/dist/src/mcp/server.js +8 -1
  49. package/dist/src/mcp/server.js.map +1 -1
  50. package/dist/src/remote/egress.d.ts +1 -1
  51. package/dist/src/remote/egress.js +90 -14
  52. package/dist/src/remote/egress.js.map +1 -1
  53. package/dist/src/remote/formats.d.ts +2 -2
  54. package/dist/src/remote/formats.js +2 -2
  55. package/dist/src/remote/lease.d.ts +2 -3
  56. package/dist/src/remote/operation-context.d.ts +13 -0
  57. package/dist/src/remote/operation-context.js +40 -0
  58. package/dist/src/remote/operation-context.js.map +1 -0
  59. package/dist/src/remote/policy.d.ts +0 -1
  60. package/dist/src/remote/policy.js +0 -1
  61. package/dist/src/remote/policy.js.map +1 -1
  62. package/dist/src/remote/worker.d.ts +3 -14
  63. package/dist/src/remote/worker.js +2 -39
  64. package/dist/src/remote/worker.js.map +1 -1
  65. package/dist/src/sources/metadata.d.ts +1 -1
  66. package/dist/src/sources/metadata.js +1 -1
  67. package/dist/src/sources/metadata.js.map +1 -1
  68. package/dist/src/sources/resolver.d.ts +1 -1
  69. package/dist/src/sources/resolver.js +36 -16
  70. package/dist/src/sources/resolver.js.map +1 -1
  71. package/dist/src/sources/timeline.d.ts +1 -1
  72. package/dist/src/sources/timeline.js +1 -1
  73. package/dist/src/sources/timeline.js.map +1 -1
  74. package/dist/src/sources/types.d.ts +1 -1
  75. package/dist/src/store/schema.d.ts +1 -2
  76. package/dist/src/store/schema.js +1 -9
  77. package/dist/src/store/schema.js.map +1 -1
  78. package/dist/src/store/sqlite-store.d.ts +0 -2
  79. package/dist/src/store/sqlite-store.js +2 -35
  80. package/dist/src/store/sqlite-store.js.map +1 -1
  81. package/dist/src/store/store.d.ts +0 -2
  82. package/dist/src/subprocess/ffmpeg.d.ts +1 -1
  83. package/dist/src/subprocess/ffmpeg.js +10 -8
  84. package/dist/src/subprocess/ffmpeg.js.map +1 -1
  85. package/dist/src/subprocess/ffprobe.d.ts +1 -1
  86. package/dist/src/subprocess/ffprobe.js +5 -4
  87. package/dist/src/subprocess/ffprobe.js.map +1 -1
  88. package/dist/src/subprocess/remote-media.d.ts +8 -1
  89. package/dist/src/subprocess/remote-media.js +15 -1
  90. package/dist/src/subprocess/remote-media.js.map +1 -1
  91. package/dist/src/subprocess/runner.d.ts +3 -1
  92. package/dist/src/subprocess/runner.js +144 -103
  93. package/dist/src/subprocess/runner.js.map +1 -1
  94. package/dist/src/subprocess/ytdlp.d.ts +5 -3
  95. package/dist/src/subprocess/ytdlp.js +34 -6
  96. package/dist/src/subprocess/ytdlp.js.map +1 -1
  97. package/dist/src/version.d.ts +1 -0
  98. package/dist/src/version.js +2 -1
  99. package/dist/src/version.js.map +1 -1
  100. package/docs/ARCHITECTURE.md +176 -207
  101. package/docs/CONTRIBUTING.md +86 -76
  102. package/docs/EVIDENCE_MODEL.md +272 -215
  103. package/docs/PRODUCT_SCOPE.md +63 -109
  104. package/docs/SECURITY.md +120 -148
  105. package/launcher-v1.mjs +50 -4
  106. package/package.json +3 -3
package/README.md CHANGED
@@ -4,8 +4,6 @@
4
4
  <img src="https://raw.githubusercontent.com/sajidurdev/urma/main/assets/urma-banner.png" alt="Urma" width="100%" />
5
5
  <br /><br />
6
6
  <strong>Retrieve video captions and frames through MCP.</strong>
7
- <br />
8
- A stdio MCP server for bounded caption and visual evidence.
9
7
  <br /><br />
10
8
  <a href="#try-urma">Try Urma</a>
11
9
  ·
@@ -17,111 +15,88 @@
17
15
  ·
18
16
  <a href="#documentation">Documentation</a>
19
17
  <br /><br />
20
- <sub><code>urma-mcp</code> · MCP stdio · Node.js 24 LTS</sub>
18
+ <sub><code>urma-mcp</code> · MCP stdio · Node.js 22.16+ (22.x), 24.x, 26.x</sub>
21
19
  </div>
22
20
 
23
21
  <br />
24
22
 
25
- > **Release candidate:** Use the `rc` npm tag for RC testing.
23
+ Urma gives MCP clients access to captions and frames from public video URLs
24
+ and local video files. Search captions for a topic, browse a visual overview,
25
+ or retrieve frames at specific timestamps.
26
26
 
27
- Urma retrieves captions and sampled frames from videos with a known end time.
28
- Each result identifies its source snapshot and requested timestamps or range.
29
- The MCP host chooses what to retrieve and interprets the results.
30
-
31
- Urma runs locally and stores its cache on your filesystem. Remote videos still
32
- require network access. The host receives the requested evidence and controls
33
- how it is processed or sent to a model.
34
-
35
- The server uses MCP stdio. A host starts one Urma process for a session and
36
- owns its lifecycle. Urma does not run a daemon or expose an HTTP API.
27
+ Urma runs locally and keeps its cache on your filesystem. Your MCP client
28
+ starts the server over stdio and receives the requested text and images.
29
+ Remote videos require network access.
37
30
 
38
31
  ## Try Urma
39
32
 
40
- 1. Install the current RC with `npx -y urma-mcp@rc setup`.
41
- 2. [Register your MCP host](#register-a-generic-json-host), then restart it.
42
- 3. Give the host a video URL or allowed local path and ask it to locate a moment
43
- using captions or an overview.
44
- 4. Request exact frames around that moment to verify the visual claim.
33
+ 1. Install with `npx -y urma-mcp@latest setup`.
34
+ 2. [Connect your MCP client](#register-a-generic-json-host) and restart it.
35
+ 3. Give the client a video URL and a question about the video.
45
36
 
46
- Example prompt (replace `<video URL>` with your source):
37
+ For example, replace `<video URL>` in this prompt with a public product demo:
47
38
 
48
- > Inspect this product-demo video: `<video URL>`. Use captions to find where the presenter
49
- > mentions dark mode, use the overview to locate the settings screen, then
50
- > request exact frames around that timestamp to verify whether the dark-mode
51
- > toggle is enabled. If the returned frames do not show the toggle clearly,
52
- > say that the evidence is insufficient.
39
+ > In this demo, where does the presenter discuss dark mode, and is the toggle
40
+ > enabled on screen? `<video URL>`
53
41
 
54
- ## RC testing
55
-
56
- External testers can report installation, MCP-host, or source/provider problems
57
- through the [RC bug-report template](https://github.com/sajidurdev/urma/issues/new?template=bug-report.md).
58
- Include reproduction steps, your OS/architecture, Node.js and host versions,
59
- the installed Urma version, and expected versus actual behavior. For a
60
- source-specific issue, include a public URL or a description of a reproducible
61
- local video. Add relevant [doctor output](#cli-and-maintenance) if setup
62
- completed; otherwise include the setup error. Remove credentials, private
63
- URLs, and personal paths before posting logs.
42
+ For a local file, [allow its directory](#local-videos) first. See
43
+ [supported sources](docs/PRODUCT_SCOPE.md#source-admission) for provider and
44
+ format limitations.
64
45
 
65
46
  ## Install and connect a host
66
47
 
67
48
  ### Requirements
68
49
 
69
- - Native Node.js 24 LTS (`>=24 <25`).
70
- - A user-owned local filesystem for Urma's data root.
71
- - One of these runtime targets: Windows x64 or arm64, macOS x64 or arm64, or
72
- Linux x64 or arm64 with glibc.
50
+ - Native Node.js `>=22.16.0 <23`, `>=24.0.0 <25`, or `>=26.0.0 <27`.
51
+ - Windows x64/arm64, macOS x64/arm64, or Linux x64/arm64 with glibc.
52
+ - A user-owned local directory with at least 1 GiB free for the installation.
73
53
 
74
- Urma installs the pinned FFmpeg, ffprobe, and yt-dlp artifacts it needs. Do
75
- not install those tools separately for the packaged runtime. Urma does not
76
- install or manage Node.js.
54
+ Setup installs the required versions of FFmpeg, ffprobe, and yt-dlp. You only
55
+ need to install Node.js yourself.
77
56
 
78
57
  ### Install the runtime
79
58
 
80
- Run the npm bootstrap with Node.js 24:
81
-
82
59
  ```sh
83
- npx -y urma-mcp@rc setup
60
+ npx -y urma-mcp@latest setup
84
61
  ```
85
62
 
86
- The `rc` tag can move between candidates. To find its exact version without
87
- installing it:
63
+ Setup downloads and verifies the native tools, tests the installed server, and
64
+ prints the paths needed by your MCP client. Updates are installed separately
65
+ from the current runtime; a failed update leaves the current installation
66
+ selected.
67
+
68
+ For a repeatable installation, pin the package version:
88
69
 
89
70
  ```sh
90
- npm view urma-mcp dist-tags.rc
71
+ npx -y urma-mcp@0.1.0 setup
91
72
  ```
92
73
 
93
- For a repeatable install, replace `rc` in the setup command with the exact
94
- version returned above.
95
-
96
- Setup downloads and verifies the pinned native tools, checks that the installed
97
- runtime can serve MCP requests, and selects the new installation for future
98
- launches. Each installation is stored in a separate directory called a
99
- generation. If setup fails during an update, the previously active generation
100
- remains selected.
101
-
102
- The default data roots are:
74
+ Urma uses these default data directories:
103
75
 
104
- | Platform | Root |
76
+ | Platform | Directory |
105
77
  | --- | --- |
106
78
  | Windows | `%LOCALAPPDATA%\Urma` |
107
79
  | macOS | `~/Library/Application Support/Urma` |
108
80
  | Linux | `${XDG_DATA_HOME:-~/.local/share}/urma` |
109
81
 
110
- Use `--data-dir PATH` with `setup`, or set `URMA_DATA_DIR`, to select another
111
- user-owned local directory. Network and UNC paths are outside the supported
112
- installation boundary.
82
+ To choose another directory, pass `--data-dir PATH` to setup or set
83
+ `URMA_DATA_DIR`. The data directory must be on a user-owned local filesystem;
84
+ network and UNC locations are unsupported.
113
85
 
114
86
  ### Register a generic JSON host
115
87
 
116
- If the host uses the usual `mcpServers` JSON shape, setup can add the `urma`
117
- entry and preserve the other entries in the file:
88
+ For clients that use an `mcpServers` JSON configuration, setup can write the
89
+ entry for you:
118
90
 
119
91
  ```sh
120
- npx -y urma-mcp@rc setup --client generic --config "/absolute/path/to/mcp.json"
92
+ npx -y urma-mcp@latest setup --client generic --config "/absolute/path/to/mcp.json"
121
93
  ```
122
94
 
123
- The configuration file path must be absolute. The resulting entry has this
124
- shape; use the absolute paths printed by setup:
95
+ The configuration path must be absolute. Setup preserves unrelated entries.
96
+ If an `urma` entry already exists, setup updates `command`, `args`, and
97
+ `env.URMA_DATA_DIR`, leaving its other settings in place.
98
+
99
+ To configure a client manually, use the absolute paths printed by setup:
125
100
 
126
101
  ```json
127
102
  {
@@ -137,302 +112,195 @@ shape; use the absolute paths printed by setup:
137
112
  }
138
113
  ```
139
114
 
140
- On Windows, use the path escaping required by JSON. The `command` and the
141
- launcher path must be absolute. The launcher selects the installed generation
142
- and starts the local Urma runtime; use the npm package only for setup and
143
- version checks.
144
-
145
- Host registration and runtime installation are reported separately. A healthy
146
- runtime can be left installed when the configuration file cannot be written.
147
- After registration, restart the host and check that it lists the [five tools](#tools).
115
+ On Windows, escape backslashes in JSON, for example `C:\\Users\\you\\AppData\\Local\\Urma`.
116
+ For clients with a different configuration format, use the same Node
117
+ executable, launcher, and environment settings in a stdio server entry.
148
118
 
149
- For a host with a different configuration format, create the equivalent
150
- stdio entry with the same absolute Node executable, launcher path, and
151
- `URMA_DATA_DIR` value.
119
+ Restart the client after saving the configuration. It should list the five
120
+ tools below. If registration fails, setup reports that separately from the
121
+ runtime installation; you can still configure the installed server manually.
152
122
 
153
123
  ## Tools
154
124
 
155
- | Tool | Returns |
156
- | --- | --- |
157
- | `inspect_video` | A source snapshot and a new investigation reference. |
158
- | `search_transcript` | Literal matches in one selected caption track. |
159
- | `read_transcript` | Timestamped caption segments in a bounded interval. |
160
- | `get_overview` | A visual overview with up to 12 sampled cells. |
161
- | `get_frames` | Exact JPEG points, ordered sparse points, or a fixed-cadence schedule. |
162
-
163
- Call `inspect_video` first for a new source. It accepts an HTTP(S) URL, an
164
- allowed local path, or a previously returned `sourceRef`. It rejects sources
165
- that do not define one finite video timeline. The default `freshness: "reuse"`
166
- reuses a stored snapshot for a known remote URL or `sourceRef`. A local path
167
- is read again to check the video and sidecar content. Set `freshness: "refresh"`
168
- to resolve the source again. Every evidence request then uses the returned
169
- `investigationRef`.
170
-
171
- Use captions to locate likely time ranges, `get_overview` to locate visual
172
- moments, and `get_frames` to verify selected moments. These tools expose
173
- different observations:
174
-
175
- - Caption search and reads are limited to the selected source-provided track.
176
- - An overview is a sparse locator with up to 12 returned cells.
177
- - A frame burst is an ordered set of requested points.
178
- - A cadence request is a finite list of exact point requests. It reports each
179
- page slot as `success`, `error`, or `unfinished`.
180
-
181
- A source cache can be reused across investigations, but evidence presentation
182
- is recorded per investigation.
183
-
184
- ### Source and caption inputs
185
-
186
- Urma accepts:
187
-
188
- - A generic HTTP(S) video URL admitted by the remote source policy.
189
- - A supported single-video YouTube URL.
190
- - A local video path under a root listed in `URMA_LOCAL_ROOTS`.
191
-
192
- Local caption sidecars are optional. Urma checks the video basename with `.vtt`
193
- first and `.srt` second. Local paths remain disabled when
194
- `URMA_LOCAL_ROOTS` is empty.
195
-
196
- `search_transcript` accepts either one `query` or a `queries` array. Its
197
- default mode is `phrase`; `terms` requires every normalized term to occur in a
198
- cue. Search is literal and case-insensitive after NFKC normalization. A
199
- matching caption is a lead for visual verification, not visual proof.
200
-
201
- `read_transcript` requires a source-global half-open interval,
202
- `[startMs,endMs)`. It returns at most 200 segments or 16,000 caption
203
- characters per page. To continue, pass `nextCursor` as `cursor` with the same
204
- investigation, interval, and selected track.
205
-
206
- ### Visual inputs
207
-
208
- `get_overview` accepts an optional source-global interval. It requests 12
209
- temporally distributed cells. The returned timestamps are the samples that
210
- were observed; they do not describe continuous coverage.
211
-
212
- `get_frames` accepts one of these requests:
213
-
214
- | Request | Contract |
125
+ | Tool | Use it to |
215
126
  | --- | --- |
216
- | `points` | 1–12 unique timestamps, each before the source duration. |
217
- | `burst` | A half-open interval and 2–12 ordered samples. |
218
- | `cadence` | A half-open interval and a positive integer `cadenceMs`. |
219
-
220
- Times are nonnegative integer milliseconds from the start of the source.
221
- Intervals require `startMs < endMs` and must fit within its duration. An exact
222
- frame request asks for the first decodable frame at or after the target; it
223
- does not guarantee a frame with precisely that presentation timestamp.
127
+ | `inspect_video` | Open a video and list its duration, metadata, and caption tracks. |
128
+ | `search_transcript` | Find literal phrases or terms in a caption track. |
129
+ | `read_transcript` | Read timestamped captions for a time range. |
130
+ | `get_overview` | Browse up to 12 visual samples from a video or time range. |
131
+ | `get_frames` | Retrieve JPEG frames at chosen times, in a burst, or at a fixed interval. |
224
132
 
225
- For `points` and `burst`, the default presentation is `individual`. Set
226
- `presentation: "panel"` to receive one derived JPEG panel plus links to the
227
- canonical frame artifacts. A panel contains at most 12 cells and preserves
228
- request order.
133
+ Start with `inspect_video`. For an allowed local file, its arguments are:
229
134
 
230
- Cadence requests are paged. The default page maximum is 12 targets and the
231
- default schedule maximum is 120 targets. Continue with the returned opaque
232
- `nextCursor`; do not construct a cursor yourself. A cadence schedule is
233
- discrete evidence and does not cover the time between its targets.
234
-
235
- ### Example tool arguments
135
+ ```json
136
+ { "source": "/absolute/path/to/demo.mp4" }
137
+ ```
236
138
 
237
- For a local video, first add its parent directory to `URMA_LOCAL_ROOTS` in the
238
- host's Urma environment and restart the host. Call `inspect_video` with the
239
- absolute path to your file:
139
+ Use the returned `investigationRef` for subsequent calls. For example, these
140
+ `search_transcript` arguments find mentions of dark mode:
240
141
 
241
142
  ```json
242
- { "source": "/absolute/path/to/video.mp4" }
143
+ {
144
+ "investigationRef": "urma:investigation:0123456789abcdef0123456789abcdef",
145
+ "query": "dark mode"
146
+ }
243
147
  ```
244
148
 
245
- Use the returned `investigationRef` in subsequent calls. For example, these
246
- `get_frames` arguments request a panel at 1 and 5 seconds from a video longer
247
- than 5 seconds. Replace the example reference with the value from inspection:
149
+ Replace the example reference with the one from inspection. If a match occurs
150
+ near 10 seconds, these `get_frames` arguments request a panel at 10 and 11
151
+ seconds from a video longer than 11 seconds:
248
152
 
249
153
  ```json
250
154
  {
251
155
  "investigationRef": "urma:investigation:0123456789abcdef0123456789abcdef",
252
- "request": { "kind": "points", "timesMs": [1000, 5000] },
156
+ "request": { "kind": "points", "timesMs": [10000, 11000] },
253
157
  "presentation": "panel"
254
158
  }
255
159
  ```
256
160
 
257
- To continue a cadence page, pass `investigationRef` and the returned
258
- `nextCursor` as `cursor`, without a new `request`.
259
-
260
- ## Resources and errors
161
+ All times are integer milliseconds from the start of the video. Caption
162
+ search uses source-provided captions; Urma does not transcribe audio. Overviews
163
+ and frame requests show selected moments, so brief events between samples can
164
+ be missed.
261
165
 
262
- Successful evidence results include investigation-scoped resource links. An
263
- artifact can be reopened through
264
- `urma://investigation/{investigationId}/artifact/{artifactHash}` only after
265
- that investigation has received it in a tool result. Reopening an artifact
266
- does not add temporal coverage.
166
+ The [tool reference](docs/EVIDENCE_MODEL.md) covers all arguments, pagination,
167
+ result fields, and timing guarantees.
267
168
 
268
- The state resource is
269
- `urma://investigation/{investigationId}/state`. It contains persisted
270
- acquisition, cache, and presentation state for that investigation.
169
+ ## Configuration
271
170
 
272
- Top-level MCP failures return `isError: true` with a JSON text object containing
273
- `code`, `retryable`, and `detail`. A cadence page can instead return an error
274
- in an individual slot and continue with other targets.
171
+ Set environment variables in the client's Urma `env` entry and restart the
172
+ client after changing them.
275
173
 
276
- ## Evidence rules
174
+ ### Local videos
277
175
 
278
- For caption search, `partial: false` means all matches under the selected
279
- track's matching rules were returned. It says nothing about uncaptioned
280
- speech or visual events. Sampled frames describe only the returned points,
281
- and reopening cached artifacts adds no coverage.
176
+ Local file access is disabled by default. Set `URMA_LOCAL_ROOTS` to the
177
+ directories that Urma may read. Use absolute paths, separated by `;` on
178
+ Windows or `:` on macOS/Linux. For example:
282
179
 
283
- See [Evidence Model](docs/EVIDENCE_MODEL.md) for the full contract.
180
+ ```json
181
+ {
182
+ "URMA_LOCAL_ROOTS": "/home/you/Videos:/home/you/Demos"
183
+ }
184
+ ```
284
185
 
285
- ## Limits
186
+ This example is an `env` fragment for macOS/Linux. On Windows, a single root
187
+ might be `"URMA_LOCAL_ROOTS": "C:\\Users\\you\\Videos"`.
286
188
 
287
- Runtime defaults are:
189
+ Urma looks for captions beside the video: `demo.vtt` first, then `demo.srt` for
190
+ `demo.mp4`. Sidecars must also be inside an allowed root. Symlinks and junctions
191
+ are checked against their resolved locations.
288
192
 
289
- | Limit | Default |
290
- | --- | ---: |
291
- | Single caption search result limit | 5, maximum 20 |
292
- | Caption query length | 256 characters |
293
- | Batched caption queries | 20 queries, 20 merged hits, 16,000 returned characters |
294
- | Caption read page | 200 segments or 16,000 characters |
295
- | Overview request | 12 requested cells |
296
- | Explicit frame request | 12 points or burst samples |
297
- | Cadence page | 12 targets |
298
- | Cadence schedule | 120 targets |
299
- | Inline image response | 8 MiB |
300
- | Resource read | 32 MiB |
301
- | Targeted media acquisition | 64 MiB |
302
- | Navigation media acquisition | 256 MiB |
303
- | Reusable evidence media | 512 MiB |
304
- | Remote acquisition wall time | 180,000 ms |
305
-
306
- The environment variables below override the tunable limits. Values for byte
307
- limits are bytes; the remote wall limit is milliseconds. Each value must be a
308
- positive integer. `URMA_MAX_FRAME_SCHEDULE_PAGE_TARGETS` cannot exceed 12.
309
-
310
- | Variable | Overrides |
193
+ | Variable | Purpose |
311
194
  | --- | --- |
312
- | `URMA_MAX_TARGETED_MEDIA_BYTES` | Targeted media limit. |
313
- | `URMA_MAX_NAVIGATION_COPY_BYTES` | Navigation media and timeline-validation limit. |
314
- | `URMA_MAX_REUSABLE_EVIDENCE_MEDIA_BYTES` | Reusable evidence media limit. |
315
- | `URMA_MAX_REMOTE_ACQUISITION_WALL_MS` | Remote acquisition wall-time limit. |
316
- | `URMA_MAX_FRAME_SCHEDULE_PAGE_TARGETS` | Cadence page limit. |
317
- | `URMA_MAX_FRAME_SCHEDULE_TARGETS` | Cadence schedule limit. |
195
+ | `URMA_DATA_DIR` | Installation, database, and cache directory. |
196
+ | `URMA_LOCAL_ROOTS` | Directories allowed for local videos and caption sidecars. |
197
+ | `URMA_ALLOW_UNC` | Set to `1` or `true` to allow UNC video inputs under an allowed root. This does not allow a UNC data directory. |
198
+ | `URMA_DEBUG` | Set to `1` or `true` to write diagnostic logs to stderr. |
199
+ | `URMA_DEBUG_FILE` | Append diagnostic logs to a JSONL file when debugging is enabled. |
318
200
 
319
- ## Configuration
201
+ ### Acquisition limits
320
202
 
321
- | Variable | Purpose |
322
- | --- | --- |
323
- | `URMA_DATA_DIR` | Selects the persistent Urma data root. |
324
- | `URMA_LOCAL_ROOTS` | Platform-delimited list of roots allowed for local videos and sidecars. |
325
- | `URMA_ALLOW_UNC` | Allows UNC paths when set to `1` or `true`; the path must still be under an allowed root. |
326
- | `URMA_DEBUG` | Writes opt-in acquisition and subprocess diagnostics to stderr when set to `1` or `true`. |
327
- | `URMA_DEBUG_FILE` | Appends diagnostics to a JSONL file when `URMA_DEBUG` is enabled. |
203
+ These limits bound downloads and frame schedules. Override them with positive
204
+ integer values; byte limits use bytes and the timeout uses milliseconds.
328
205
 
329
- Set these variables in the host's Urma `env` entry, then restart the host.
330
- Separate local roots with `;` on Windows and `:` on macOS/Linux. Use absolute
331
- paths so root selection does not depend on the host's working directory.
206
+ | Variable | Default |
207
+ | --- | ---: |
208
+ | `URMA_MAX_TARGETED_MEDIA_BYTES` | 67,108,864 (64 MiB) |
209
+ | `URMA_MAX_NAVIGATION_COPY_BYTES` | 268,435,456 (256 MiB); also used for timeline validation |
210
+ | `URMA_MAX_REUSABLE_EVIDENCE_MEDIA_BYTES` | 536,870,912 (512 MiB) |
211
+ | `URMA_MAX_REMOTE_ACQUISITION_WALL_MS` | 180,000 (3 minutes) |
212
+ | `URMA_MAX_FRAME_SCHEDULE_PAGE_TARGETS` | 12; cannot be increased above 12 |
213
+ | `URMA_MAX_FRAME_SCHEDULE_TARGETS` | 120 |
332
214
 
333
- The packaged launcher uses the selected generation's absolute native-tool
334
- paths. It does not look up FFmpeg, ffprobe, or yt-dlp through `PATH`.
215
+ Inline image responses have a fixed 8 MiB ceiling, and resource reads have a
216
+ fixed 32 MiB ceiling. Tool-specific caption and sampling limits are listed in
217
+ the [tool reference](docs/EVIDENCE_MODEL.md).
335
218
 
336
219
  ## CLI and maintenance
337
220
 
338
- The npm entry point exposes setup and version checks:
339
-
340
- ```sh
341
- npx -y urma-mcp@rc --version
342
- npx -y urma-mcp@rc setup
343
- ```
221
+ Run setup again to update Urma. Restart the MCP client to use the new
222
+ installation; an already running server keeps its current version.
344
223
 
345
- The `npx` version command reports the npm candidate's version. To check the
346
- installed generation, use the Node and launcher paths printed by setup:
224
+ The npm version command reports the package selected by the tag:
347
225
 
348
226
  ```sh
349
- "/absolute/path/to/node" "/absolute/path/to/Urma/launcher-v1.mjs" --version
227
+ npx -y urma-mcp@latest --version
350
228
  ```
351
229
 
352
- After setup, run the read-only doctor through the persistent launcher:
230
+ To check the installed version or diagnose a problem, use the Node and launcher
231
+ paths printed by setup. If setup used a custom data directory, set
232
+ `URMA_DATA_DIR` to that directory before running launcher commands:
353
233
 
354
234
  ```sh
235
+ "/absolute/path/to/node" "/absolute/path/to/Urma/launcher-v1.mjs" --version
355
236
  "/absolute/path/to/node" "/absolute/path/to/Urma/launcher-v1.mjs" doctor
356
237
  ```
357
238
 
358
- In PowerShell, prefix the quoted executable path with `&`:
239
+ In PowerShell, prefix a quoted executable path with `&`:
359
240
 
360
241
  ```powershell
361
242
  & "C:\path\to\node.exe" "C:\path\to\Urma\launcher-v1.mjs" doctor
362
243
  ```
363
244
 
364
- Doctor checks the selected runtime, Node version, SQLite/FTS5, native-tool
365
- versions, storage, blob access, local roots, and frame-schedule limits. It
366
- prints its report to stderr and exits with status 0 when no check fails
367
- (warnings are allowed), or 1 when a check fails.
368
-
369
- For both version checks and doctor, set `URMA_DATA_DIR` if setup used a custom
370
- data root. To diagnose host behavior, also use the host's `URMA_LOCAL_ROOTS`
371
- and other Urma settings. If setup did not complete, report its error instead.
245
+ Doctor checks the runtime, native tools, storage, local roots, and configured
246
+ limits without changing the installation. Its report goes to stderr. Exit
247
+ status `0` means no check failed, although warnings may remain; `1` means at
248
+ least one check failed. Use the same `URMA_DATA_DIR`, `URMA_LOCAL_ROOTS`, and
249
+ other Urma settings as your MCP client.
372
250
 
373
- The launcher also provides local generation recovery:
251
+ If an update causes problems, the launcher provides two recovery commands:
374
252
 
375
253
  ```sh
376
254
  "/absolute/path/to/node" "/absolute/path/to/Urma/launcher-v1.mjs" rollback
377
255
  "/absolute/path/to/node" "/absolute/path/to/Urma/launcher-v1.mjs" recover
378
256
  ```
379
257
 
380
- `rollback` selects the retained previous generation after integrity and state
381
- compatibility checks. `recover` restores the selection recorded in
382
- `ACTIVE.backup.json`. Set `URMA_DATA_DIR` for a non-default data root.
258
+ `rollback` selects the retained previous installation after integrity and
259
+ state-compatibility checks. `recover` restores the installation selection
260
+ saved in `ACTIVE.backup.json`. Restart the MCP client afterward.
383
261
 
384
- Normal MCP startup selects one generation for the process. It does not invoke
385
- npm, make a network request, check for updates, modify `PATH`, or download
386
- dependencies. A later setup affects new processes only.
262
+ ## Reporting problems
387
263
 
388
- ## Boundaries
264
+ Use the [bug-report template](https://github.com/sajidurdev/urma/issues/new?template=bug-report.md).
265
+ Include reproduction steps, your OS and architecture, Node.js and MCP client
266
+ versions, and the installed Urma version. For source-specific problems,
267
+ include a public URL or describe a local file that reproduces the failure.
389
268
 
390
- Urma v0.1 does not transcribe audio, recognize objects or actions, or call a
391
- model. It supports finite videos without authentication or DRM. See
392
- [Product scope](docs/PRODUCT_SCOPE.md) for supported sources and exclusions.
269
+ Include doctor output if setup completed, or the setup error if it did not.
270
+ Remove credentials, private URLs, and personal paths before posting logs.
393
271
 
394
272
  ## Security
395
273
 
396
- Local paths require explicit allowed roots. Remote HTTP(S) work uses a
397
- process-local Safe Proxy that validates destinations and DNS results before
398
- connecting. Installed native tools are receipt-bound and hash-checked before
399
- first use. Subprocesses use argument arrays, `shell: false`, an allowlisted
400
- environment, bounded output, deadlines, cancellation, and process-tree
401
- cleanup.
402
-
403
- These controls protect the local application boundary under the trusted
404
- Node/FFmpeg/ffprobe/yt-dlp runtime model. They are not an operating-system
405
- sandbox against a compromised trusted executable.
406
-
407
- See [Security](docs/SECURITY.md) for the full boundary and failure behavior.
274
+ Urma restricts local files to configured roots, validates remote destinations,
275
+ and verifies its managed native tools. It is intended for one trusted local
276
+ user. See [Security](docs/SECURITY.md) for the controls, assumptions, and MCP
277
+ integration considerations.
408
278
 
409
279
  ## Development
410
280
 
411
- Use Node.js 24 and the pnpm version declared in `package.json`. See the
412
- [development prerequisites](docs/CONTRIBUTING.md#development-setup) for native
413
- tools used by the tests. From the repository root:
281
+ From the repository root, using Node.js 24 and the pnpm version in
282
+ `package.json`:
414
283
 
415
284
  ```sh
416
285
  pnpm install --frozen-lockfile
417
286
  pnpm check
418
287
  ```
419
288
 
420
- Contributions are welcome. Follow the [contribution guide](docs/CONTRIBUTING.md)
421
- for code structure, documentation standards, and pull request expectations.
289
+ See [Contributing](docs/CONTRIBUTING.md) for native-tool prerequisites, code
290
+ structure, and validation commands.
422
291
 
423
- ## License
292
+ ## Documentation
424
293
 
425
- Urma is licensed under [Apache License 2.0](LICENSE). Third-party dependencies
426
- and downloaded native tools retain their own licenses. The installed
427
- generation's `licenses/` directory records native component licenses and
428
- upstream references; preserve the accompanying upstream notices when
429
- redistributing those tools. Urma's license does not grant rights to videos or
430
- captions retrieved from other sources.
294
+ - [Product scope](docs/PRODUCT_SCOPE.md): supported sources and limitations.
295
+ - [Tool reference](docs/EVIDENCE_MODEL.md): arguments, results, and examples.
296
+ - [Architecture](docs/ARCHITECTURE.md): source snapshots, acquisition, caching, and installation design.
297
+ - [Security](docs/SECURITY.md): filesystem, network, subprocess, and resource boundaries.
298
+ - [Contributing](docs/CONTRIBUTING.md): development setup and contribution guidelines.
431
299
 
432
- ## Documentation
300
+ ## License
433
301
 
434
- - [Product scope](docs/PRODUCT_SCOPE.md) — current v0.1 behavior and exclusions.
435
- - [Architecture](docs/ARCHITECTURE.md) — runtime layers, persistence, caching, and acquisition decisions.
436
- - [Evidence Model](docs/EVIDENCE_MODEL.md) — what each result means and what it cannot establish.
437
- - [Security](docs/SECURITY.md) — path, network, subprocess, installation, and cache controls.
438
- - [Contributing](docs/CONTRIBUTING.md) — local setup, validation commands, and change expectations.
302
+ Urma is licensed under [Apache License 2.0](LICENSE). Dependencies and downloaded
303
+ native tools retain their own licenses. The installed runtime's `licenses/`
304
+ directory contains native component licenses and upstream references; preserve
305
+ their notices when redistributing those tools. Urma's license does not grant
306
+ rights to retrieved videos or captions.
@@ -4,7 +4,7 @@ import type { ResolvedSource } from "../sources/types.js";
4
4
  import { BlobStore } from "../store/blob-store.js";
5
5
  import type { StoredArtifact, UrmaStore } from "../store/store.js";
6
6
  import { MediaAcquirer } from "./media.js";
7
- import type { RemoteOperationContext } from "../remote/worker.js";
7
+ import type { RemoteOperationContext } from "../remote/operation-context.js";
8
8
  export declare function exactFrameRequestKey(source: Pick<ResolvedSource, "sourceRef" | "revision">, atMs: number): string;
9
9
  export type FrameTargetOutcome = Readonly<{
10
10
  status: "success";