urma-mcp 0.1.0 → 0.2.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 (49) hide show
  1. package/README.md +13 -13
  2. package/dist/src/acquisition/frames.d.ts +1 -1
  3. package/dist/src/acquisition/frames.js +8 -19
  4. package/dist/src/acquisition/frames.js.map +1 -1
  5. package/dist/src/acquisition/media.js +3 -2
  6. package/dist/src/acquisition/media.js.map +1 -1
  7. package/dist/src/acquisition/remote-budget.js +2 -2
  8. package/dist/src/acquisition/remote-budget.js.map +1 -1
  9. package/dist/src/acquisition/transcript.js +70 -12
  10. package/dist/src/acquisition/transcript.js.map +1 -1
  11. package/dist/src/acquisition/video-timing.d.ts +2 -0
  12. package/dist/src/acquisition/video-timing.js +9 -0
  13. package/dist/src/acquisition/video-timing.js.map +1 -1
  14. package/dist/src/core/coverage.d.ts +14 -0
  15. package/dist/src/core/coverage.js +15 -0
  16. package/dist/src/core/coverage.js.map +1 -1
  17. package/dist/src/core/diagnostics.d.ts +1 -1
  18. package/dist/src/core/diagnostics.js +1 -1
  19. package/dist/src/core/diagnostics.js.map +1 -1
  20. package/dist/src/core/search-limits.d.ts +1 -1
  21. package/dist/src/core/search-limits.js +1 -1
  22. package/dist/src/core/search-limits.js.map +1 -1
  23. package/dist/src/distribution/manifest.js +15 -15
  24. package/dist/src/distribution/manifest.js.map +1 -1
  25. package/dist/src/evidence/service.d.ts +65 -0
  26. package/dist/src/evidence/service.js +9 -2
  27. package/dist/src/evidence/service.js.map +1 -1
  28. package/dist/src/mcp/projection.d.ts +1 -1
  29. package/dist/src/mcp/projection.js +1 -1
  30. package/dist/src/mcp/projection.js.map +1 -1
  31. package/dist/src/mcp/schemas.d.ts +160 -0
  32. package/dist/src/mcp/schemas.js +12 -0
  33. package/dist/src/mcp/schemas.js.map +1 -1
  34. package/dist/src/mcp/server.js +22 -18
  35. package/dist/src/mcp/server.js.map +1 -1
  36. package/dist/src/store/sqlite-store.js +25 -5
  37. package/dist/src/store/sqlite-store.js.map +1 -1
  38. package/dist/src/store/store.d.ts +1 -0
  39. package/dist/src/subprocess/runner.js +116 -23
  40. package/dist/src/subprocess/runner.js.map +1 -1
  41. package/dist/src/subprocess/ytdlp.d.ts +2 -2
  42. package/dist/src/subprocess/ytdlp.js +2 -2
  43. package/dist/src/subprocess/ytdlp.js.map +1 -1
  44. package/package.json +6 -7
  45. package/docs/ARCHITECTURE.md +0 -242
  46. package/docs/CONTRIBUTING.md +0 -118
  47. package/docs/EVIDENCE_MODEL.md +0 -350
  48. package/docs/PRODUCT_SCOPE.md +0 -69
  49. package/docs/SECURITY.md +0 -151
