mooteam-mcp 0.2.0 → 0.3.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.
@@ -25,7 +25,11 @@ Never publish session tokens or credential-bearing download links.
25
25
  | `MOOTEAM_COMPANY_ALIAS` | Config `company` | Exact `X-MT-Company` header value |
26
26
  | `MOOTEAM_FILE_TOKEN` | Config `fileToken` | Optional fallback download token |
27
27
  | `MOOTEAM_ROLES_FILE` | `roles.json` beside the selected config file | Optional local participant roles |
28
- | `MOOTEAM_TIMEOUT_MS` | `30000` | Per-request and PDF extraction timeout, 1000–120000 |
28
+ | `MOOTEAM_HISTORY` | Enabled | Set `off` to disable local history reads/writes |
29
+ | `MOOTEAM_HISTORY_MAX_BYTES` | `1048576` | Compressed history budget per workspace, 16384–10485760 |
30
+ | `MOOTEAM_HISTORY_MAX_TASKS` | `200` | Maximum retained task baselines, 1–2000 |
31
+ | `MOOTEAM_HISTORY_DAYS` | `90` | Expire tasks after this many days without an observation, 1–365 |
32
+ | `MOOTEAM_TIMEOUT_MS` | `30000` | Per-request and document worker timeout, 1000–120000 |
29
33
  | `MOOTEAM_MAX_PAGES` | `100` | Maximum pages in each API collection, 1–1000 |
30
34
  | `MOOTEAM_MAX_ATTACHMENT_BYTES` | `10485760` | Download limit, 1024–52428800 bytes |
31
35
  | `LOG_LEVEL` | `info` | `debug`, `info`, `warn`, `error`, `silent` |
@@ -60,14 +64,51 @@ Missing files mean no configured roles. Invalid files or a mismatched company
60
64
  produce a warning and omit roles while preserving task reads. The file limit is
61
65
  1 MiB; role labels must contain 1–256 characters.
62
66
 
63
- You can tell a local coding assistant who does what and ask it to update this
64
- file. It should resolve names to user IDs, use only roles you explicitly supply,
67
+ Tell the assistant who does what: it can use `list_participants`, then
68
+ `set_participant_role` with the exact user ID, expected full name and
69
+ `userConfirmed: true`. It must use only roles you explicitly supply,
65
70
  preserve other entries and the company value, and never publish the directory.
66
71
  If a name is ambiguous, clarify the person before assigning a role. Use a project
67
- override only when you specify that scope. No Moo.team write or MCP write tool is
68
- needed. Role labels provide context; they do not grant permissions or constitute
72
+ override only when you specify that scope. `role: null` removes the selected
73
+ scope. The tool writes only this local file and preserves other entries with an
74
+ atomic replacement and cross-process lock. Role labels provide context; they do not grant permissions or constitute
69
75
  instructions to perform actions.
70
76
 
77
+ ## Compact local history
78
+
79
+ `get_task_context` tracks changes by default; set `trackChanges: false` to leave
80
+ the baseline unchanged. `get_task_changes` compares and advances the same baseline.
81
+ The first complete read establishes a baseline. Attachment reads, search and related
82
+ task reads never advance it. Missing/incomplete comments preserve the previous
83
+ baseline. A late response cannot overwrite an observation that started later.
84
+
85
+ One `history-<workspace-hash>.json.gz` sits beside the selected config file.
86
+ It contains semantic hashes of task fields, comments and file metadata, source IDs,
87
+ status IDs/values, observation timestamps and short change events. It contains no
88
+ task titles, descriptions, discussion text, participant names or attachment bytes.
89
+ It is a change detector, not a backup: old text cannot be reconstructed, and edits
90
+ made and reverted between reads cannot be detected. A missing comment/file means
91
+ "no longer visible", not confirmed deletion. Changing local roles does not create
92
+ an edit to the source discussion.
93
+
94
+ The defaults are 1 MiB compressed, 200 tasks, 90 days since last observation and
95
+ 20 events per task. At most five recent events are returned. Expiry and oldest-task
96
+ eviction run during tracked reads; an evicted task starts a new baseline next time.
97
+ Each returned ID list is capped at 100 and includes full counts/truncation flags.
98
+ Uncompressed state is also bounded to 16 MiB. An individual baseline that cannot
99
+ fit is skipped with a warning, preserving the existing file.
100
+
101
+ An atomic save temporarily needs up to one additional file of the configured
102
+ size plus a small lock file. Normal completion removes temporary files. A crash
103
+ can leave a lock/temp file: stop all MCP processes before removing those leftovers.
104
+ Corrupt, oversized, busy or inaccessible state produces a warning and is preserved;
105
+ task reads still work. To reset a corrupt baseline, stop MCP and remove its history
106
+ file. Setting `MOOTEAM_HISTORY=off` does not remove an existing history file.
107
+
108
+ Keep the configuration directory private to your OS account, including its
109
+ inherited permissions on Windows: atomic replacements inherit directory ACLs.
110
+ History is gzip-compressed, not encrypted.
111
+
71
112
  ## Stdio clients
72
113
 
73
114
  ```json
@@ -115,8 +156,11 @@ in the host's environment to keep credentials in another location.
115
156
  pagination metadata was missing, or the configured page cap was reached.
116
157
 
117
158
  Operational logs go to stderr and omit credentials, full URLs and task content.
118
- No task database or attachment cache is written to disk. PDF text extraction uses
119
- a worker with a timeout and bounded V8 heap; this is not a general-purpose sandbox.
159
+ Only compact history and local roles are maintained on disk. Attachments are fetched
160
+ into RAM, processed and released; neither originals nor extracted/rendered content
161
+ are written as files. PDF/Office/ZIP processing uses workers with timeouts and a
162
+ 256 MiB V8 heap cap, plus explicit byte limits. Native allocations are outside the
163
+ V8 heap cap; this is not a general-purpose sandbox.
120
164
 
121
165
  ## See also
122
166
 
@@ -11,7 +11,8 @@ npm pack --dry-run
11
11
 
12
12
  Tests use synthetic data and an injected fetch implementation. No credentials or
13
13
  network access are needed for the test suite. The protocol test starts a separate
14
- stdio server and verifies tool discovery, task reads and image blocks.
14
+ stdio server and verifies tool discovery, task reads, history, local roles, search
15
+ and image blocks. Synthetic Office/ZIP/PDF fixtures are constructed in memory.
15
16
 
16
17
  For a live read-only check, configure local credentials and run `mooteam-mcp --check`.
17
18
  Set `MOOTEAM_SMOKE_TASK` and optionally `MOOTEAM_SMOKE_FILE`, then run `npm run smoke`.
@@ -32,22 +33,67 @@ MCP stdio → tool handlers → task context / attachment services → GET-only
32
33
  | `src/api-client.ts` | Fixed API origin, auth, bounded GETs and pagination |
33
34
  | `src/task-context.ts` | Task/comment assembly, authors and file ownership |
34
35
  | `src/roles.ts` | Bounded local role directory, workspace scope and project overrides |
36
+ | `src/local-state.ts` | Bounded reads, cross-process locks and atomic local state replacement |
37
+ | `src/history.ts` | Compressed semantic fingerprints, changes and retention/size eviction |
38
+ | `src/search.ts` | Project/participant discovery and bounded task collection search |
39
+ | `src/related.ts` | Parent/subtask/link traversal with provenance and attempt/depth limits |
35
40
  | `src/rich-text.ts` | Rich-text conversion with explicit limitations |
36
41
  | `src/attachments.ts` | File validation, format dispatch and output bounds |
37
- | `src/pdf-worker.ts` | Isolated PDF text extraction |
42
+ | `src/pdf-worker.ts` | Isolated PDF text extraction and selected-page rendering |
43
+ | `src/documents.ts`, `src/document-worker.ts` | Isolated bounded ZIP/OOXML text extraction |
38
44
 
39
- Runtime dependencies are the official MCP server SDK v2, Zod and PDF.js.
45
+ Runtime dependencies are the official MCP server SDK v2, Zod, PDF.js,
46
+ `@napi-rs/canvas` for PDF rendering, `yauzl` for bounded ZIP streams and `saxes`
47
+ for XML parsing without DTDs/external entities.
40
48
  MCP SDK's stdio compatibility support handles older protocol clients.
41
49
  There is no LLM API dependency and no hosted proxy.
42
50
 
51
+ Only explicit task tool reads update history. The full normalized comment set is
52
+ associated with a context object in a WeakMap, so returned pagination and internal
53
+ attachment ownership checks cannot corrupt or consume baselines. History stores
54
+ hashes and IDs, never rich bodies. Local role updates require user-supplied roles
55
+ and exact API name/ID resolution. Moo.team requests remain GET-only; MCP tools
56
+ that modify local files are annotated as local writes.
57
+
58
+ Document parsers receive byte arrays and return text/images over worker messages.
59
+ They never extract archives onto the filesystem. Limits include 1000 archive
60
+ entries, 8 MiB per inflated member, 24 MiB total inflation, 100000 XML elements,
61
+ 128 nesting levels, 10000 spreadsheet cells and requested character/page limits.
62
+ PDF images are capped at 4 million pixels per page and 5 MiB total PNG bytes.
63
+ Parser stdout/stderr is consumed privately so document content cannot enter MCP
64
+ protocol output or application logs. Every extraction reports its limitations.
65
+
43
66
  ## Release
44
67
 
45
- 1. Run tests and type checking.
46
- 2. Run `npm pack --dry-run` and inspect the package allowlist.
47
- 3. Check staged source contains no tokens, private task data or local configuration.
48
- 4. Commit and push reviewed source.
49
- 5. Publish with `npm publish --access public` using your own npm account.
50
- 6. Verify the published version and install it in a clean directory.
68
+ Releases run automatically from `.github/workflows/release.yml` after a push to
69
+ `main`. Pull requests and other branches only run checks. To prepare a release:
70
+
71
+ ```sh
72
+ npm run release:version -- patch
73
+ ```
74
+
75
+ Use `minor` or `major` when appropriate. This updates package.json and the lockfile;
76
+ the CLI and MCP protocol read that same version. Commit the reviewed changes and
77
+ push to main. Never include local credentials, participant directories or real
78
+ task fixtures in the commit.
79
+
80
+ The workflow runs the Windows/Linux and Node 22/24 checks first. If the version is
81
+ newer than npm's latest release, it builds, checks the package file allowlist,
82
+ publishes to npm, verifies the registry commit, then creates a `vVERSION` tag and
83
+ GitHub Release with generated notes. Unchanged published versions are skipped.
84
+ Only stable versions are supported by this workflow.
85
+
86
+ Publishing uses [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/)
87
+ with OIDC: package `mooteam-mcp`, repository `Mostok/mooteam-mcp`, workflow filename
88
+ `release.yml`, and direct `npm publish` permission. No npm token or Moo.team
89
+ credentials are stored in Actions. Only the publish job can request an OIDC token;
90
+ only the GitHub Release job can write repository metadata.
91
+
92
+ If a run fails, use **Re-run failed jobs** on that run. A version already published
93
+ from the same commit is not republished; verification and GitHub Release creation
94
+ can resume. Do not move an existing release tag. A new commit without a new version
95
+ does not repair an older release; retry the original run instead. `workflow_dispatch`
96
+ is available on main and runs the same checks and release guards.
51
97
 
52
98
  Only `dist`, `docs`, README, package metadata and LICENSE ship in the npm package.
53
99
  Internal plans, editor settings, tests, local credentials and development helpers
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mooteam-mcp",
3
- "version": "0.2.0",
4
- "description": "Read-only Moo.team MCP server: task context, attributed comments and attachments through the API.",
3
+ "version": "0.3.0",
4
+ "description": "Moo.team MCP: GET-only task context, search, compact local history, participant roles and in-memory attachments.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "mooteam-mcp": "dist/cli.js"
@@ -20,7 +20,8 @@
20
20
  "test": "npm run build && node --test test/*.test.mjs",
21
21
  "check": "tsc -p tsconfig.json --noEmit",
22
22
  "prepack": "npm run build",
23
- "smoke": "node scripts/smoke.mjs"
23
+ "smoke": "node scripts/smoke.mjs",
24
+ "release:version": "npm version --no-git-tag-version"
24
25
  },
25
26
  "keywords": [
26
27
  "mcp",
@@ -40,12 +41,16 @@
40
41
  "homepage": "https://github.com/Mostok/mooteam-mcp#readme",
41
42
  "dependencies": {
42
43
  "@modelcontextprotocol/server": "^2.0.0",
44
+ "@napi-rs/canvas": "^1.0.9",
43
45
  "pdfjs-dist": "^6.3.289",
46
+ "saxes": "^6.0.0",
47
+ "yauzl": "^3.4.0",
44
48
  "zod": "^4.5.4"
45
49
  },
46
50
  "devDependencies": {
47
51
  "@modelcontextprotocol/client": "^2.0.0",
48
52
  "@types/node": "^22.0.0",
53
+ "@types/yauzl": "^3.4.0",
49
54
  "typescript": "^5.9.3"
50
55
  }
51
56
  }