@@ -1,242 +0,0 @@
1
- # Architecture
2
-
3
- <p align="center">
4
- <img src="https://raw.githubusercontent.com/sajidurdev/urma/main/docs/assets/architecture.png" alt="Urma architecture" width="100%" />
5
- </p>
6
-
7
- Urma separates MCP request handling from source resolution, media acquisition,
8
- and persistence. `EvidenceService` coordinates those layers and records which
9
- results were returned to each investigation.
10
-
11
- ## Runtime shape
12
-
13
- ```text
14
- MCP client ──stdio──> MCP server ──> EvidenceService
15
- ├─ SourceResolver
16
- ├─ TranscriptAcquirer
17
- ├─ OverviewAcquirer
18
- ├─ FrameAcquirer
19
- ├─ SQLite store
20
- └─ content-addressed blob store
21
-
22
- launcher-v1.mjs ──> selected installed runtime
23
- acquisition ──────> Safe Proxy / yt-dlp / ffprobe / ffmpeg
24
- ```
25
-
26
- `src/mcp/schemas.ts` validates tool inputs and service results. The projection
27
- in `src/mcp/projection.ts` selects the public response fields, including source
28
- references, timestamps, completeness, pagination, and resource links. Richer
29
- acquisition and presentation records remain in storage.
30
-
31
- The server exposes five tools and two resource templates. `stdio.ts` owns the
32
- transport and shuts down the application when input closes or the process
33
- terminates. Stdout carries protocol messages; opt-in diagnostics go to stderr
34
- and optionally a JSONL file.
35
-
36
- ## Source identity and snapshots
37
-
38
- A remote video's delivery URL can expire or change while the video remains
39
- the same source. A local file can change at the same path. Urma therefore
40
- separates source identity, snapshot revision, and artifact content identity.
41
-
42
- ```text
43
- source reference → snapshot revision → acquired artifacts
44
- ```
45
-
46
- Source references have these forms:
47
-
48
- ```text
49
- urma:source:local:<32 lowercase hexadecimal characters>
50
- urma:source:remote:v1:<64 lowercase hexadecimal characters>
51
- ```
52
-
53
- `SourceResolver` accepts an HTTP(S) URL, an allowed local path, or a source
54
- reference. With `reuse`, a known remote URL or source reference loads the
55
- latest saved snapshot. `refresh` resolves it again. Direct local paths are
56
- always checked and pinned again.
57
-
58
- Remote resolution uses yt-dlp. YouTube single-video URLs have a dedicated
59
- branch that checks the requested video ID; other URLs use the generic branch.
60
- Both apply the remote source policy and validate a finite timeline. Admission
61
- requires a valid progressive/container probe, a finite HLS media playlist with
62
- `#EXT-X-ENDLIST`, or a static DASH MPD with a finite
63
- `mediaPresentationDuration`. Live, dynamic, and multi-entry results are
64
- rejected.
65
-
66
- A remote refresh records a new snapshot. Delivery locators belong to that
67
- snapshot's acquisition data and are treated as temporary leases. Format IDs
68
- select representations within the snapshot; they are not global cache keys.
69
-
70
- For local sources, the resolver checks canonical paths against allowed roots
71
- and pins the video bytes. The revision includes the video's content and the
72
- selected sidecar's path, content, and format, or its explicit absence. File
73
- statistics alone do not determine whether the source changed.
74
-
75
- Snapshots retain duration and timeline validation, observation time, safe
76
- metadata, chapters, capabilities, caption tracks, format candidates, and the
77
- policy and normalization versions used during resolution.
78
-
79
- ## Investigations and evidence
80
-
81
- `inspect_video` creates an investigation tied to a source reference, snapshot
82
- revision, and duration. Later tool calls use that saved snapshot.
83
-
84
- Source-level caches can serve several investigations, but each investigation
85
- records its own presentations. Finding an existing artifact in the cache does
86
- not count as returning it to the caller. This separation lets resource reads
87
- check that an investigation has actually received the requested content.
88
-
89
- ### Captions
90
-
91
- `TranscriptAcquirer` parses JSON3, WebVTT, or SRT into timestamped segments
92
- under a selected track. Tracks retain their language, kind, display name, and
93
- provider identifier when available. Search performs normalized literal
94
- matching; reads select segments overlapping a half-open time range.
95
-
96
- Caption artifacts and presentations retain the selected track and request
97
- scope. Urma does not merge tracks or generate transcripts from audio.
98
-
99
- ### Overviews
100
-
101
- `OverviewAcquirer` requests 12 temporally distributed points. It prefers a
102
- native storyboard and otherwise decodes navigation media. A short interval can
103
- produce fewer distinct points.
104
-
105
- The overview panel is a locator artifact. Each cell retains its sample
106
- provenance; current producers report nominal timing. The response distinguishes
107
- the requested interval from the returned sample timestamps and does not infer
108
- continuous coverage from sample spacing.
109
-
110
- Sample identity is also kept separately from transport reuse. A new interval
111
- can select a subset of existing storyboard cells, while decoding new times
112
- from cached navigation media produces new samples.
113
-
114
- ### Exact frames
115
-
116
- `FrameAcquirer` validates video timing and selects the first decodable
117
- presentation frame at or after each requested source time. Point requests,
118
- bursts, and cadence schedules use the same frame acquisition path. Each JPEG
119
- has a content hash and keeps its requested timestamp in the result.
120
-
121
- Remote HLS acquisition can download a bounded section around a target instead
122
- of a complete video. The section's requested bounds and validated video-stream
123
- presentation timestamp (PTS) coverage are stored separately. Acquisition only
124
- commits a section after media and timing validation succeed.
125
-
126
- Decoder seeks use the container start time, which can differ from the first
127
- video frame's PTS. A complete source copy can supply its first video frame for
128
- a target before that frame. A bounded section ordinarily needs validated PTS
129
- coverage of the target.
130
-
131
- There is a narrow exception for source time zero in HLS. Urma compares the
132
- section's first decoded RGB image and display geometry with the first decoded
133
- frame from the selected rendition's initial media segment. Both must have a
134
- positive video delay relative to their container start, and those delays must
135
- match within 1 ms. The playlist must be finite, start at media sequence zero,
136
- and have an end marker. A mismatch or unsupported playlist keeps the ordinary
137
- coverage requirement. Sections for nonzero targets still require PTS coverage.
138
-
139
- The public frame timestamps describe the requests. The current extraction
140
- path does not expose a measured selected-frame PTS.
141
-
142
- A panel is derived from successfully acquired JPEGs. It preserves their
143
- request order and links back to the individual artifacts. Explicit requests
144
- require all frames to succeed before panel composition. Cadence pages can
145
- return mixed slot outcomes, but only an all-success page gets a panel.
146
-
147
- ### Fixed cadence
148
-
149
- A cadence schedule computes targets from the original start time:
150
-
151
- ```text
152
- target(i) = startMs + i * cadenceMs, while target(i) < endMs
153
- ```
154
-
155
- The total count is checked before acquisition. Pages default to at most 12
156
- targets, and schedules default to at most 120. Each slot retains its schedule
157
- index and a `success`, `error`, or `unfinished` status.
158
-
159
- Signed continuation cursors bind the investigation, snapshot, schedule, and
160
- frame-selection contract to a next index. The signing key is process-local,
161
- so a restart requires a new request for the schedule. Pages reuse ordinary
162
- frame artifacts; future pages are not acquired in advance.
163
-
164
- ## Cache, artifacts, and storage
165
-
166
- Request keys combine the source revision, normalized arguments, and contract
167
- version. Artifact identities use the SHA-256 digest of their content. Keeping
168
- these keys separate allows equivalent requests to share work without treating
169
- parameters as proof of identical bytes.
170
-
171
- Artifacts have one of three roles:
172
-
173
- | Role | Content |
174
- | --- | --- |
175
- | `locator` | Overview images and derived frame panels. |
176
- | `transport` | Navigation media and bounded media sections used for extraction. |
177
- | `evidence` | Exact JPEG frames and transcript artifacts. |
178
-
179
- Blobs use this layout under the data directory:
180
-
181
- ```text
182
- blobs/<first two hash characters>/<next two hash characters>/<sha256>
183
- ```
184
-
185
- Writes use a temporary file, validation, hashing, and atomic promotion. A
186
- corrupt existing blob is quarantined before replacement. Reads check the
187
- expected path, size, and digest. An acquisition can replace invalid cached
188
- content; a resource read only reopens existing validated content.
189
-
190
- SQLite stores sources, snapshots, delivery locators, investigations, caption
191
- tracks and segments, artifacts, acquisitions, derivations, and presentations.
192
- It also records which artifacts each investigation may read. The current
193
- schema version is 5; incompatible database schemas are rejected rather than
194
- silently migrated.
195
-
196
- The state resource is derived from those persisted records. Like artifact
197
- reads, it is bounded by the resource byte limit. See the
198
- [tool reference](EVIDENCE_MODEL.md#resources-and-state) for public resource URIs.
199
-
200
- Equivalent acquisitions share an in-flight operation through singleflight.
201
- Observers can cancel independently; shared work stops when the last observer
202
- detaches. Failed or cancelled work does not create a successful acquisition
203
- record.
204
-
205
- ## Distribution and startup
206
-
207
- The npm package supplies setup and release artifacts. On a supported native
208
- Node.js installation, setup validates the local data directory, stages the
209
- runtime and pinned native tools, verifies hashes and archive contents, and
210
- runs native qualification plus a persisted-runtime MCP smoke test. Only a
211
- qualified installation is selected for launch.
212
-
213
- Each installation is stored in an immutable generation containing the runtime,
214
- native tools, assets, license notices, and `receipt.json`. Setup operations use
215
- one installation lock, with staging on the same filesystem as the final
216
- generation. Updates do not overwrite a running generation.
217
-
218
- `ACTIVE.json` selects the generation. Setup writes and flushes a temporary
219
- selector, then atomically renames it into place. The previous selector is kept
220
- in `ACTIVE.backup.json` for recovery.
221
-
222
- `launcher-v1.mjs` validates the selected generation and receipt, then starts
223
- the recorded runtime with absolute paths. A running process keeps that
224
- generation; a later setup affects new processes. Normal startup does not
225
- invoke npm, download dependencies, or check for updates.
226
-
227
- The launcher also accepts `doctor`, `rollback`, and `recover`. Rollback checks
228
- the retained generation's integrity and state compatibility. Recovery restores
229
- `ACTIVE.backup.json`. Setup itself runs from the npm entry point.
230
-
231
- ## Network and native tools
232
-
233
- Remote acquisition passes through a process-local Safe Proxy that validates
234
- URLs and DNS results before dialing a selected address. yt-dlp uses fixed
235
- arguments and an allowlisted environment. Remote FFmpeg and ffprobe inputs
236
- receive an explicit proxy and restricted protocol list. Local media inputs
237
- use a read-only file descriptor with an `fd`-only protocol list.
238
-
239
- Packaged runtimes use generation-local, receipt-verified native executables.
240
- Output and media byte limits, deadlines, cancellation, and process-tree
241
- cleanup bound acquisition work. The [security documentation](SECURITY.md)
242
- describes these controls and their trust assumptions in detail.
@@ -1,118 +0,0 @@
1
- # Contributing
2
-
3
- <p align="center">
4
- <img src="https://raw.githubusercontent.com/sajidurdev/urma/main/docs/assets/contribution.png" alt="Contributing to Urma" width="100%" />
5
- </p>
6
-
7
- Bug fixes, documentation corrections, tests, and improvements within the
8
- [product scope](PRODUCT_SCOPE.md) are welcome.
9
-
10
- ## Development setup
11
-
12
- Use the Node.js 24 version in
13
- [`.node-version`](https://github.com/sajidurdev/urma/blob/main/.node-version)
14
- and the pnpm version in
15
- [`package.json`](https://github.com/sajidurdev/urma/blob/main/package.json).
16
- Tests also require `ffmpeg`, `ffprobe`, and `yt-dlp` on `PATH`, with an FFmpeg
17
- build that includes `libx264`. Packaged installations manage their own native
18
- tools; setup does not add those tools to your development shell's `PATH`.
19
-
20
- From the repository root:
21
-
22
- ```sh
23
- pnpm install --frozen-lockfile
24
- pnpm build
25
- pnpm typecheck
26
- ```
27
-
28
- Run the unit and integration suites with:
29
-
30
- ```sh
31
- pnpm test:unit
32
- pnpm test:integration
33
- ```
34
-
35
- Each test command builds first. `pnpm check` runs the type-check and both
36
- suites. For package metadata, CI, or release changes, also run:
37
-
38
- ```sh
39
- node scripts/validate-metadata.mjs
40
- node --test scripts/tests/*.test.mjs
41
- ```
42
-
43
- The [CI workflow](https://github.com/sajidurdev/urma/blob/main/.github/workflows/ci.yml)
44
- shows the native-tool setup used in CI. It runs on pull request updates and
45
- pushes to `main` using Node.js 22.16.0 and the latest 22, 24, and 26 releases.
46
-
47
- ## Code structure
48
-
49
- | Directory | Responsibility |
50
- | --- | --- |
51
- | [`src/mcp`](https://github.com/sajidurdev/urma/tree/main/src/mcp) | Tool schemas, response projections, and MCP transport. |
52
- | [`src/evidence`](https://github.com/sajidurdev/urma/tree/main/src/evidence) | Request orchestration and presentation records. |
53
- | [`src/sources`](https://github.com/sajidurdev/urma/tree/main/src/sources) | Source resolution and snapshots. |
54
- | [`src/acquisition`](https://github.com/sajidurdev/urma/tree/main/src/acquisition) | Caption, overview, and media acquisition. |
55
- | [`src/store`](https://github.com/sajidurdev/urma/tree/main/src/store) | SQLite records and blob storage. |
56
- | [`src/distribution`](https://github.com/sajidurdev/urma/tree/main/src/distribution) | Installation, managed tools, receipts, and launchers. |
57
-
58
- See [Architecture](ARCHITECTURE.md) for how these layers fit together. Place
59
- tests in the corresponding
60
- [`tests/unit`](https://github.com/sajidurdev/urma/tree/main/tests/unit) or
61
- [`tests/integration`](https://github.com/sajidurdev/urma/tree/main/tests/integration)
62
- suite, following nearby tests.
63
-
64
- ## Preparing a change
65
-
66
- Keep each change focused on one problem. Follow the surrounding naming and
67
- module structure, and separate unrelated formatting or refactoring work.
68
- Tests should cover observable behavior and meaningful failure cases. Comments
69
- should explain a non-obvious constraint or decision rather than repeat the
70
- code.
71
-
72
- Changes to tool arguments, source references, timestamps, pagination, or result
73
- limits affect MCP clients. Update the relevant schemas, projections, tests,
74
- and [tool reference](EVIDENCE_MODEL.md) together. Acquisition changes also need
75
- to preserve [file, network, and subprocess controls](SECURITY.md) and the
76
- investigation's record of returned evidence.
77
-
78
- For documentation changes, check examples against
79
- [`src/mcp/schemas.ts`](https://github.com/sajidurdev/urma/blob/main/src/mcp/schemas.ts),
80
- response fields against
81
- [`src/mcp/projection.ts`](https://github.com/sajidurdev/urma/blob/main/src/mcp/projection.ts),
82
- and settings against
83
- [`src/config.ts`](https://github.com/sajidurdev/urma/blob/main/src/config.ts).
84
- Keep installation instructions in the README and detailed tool behavior in
85
- the reference. Verify commands and links, explain placeholders, and keep
86
- necessary limits next to the behavior they constrain.
87
-
88
- ## Installation and release changes
89
-
90
- The [release workflow](https://github.com/sajidurdev/urma/blob/main/.github/workflows/release.yml)
91
- qualifies the packed npm artifact on six platforms. Changes to setup,
92
- launchers, managed binaries, or release metadata need the corresponding
93
- qualification checks.
94
-
95
- Pinned native versions live in
96
- [`manifest.ts`](https://github.com/sajidurdev/urma/blob/main/src/distribution/manifest.ts).
97
- When updating FFmpeg pins, check the
98
- [BtbN retention policy](https://github.com/BtbN/FFmpeg-Builds#release-retention-policy)
99
- and choose artifacts that will remain available for the supported release.
100
-
101
- Releases are managed by the owner and designated core maintainers. Leave
102
- package versions unchanged unless a maintainer requests a version change.
103
-
104
- ## Pull requests
105
-
106
- Use a specific title. Explain the problem, the resulting behavior, and the
107
- validation performed. Include reproduction steps for a bug and call out any
108
- material limitation or check you could not run. Documentation-only changes
109
- need examples, links, and implementation claims checked; code changes need
110
- the relevant build and tests as well.
111
-
112
- ## License
113
-
114
- Contributions are submitted under the project's
115
- [Apache License 2.0](../LICENSE), subject to its contribution terms.
116
- Contributors retain copyright in their contributions. Only submit material
117
- you have the right to contribute, and retain applicable third-party license
118
- and attribution notices.