@juvantlabs/m365-graph-mcp-server 0.4.0 → 0.4.3
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.
- package/ARCHITECTURE.md +2 -2
- package/CHANGELOG.md +172 -2
- package/README.md +10 -6
- package/dist/auth/confirmation_tokens.d.ts +1 -0
- package/dist/auth/confirmation_tokens.d.ts.map +1 -1
- package/dist/auth/confirmation_tokens.js +21 -2
- package/dist/auth/confirmation_tokens.js.map +1 -1
- package/dist/auth/msal.d.ts +28 -2
- package/dist/auth/msal.d.ts.map +1 -1
- package/dist/auth/msal.js +35 -1
- package/dist/auth/msal.js.map +1 -1
- package/dist/auth/setup.d.ts.map +1 -1
- package/dist/auth/setup.js +3 -11
- package/dist/auth/setup.js.map +1 -1
- package/dist/tools/create_folder.d.ts +64 -0
- package/dist/tools/create_folder.d.ts.map +1 -0
- package/dist/tools/create_folder.js +123 -0
- package/dist/tools/create_folder.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/package.json +11 -10
package/ARCHITECTURE.md
CHANGED
|
@@ -290,9 +290,9 @@ security smell (handbook anti-pattern S1).
|
|
|
290
290
|
|
|
291
291
|
| Dependency | Version | Why |
|
|
292
292
|
|---|---|---|
|
|
293
|
-
| `@modelcontextprotocol/sdk` | `^1.
|
|
293
|
+
| `@modelcontextprotocol/sdk` | `^1.32.2` | MCP framing; ≥1.25.2 required (ReDoS + DNS rebinding fixes — audit C7); ≥1.32 clears the late-2026 `npm audit` advisories on the SDK and its transitive HTTP stack. |
|
|
294
294
|
| `@microsoft/microsoft-graph-client` | `^3.0.7` | Microsoft's official Graph SDK — handles batching, retries, types |
|
|
295
|
-
| `@azure/msal-node` | `^
|
|
295
|
+
| `@azure/msal-node` | `^7.1.2` | OAuth — never roll auth. v5+ avoids transitive `uuid <14` GHSA-w5hq-g745-h8pq; v7.1.2 clears the high-severity advisory affecting 5.0.0-beta.0 – 7.0.2. The v6/v7 majors only change `PublicClientApplication.acquireTokenInteractive` (unused here); the confidential-client auth-code flow, `getAuthCodeUrl` defaults and the token-cache format are unchanged — pinned by `tests/unit/msal_contract.test.ts`, including a cache fixture written by 5.1.5. |
|
|
296
296
|
| `@napi-rs/keyring` | `^1.3.0` | OS keychain for token persistence; replaces archived `keytar`. |
|
|
297
297
|
| `isomorphic-fetch` | `^3.0.0` | Peer dep of the Graph SDK. |
|
|
298
298
|
|
package/CHANGELOG.md
CHANGED
|
@@ -11,7 +11,168 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
-
## [0.4.
|
|
14
|
+
## [0.4.3] - unreleased — publish-workflow fix; first npm release of the 0.4.2 content
|
|
15
|
+
|
|
16
|
+
Ships everything listed under `[0.4.2]` below (that version was tagged
|
|
17
|
+
but never reached npm). No tool, schema or behaviour change.
|
|
18
|
+
|
|
19
|
+
### Fixed — release pipeline
|
|
20
|
+
|
|
21
|
+
- **`publish.yml`: pin the npm upgrade to `npm@^11.5.1`** instead of
|
|
22
|
+
`npm@latest`. npm 12 dropped Node 20 (engines `^22.22.2 || ^24.15.0
|
|
23
|
+
|| >=26`), so `npm install -g npm@latest` failed with `EBADENGINE` on
|
|
24
|
+
the Node 20 publish job and the `v0.4.2` run published nothing.
|
|
25
|
+
11.5.1 is the npm Trusted Publishing minimum, and npm 11 supports
|
|
26
|
+
Node `^20.17.0` (the job runs Node 20.20.x). `ci.yml` does not upgrade
|
|
27
|
+
npm and is unaffected.
|
|
28
|
+
|
|
29
|
+
## [0.4.2] - tagged, never published — dependency security remediation
|
|
30
|
+
|
|
31
|
+
> **Not on npm.** The `v0.4.2` tag exists, but its publish run failed at
|
|
32
|
+
> the npm-upgrade step (see `[0.4.3]`) before anything was published.
|
|
33
|
+
> The tag was deliberately not moved; this content first ships in
|
|
34
|
+
> **0.4.3**.
|
|
35
|
+
|
|
36
|
+
No tool, schema or behaviour change. Clears every `npm audit` advisory
|
|
37
|
+
(34 → 0: 3 critical, 13 high, 17 moderate, 1 low) so the CI and publish
|
|
38
|
+
audit gate (`--audit-level=moderate`, unchanged) passes again. No
|
|
39
|
+
advisory is ignored.
|
|
40
|
+
|
|
41
|
+
### Security — runtime dependencies (shipped)
|
|
42
|
+
|
|
43
|
+
- **`@azure/msal-node` `^5.0.0` → `^7.1.2`** (high; affected range
|
|
44
|
+
5.0.0-beta.0 – 7.0.2; resolved 5.1.5 → 7.1.2; `@azure/msal-common`
|
|
45
|
+
stays on the 16.x line, 16.5.2 → 16.15.0). Migration review:
|
|
46
|
+
- v6 / v7 breaking changes are confined to
|
|
47
|
+
`PublicClientApplication.acquireTokenInteractive` (`form_post`
|
|
48
|
+
default, then `responseMode` removed; custom `loopbackClient` /
|
|
49
|
+
`ILoopbackClient` removed; loopback GET callbacks rejected). This
|
|
50
|
+
server uses `ConfidentialClientApplication` with a manually hosted
|
|
51
|
+
authorization-code flow (`getAuthCodeUrl` + own localhost listener +
|
|
52
|
+
`acquireTokenByCode`), `acquireTokenSilent`, and a custom
|
|
53
|
+
`ICachePlugin` on the OS keychain — none of which changed contract.
|
|
54
|
+
No device-code or interactive (`acquireTokenInteractive`) path
|
|
55
|
+
exists here.
|
|
56
|
+
- `getAuthCodeUrl` on a confidential client still defaults to
|
|
57
|
+
`response_mode=query`, which the setup listener reads.
|
|
58
|
+
- Since 5.6 / 6.0.1, `acquireTokenByCode` validates the ID-token nonce
|
|
59
|
+
strictly. Setup sends no nonce, so Entra issues none and the
|
|
60
|
+
exchange passes; the two setup requests are now built by
|
|
61
|
+
`authCodeUrlRequest()` / `authCodeTokenRequest()` in
|
|
62
|
+
`src/auth/msal.ts` so they cannot drift apart.
|
|
63
|
+
- 7.0.2 / 7.1.0 sanitize the auth-code payload and reject
|
|
64
|
+
`instanceAware` for confidential clients — not used here.
|
|
65
|
+
- 7.0.0 coalesces concurrent identical silent-token requests
|
|
66
|
+
(beneficial for parallel tool calls).
|
|
67
|
+
- Token-cache format: a cache serialized by 5.1.5 is read by 7.1.2
|
|
68
|
+
and refreshes with its refresh token — existing keychain entries
|
|
69
|
+
keep working; no re-run of `setup` expected.
|
|
70
|
+
- **`@modelcontextprotocol/sdk` `^1.25.2` → `^1.32.2`** (high; also
|
|
71
|
+
clears transitive `hono`, `@hono/node-server`, `express-rate-limit`,
|
|
72
|
+
`body-parser`, `proxy-addr` (critical), `qs`, `fast-uri`, `zod`,
|
|
73
|
+
`ip-address`).
|
|
74
|
+
|
|
75
|
+
### Security — development toolchain (not shipped)
|
|
76
|
+
|
|
77
|
+
- `vitest` / `@vitest/coverage-v8` `^3` → `^4.1.12` (critical via
|
|
78
|
+
`vitest`, `tinypool`; also `vite`, `esbuild`, `postcss`, `nanoid`,
|
|
79
|
+
`source-map-js`, `glob`, `test-exclude`, `js-yaml`). Vitest 5 was not
|
|
80
|
+
taken: it requires Node ≥ 22 and this package supports Node ≥ 20.
|
|
81
|
+
- `eslint` `^9` → `^10.14.0`, `@typescript-eslint/*` → `^8.72.1`,
|
|
82
|
+
`tsx` → `^4.23.15`.
|
|
83
|
+
- `overrides.minimatch: ^11.0.1` (moderate, GHSA-g3hv-75wg-m249). Every
|
|
84
|
+
current ESLint / typescript-eslint release still depends on
|
|
85
|
+
minimatch 10.x and there is no 10.x backport, so the patched major is
|
|
86
|
+
forced. Its consumers here only use `new Minimatch(pattern, { dot })`,
|
|
87
|
+
`Minimatch#match` and the named `minimatch()` — all retained in 11.x
|
|
88
|
+
(11.0 removed `makeRe`, `regexp`, `AST`, `debug`, none of which they
|
|
89
|
+
call).
|
|
90
|
+
|
|
91
|
+
### Tests
|
|
92
|
+
|
|
93
|
+
- Vitest 4: constructor mocks (`new Entry(...)`) now use `function`
|
|
94
|
+
implementations (arrow functions are not constructible under v4).
|
|
95
|
+
- `@vitest/coverage-v8` 4 counts lines and branches more strictly; the
|
|
96
|
+
per-file thresholds (unchanged) are met by new tests rather than by
|
|
97
|
+
lowering them: plain streaming download (`download_file_stream`),
|
|
98
|
+
resumable large-file upload (`upload_file_large`), and search result
|
|
99
|
+
mapping.
|
|
100
|
+
- New `msal_contract.test.ts` runs the **real** msal-node offline (fake
|
|
101
|
+
keychain + fake token endpoint): setup URL (`response_mode=query`, no
|
|
102
|
+
nonce), code exchange → keychain → silent token after restart, strict
|
|
103
|
+
nonce rejection, and a keychain cache written by msal-node 5.1.5
|
|
104
|
+
(fixture + generator in `tests/fixtures/msal-legacy-cache/`) yielding
|
|
105
|
+
its token and refreshing with its refresh token. The fixture stores a
|
|
106
|
+
placeholder instead of the JWT-shaped synthetic ID token (secret
|
|
107
|
+
scanning treats it as a credential); the test rebuilds it at load.
|
|
108
|
+
- `makeMsalClient()` accepts optional offline-metadata / network-module
|
|
109
|
+
overrides (test seam; production passes none).
|
|
110
|
+
|
|
111
|
+
## [0.4.1] - 2026-07-04 — folder creation + confirmation-token expiry semantics
|
|
112
|
+
|
|
113
|
+
> Release-hygiene note: `[0.4.0]` was tag-published on 2026-06-26 from
|
|
114
|
+
> commit `5235c78`. Three subsequent PRs (#9, #11, #12) merged to `main`
|
|
115
|
+
> **without** a version bump on `package.json`, so the source tree
|
|
116
|
+
> drifted from what's on npm. This `0.4.1` restores that alignment. See
|
|
117
|
+
> the root-cause writeup in `docs/adr/` (forthcoming) and the follow-up
|
|
118
|
+
> to add a CI guard that fails a merge when `package.json.version`
|
|
119
|
+
> matches a version already in `npm view … versions`.
|
|
120
|
+
|
|
121
|
+
### Added — Files
|
|
122
|
+
|
|
123
|
+
- **`m365-graph:create_folder`** — new tool for creating folders in
|
|
124
|
+
OneDrive personal drives and SharePoint document libraries. Wraps
|
|
125
|
+
`POST /drives/{drive-id}/items/{parent-id}/children` with the
|
|
126
|
+
`folder: {}` facet. Parameters: `name` (required), `parent_item_id?`
|
|
127
|
+
(defaults to drive root), `drive_id?` (defaults to `/me/drive`),
|
|
128
|
+
`conflict_behavior?` — **restricted to `fail` (default) | `rename`
|
|
129
|
+
by design**. `replace` is intentionally NOT exposed: Graph accepts
|
|
130
|
+
it, but replacing an existing folder is a near-destructive intent
|
|
131
|
+
(the existing folder — potentially with content — is displaced)
|
|
132
|
+
that would push this tool from `write_idempotent` toward
|
|
133
|
+
`write_irreversible` semantics and force a two-phase confirmation
|
|
134
|
+
gate. Callers that truly need replacement compose it from
|
|
135
|
+
`delete_file` (already two-phase-gated) + `create_folder`.
|
|
136
|
+
Returns the created folder's item ID so agents can chain
|
|
137
|
+
`upload_file(parent_item_id=<new_id>, …)` without a round-trip
|
|
138
|
+
through `list_items`. Categorized `write_idempotent` — repeated
|
|
139
|
+
calls with the default `fail` behavior converge on a single
|
|
140
|
+
effective state, and the created folder is reversible via
|
|
141
|
+
`delete_file`. No new Graph scope required: `Files.ReadWrite`
|
|
142
|
+
(OneDrive) and `Sites.ReadWrite.All` (SharePoint) already granted
|
|
143
|
+
in 0.4.0. Filed as issue #10; motivated by real friction archiving
|
|
144
|
+
invoices into the `finance-invoices` SharePoint library where
|
|
145
|
+
destination folders (`Aruba/`, `_SDI-ufficiali/`, `Namecheap/`,
|
|
146
|
+
`_Personal-pre_startup/`) had to be created by hand in the web UI
|
|
147
|
+
before the server could upload into them. Total tool count is now
|
|
148
|
+
20 (5 write on files: upload, create_folder, copy, move, delete).
|
|
149
|
+
|
|
150
|
+
### Fixed
|
|
151
|
+
|
|
152
|
+
- **`consumeConfirmation` — expired token now reports `token_expired`,
|
|
153
|
+
not `token_unknown`** (`src/auth/confirmation_tokens.ts`). Pre-fix, the
|
|
154
|
+
periodic `gc()` pass ran BEFORE the entry lookup, so an expired-but-
|
|
155
|
+
still-recorded entry was garbage-collected first and the subsequent
|
|
156
|
+
`pending.get(token)` returned `undefined` — the caller saw
|
|
157
|
+
`token_unknown` and the `token_expired` code path was effectively
|
|
158
|
+
unreachable from wall-clock expiry. The two states are semantically
|
|
159
|
+
distinct (expired = "you're late"; unknown = "there's no such token")
|
|
160
|
+
and both are audit-relevant on a security-relevant two-phase gate
|
|
161
|
+
(`delete_file`, `cancel_event`, `decline_event`). Fix: look up the
|
|
162
|
+
entry FIRST, distinguish expired vs unknown, then run `gc()` on the
|
|
163
|
+
rest of the store. A new `_injectExpiredConfirmation` test helper and
|
|
164
|
+
two unit tests assert the distinct outcomes without racing wall-clock
|
|
165
|
+
time. Surfaced by a sibling MCP server (`m365-mail`) while porting the
|
|
166
|
+
same confirmation-token module. No behavior change on any other
|
|
167
|
+
outcome (`ok`, `token_wrong_tool`, `spec_mismatch` all unchanged).
|
|
168
|
+
This fix was originally listed under `[0.4.0]` in the pre-audit
|
|
169
|
+
changelog, but did NOT make it into the npm-published 0.4.0 tarball
|
|
170
|
+
(verified by tarball inspection on 2026-07-04); it lands in the user-
|
|
171
|
+
visible surface only with this 0.4.1.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## [0.4.0] - 2026-06-26 — SharePoint sites RW + permission-surface invariants
|
|
15
176
|
|
|
16
177
|
### Added
|
|
17
178
|
|
|
@@ -53,6 +214,11 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
53
214
|
|
|
54
215
|
Reference: decisions#210 (per-agent legal-ip enforcement architecture).
|
|
55
216
|
|
|
217
|
+
Published from tag `v0.4.0` → commit `5235c78`. **Note**: the fix
|
|
218
|
+
`consumeConfirmation reports token_expired distinctly from
|
|
219
|
+
token_unknown` was originally targeted for this release but landed on
|
|
220
|
+
`main` after the tag was cut; it ships in `0.4.1`.
|
|
221
|
+
|
|
56
222
|
---
|
|
57
223
|
|
|
58
224
|
## [0.3.0] - 2026-06-22 — Long Teams transcript paging + cap fix
|
|
@@ -410,7 +576,11 @@ the Juvant OS instance level — see juvant-os-pm FEAT-018 / 019 /
|
|
|
410
576
|
|
|
411
577
|
---
|
|
412
578
|
|
|
413
|
-
[Unreleased]: https://github.com/juvantlabs/m365-graph-mcp-server/compare/v0.3
|
|
579
|
+
[Unreleased]: https://github.com/juvantlabs/m365-graph-mcp-server/compare/v0.4.3...HEAD
|
|
580
|
+
[0.4.3]: https://github.com/juvantlabs/m365-graph-mcp-server/compare/v0.4.2...v0.4.3
|
|
581
|
+
[0.4.2]: https://github.com/juvantlabs/m365-graph-mcp-server/compare/v0.4.1...v0.4.2
|
|
582
|
+
[0.4.1]: https://github.com/juvantlabs/m365-graph-mcp-server/compare/v0.4.0...v0.4.1
|
|
583
|
+
[0.4.0]: https://github.com/juvantlabs/m365-graph-mcp-server/compare/v0.3.0...v0.4.0
|
|
414
584
|
[0.3.0]: https://github.com/juvantlabs/m365-graph-mcp-server/compare/v0.2.1...v0.3.0
|
|
415
585
|
[0.2.1]: https://github.com/juvantlabs/m365-graph-mcp-server/compare/v0.2.0...v0.2.1
|
|
416
586
|
[0.2.0]: https://github.com/juvantlabs/m365-graph-mcp-server/compare/v0.1.4...v0.2.0
|
package/README.md
CHANGED
|
@@ -32,10 +32,13 @@ See [CHANGELOG.md](CHANGELOG.md) for the full change list.
|
|
|
32
32
|
|
|
33
33
|
## Status
|
|
34
34
|
|
|
35
|
-
**Published.** v0.
|
|
36
|
-
([`@juvantlabs/m365-graph-mcp-server`](https://www.npmjs.com/package/@juvantlabs/m365-graph-mcp-server))
|
|
37
|
-
19 tools across files (OneDrive + SharePoint),
|
|
38
|
-
Teams meeting transcripts.
|
|
35
|
+
**Published.** v0.4.0 on npm
|
|
36
|
+
([`@juvantlabs/m365-graph-mcp-server`](https://www.npmjs.com/package/@juvantlabs/m365-graph-mcp-server)),
|
|
37
|
+
released 2026-06-26. 19 tools across files (OneDrive + SharePoint),
|
|
38
|
+
Outlook Calendar, and Teams meeting transcripts. v0.4.1 is prepared
|
|
39
|
+
on `main` — adds `create_folder` (bringing the tool count to 20) and
|
|
40
|
+
fixes the `consumeConfirmation` gc-ordering bug; pending manual tag +
|
|
41
|
+
release trigger. Published via npm **Trusted Publishing**
|
|
39
42
|
(OIDC-based auth from GitHub Actions; no static `NPM_TOKEN`) with
|
|
40
43
|
provenance attestation; manual approval gate on the `production`
|
|
41
44
|
GitHub Environment guards the publish step.
|
|
@@ -96,7 +99,7 @@ The Juvant OS adopter binds this server in `.juvant/config.json`:
|
|
|
96
99
|
{
|
|
97
100
|
"m365-graph": {
|
|
98
101
|
"provider": "microsoft",
|
|
99
|
-
"mcp_server": "npx @juvantlabs/m365-graph-mcp-server@0.
|
|
102
|
+
"mcp_server": "npx @juvantlabs/m365-graph-mcp-server@0.4.0",
|
|
100
103
|
"scope": "rw"
|
|
101
104
|
}
|
|
102
105
|
}
|
|
@@ -122,6 +125,7 @@ Step 8.5 cross-check semantics.
|
|
|
122
125
|
| `m365-graph:search_events` | Searches events by subject substring (Graph $search isn't supported on Events; subject-only via `contains()`). Returns recurrence series masters, not occurrences. | `query` (required), `limit?` (1–50, default 20) | `{ count, results: [] }` (same event shape). | `Calendars.Read` |
|
|
123
126
|
| `m365-graph:get_event` | Fetches full details for a single event — body (capped at 8000 chars), attendees with response statuses, location, recurrence rule, online-meeting join URL when applicable. | `event_id` (required) | event summary + `body` / `body_content_type` / `body_truncated` / `recurrence` / `online_meeting_join_url`. | `Calendars.Read` |
|
|
124
127
|
| `m365-graph:upload_file` | Uploads a local file to a drive. Auto-routes between single PUT (≤ 4 MB) and resumable upload session (> 4 MB, 10 MB chunks). 200 MB hard cap. | `local_path` (required), `drive_id?`, `parent_item_id?`, `name?`, `conflict_behavior?` (`fail`/`replace`/`rename`, default `fail`) | `{ uploaded: { id, name, size, webUrl, upload_path } }` | `Files.ReadWrite` |
|
|
128
|
+
| `m365-graph:create_folder` | Creates a folder in a drive (OneDrive primary by default; SharePoint document library via `drive_id`). Synchronous POST to `/children`. Returns the new folder's item ID so it can be passed as `parent_item_id` to a subsequent `upload_file` / `create_folder` call. `replace` conflict behavior is intentionally not exposed (compose `delete_file` + `create_folder` if truly needed). | `name` (required), `parent_item_id?`, `drive_id?`, `conflict_behavior?` (`fail`/`rename`, default `fail`) | `{ created: { id, name, webUrl, parent_id, child_count } }` | `Files.ReadWrite` |
|
|
125
129
|
| `m365-graph:create_event` | Creates a new event on the user's primary calendar (or a specified calendar). Sends invitations to attendees by Graph default. | `subject` + `start` + `end` (required), `timezone?` (default UTC), `body?`, `body_content_type?` (`text`/`html`), `location?`, `attendees?`, `is_all_day?`, `calendar_id?` | `{ created: <event summary> }` | `Calendars.ReadWrite` |
|
|
126
130
|
| `m365-graph:update_event` | Updates an existing event. All fields except `event_id` are optional; only provided fields are PATCHed. **Attendees: full replacement, not merge** — pass the full intended list. | `event_id` (required), then any subset of `subject`/`start`+`end`+`timezone`/`body`+`body_content_type`/`location`/`attendees`/`is_all_day` | `{ updated: <event summary> }` | `Calendars.ReadWrite` |
|
|
127
131
|
| `m365-graph:copy_file` | Async copy with polling. POSTs to `/items/{id}/copy`, polls the monitor URL with exponential backoff (1s → 2s → … capped at 30s) until completion. Falls back to `list-by-name` if the monitor's completed response omits `resourceLocation` (common Graph quirk). | `item_id` + `target_parent_id` (required); `source_drive_id?`, `target_drive_id?`, `new_name?`, `wait_max_seconds?` (1–1800, default 300) | `{ status: "completed", copied: { id, name, ... } }` | `Files.ReadWrite` |
|
|
@@ -135,7 +139,7 @@ Step 8.5 cross-check semantics.
|
|
|
135
139
|
|
|
136
140
|
¹ **Admin consent required.** `OnlineMeetings.Read` and `OnlineMeetingTranscript.Read.All` must be granted in the Entra app registration under **API permissions → Add a permission → Microsoft Graph → Delegated → Grant admin consent**. Without admin consent these tools return 403 Forbidden.
|
|
137
141
|
|
|
138
|
-
That's 4 read +
|
|
142
|
+
That's 4 read + 5 write on files, 5 read + 4 write on calendars, 2 read on meeting transcripts — **20 tools total**. Read tools exercise delegated `Files.Read` + `Calendars.Read`; write tools require `Files.ReadWrite` + `Calendars.ReadWrite`; transcript tools require `OnlineMeetings.Read` + `OnlineMeetingTranscript.Read.All` (all separately granted + admin-consented in the Entra app).
|
|
139
143
|
|
|
140
144
|
## Local development
|
|
141
145
|
|
|
@@ -35,4 +35,5 @@ export type ConsumeResult = {
|
|
|
35
35
|
};
|
|
36
36
|
export declare function consumeConfirmation(token: string, toolName: string, spec: Record<string, unknown>): ConsumeResult;
|
|
37
37
|
export declare function _resetConfirmationTokens(): void;
|
|
38
|
+
export declare function _injectExpiredConfirmation(token: string, toolName: string, spec: Record<string, unknown>): void;
|
|
38
39
|
//# sourceMappingURL=confirmation_tokens.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirmation_tokens.d.ts","sourceRoot":"","sources":["../../src/auth/confirmation_tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAmCH,MAAM,WAAW,WAAW;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,WAAW,CAcb;AAED,MAAM,MAAM,YAAY,GACpB,eAAe,GACf,eAAe,GACf,kBAAkB,GAClB,eAAe,CAAC;AAEpB,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC;AAEvC,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,aAAa,
|
|
1
|
+
{"version":3,"file":"confirmation_tokens.d.ts","sourceRoot":"","sources":["../../src/auth/confirmation_tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAmCH,MAAM,WAAW,WAAW;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,WAAW,CAcb;AAED,MAAM,MAAM,YAAY,GACpB,eAAe,GACf,eAAe,GACf,kBAAkB,GAClB,eAAe,CAAC;AAEpB,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC;AAEvC,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,aAAa,CA4Bf;AAID,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAID,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,IAAI,CAMN"}
|
|
@@ -59,14 +59,24 @@ export function issueConfirmation(toolName, spec) {
|
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
export function consumeConfirmation(token, toolName, spec) {
|
|
62
|
-
|
|
62
|
+
// Look up the token BEFORE the periodic GC pass so an expired-but-
|
|
63
|
+
// still-recorded entry reports as `token_expired`, not `token_unknown`
|
|
64
|
+
// — the two states are semantically distinct (expired says "you're
|
|
65
|
+
// late"; unknown says "there's no such token"). Only after this
|
|
66
|
+
// lookup do we GC other stale entries. For a security-relevant two-
|
|
67
|
+
// phase gate (delete_file, cancel_event, decline_event) this matters
|
|
68
|
+
// for the caller-facing UX and for audit signal fidelity.
|
|
63
69
|
const entry = pending.get(token);
|
|
64
|
-
if (!entry)
|
|
70
|
+
if (!entry) {
|
|
71
|
+
gc();
|
|
65
72
|
return { ok: false, error: "token_unknown" };
|
|
73
|
+
}
|
|
66
74
|
if (entry.expiresAt <= Date.now()) {
|
|
67
75
|
pending.delete(token);
|
|
76
|
+
gc();
|
|
68
77
|
return { ok: false, error: "token_expired" };
|
|
69
78
|
}
|
|
79
|
+
gc();
|
|
70
80
|
if (entry.toolName !== toolName) {
|
|
71
81
|
return { ok: false, error: "token_wrong_tool" };
|
|
72
82
|
}
|
|
@@ -82,4 +92,13 @@ export function consumeConfirmation(token, toolName, spec) {
|
|
|
82
92
|
export function _resetConfirmationTokens() {
|
|
83
93
|
pending.clear();
|
|
84
94
|
}
|
|
95
|
+
// Test helper — inject a pre-expired token so expiry paths can be
|
|
96
|
+
// exercised deterministically without racing wall-clock time.
|
|
97
|
+
export function _injectExpiredConfirmation(token, toolName, spec) {
|
|
98
|
+
pending.set(token, {
|
|
99
|
+
toolName,
|
|
100
|
+
specHash: hashSpec(spec),
|
|
101
|
+
expiresAt: Date.now() - 1_000,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
85
104
|
//# sourceMappingURL=confirmation_tokens.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirmation_tokens.js","sourceRoot":"","sources":["../../src/auth/confirmation_tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAQhC,MAAM,OAAO,GAAqC,IAAI,GAAG,EAAE,CAAC;AAE5D,SAAS,YAAY,CAAC,IAA6B;IACjD,oEAAoE;IACpE,qEAAqE;IACrE,iDAAiD;IACjD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,UAAU;QAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,QAAQ,CAAC,IAA6B;IAC7C,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,EAAE;IACT,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,CAAC,SAAS,IAAI,GAAG;YAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAQD,MAAM,UAAU,iBAAiB,CAC/B,QAAgB,EAChB,IAA6B;IAE7B,EAAE,EAAE,CAAC;IACL,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE;QACjB,QAAQ;QACR,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC;QACxB,SAAS;KACV,CAAC,CAAC;IACH,OAAO;QACL,kBAAkB,EAAE,KAAK;QACzB,UAAU,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;QAC7C,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;KACjD,CAAC;AACJ,CAAC;AAYD,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,QAAgB,EAChB,IAA6B;IAE7B,
|
|
1
|
+
{"version":3,"file":"confirmation_tokens.js","sourceRoot":"","sources":["../../src/auth/confirmation_tokens.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/msal.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Tokens persist in the OS keychain via `src/auth/keyring.ts`. The MSAL
|
|
10
10
|
* cache plugin pattern is: load on first access, save when it changes.
|
|
11
11
|
*/
|
|
12
|
-
import { ConfidentialClientApplication, type ICachePlugin } from "@azure/msal-node";
|
|
12
|
+
import { ConfidentialClientApplication, type AuthorizationCodeRequest, type AuthorizationUrlRequest, type Configuration, type ICachePlugin } from "@azure/msal-node";
|
|
13
13
|
/**
|
|
14
14
|
* Delegated scopes the MCP server requests. Order is irrelevant; MSAL
|
|
15
15
|
* normalizes. `offline_access` is required to get a refresh token.
|
|
@@ -25,13 +25,39 @@ export declare const DELEGATED_SCOPES: string[];
|
|
|
25
25
|
* app registration. See README § Local development.
|
|
26
26
|
*/
|
|
27
27
|
export declare const REDIRECT_URI = "http://localhost:3000/auth/callback";
|
|
28
|
+
/**
|
|
29
|
+
* Authorization-URL request used by `setup`. Deliberately no `nonce`
|
|
30
|
+
* and no `responseMode`:
|
|
31
|
+
* - the confidential-client `getAuthCodeUrl` defaults to
|
|
32
|
+
* `response_mode=query`, which is what the setup localhost listener
|
|
33
|
+
* reads (GET `?code=`);
|
|
34
|
+
* - `acquireTokenByCode` (msal-node ≥ 5.6) validates the ID-token
|
|
35
|
+
* nonce strictly — if a nonce were sent here it would also have to be
|
|
36
|
+
* passed to the code exchange, otherwise the exchange fails with
|
|
37
|
+
* `nonce_mismatch`. Sending none keeps the two requests consistent.
|
|
38
|
+
* Pinned by tests/unit/msal_contract.test.ts.
|
|
39
|
+
*/
|
|
40
|
+
export declare function authCodeUrlRequest(): AuthorizationUrlRequest;
|
|
41
|
+
/** Code-exchange request used by `setup`; mirrors authCodeUrlRequest(). */
|
|
42
|
+
export declare function authCodeTokenRequest(code: string): AuthorizationCodeRequest;
|
|
28
43
|
/**
|
|
29
44
|
* Build the MSAL cache plugin for a given tenant. Exported so tests
|
|
30
45
|
* can drive the load/save lifecycle directly with a fake
|
|
31
46
|
* TokenCacheContext + spied keychain store.
|
|
32
47
|
*/
|
|
33
48
|
export declare function makeCachePlugin(tenantId: string): ICachePlugin;
|
|
34
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Optional, additive overrides. Production calls `makeMsalClient()` with
|
|
51
|
+
* none; tests pass offline authority/cloud-discovery metadata and a fake
|
|
52
|
+
* network module so the real MSAL code paths run without a tenant.
|
|
53
|
+
* Credentials, authority and cache plugin are never overridable here.
|
|
54
|
+
*/
|
|
55
|
+
export interface MsalClientOverrides {
|
|
56
|
+
authorityMetadata?: string;
|
|
57
|
+
cloudDiscoveryMetadata?: string;
|
|
58
|
+
system?: Configuration["system"];
|
|
59
|
+
}
|
|
60
|
+
export declare function makeMsalClient(overrides?: MsalClientOverrides): ConfidentialClientApplication;
|
|
35
61
|
/**
|
|
36
62
|
* Acquire an access token silently from the cache. Refreshes via the
|
|
37
63
|
* cached refresh token if the access token is expired. Throws if no
|
package/dist/auth/msal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"msal.d.ts","sourceRoot":"","sources":["../../src/auth/msal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,6BAA6B,
|
|
1
|
+
{"version":3,"file":"msal.d.ts","sourceRoot":"","sources":["../../src/auth/msal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,6BAA6B,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,YAAY,EAElB,MAAM,kBAAkB,CAAC;AAI1B;;;;;;;GAOG;AAcH,eAAO,MAAM,gBAAgB,UAQ5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,wCAAwC,CAAC;AAElE;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,IAAI,uBAAuB,CAM5D;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,wBAAwB,CAM3E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAe9D;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;CAClC;AAED,wBAAgB,cAAc,CAAC,SAAS,GAAE,mBAAwB,GAAG,6BAA6B,CAoBjG;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,MAAM,CAAC,CAoBjB"}
|
package/dist/auth/msal.js
CHANGED
|
@@ -47,6 +47,33 @@ export const DELEGATED_SCOPES = [
|
|
|
47
47
|
* app registration. See README § Local development.
|
|
48
48
|
*/
|
|
49
49
|
export const REDIRECT_URI = "http://localhost:3000/auth/callback";
|
|
50
|
+
/**
|
|
51
|
+
* Authorization-URL request used by `setup`. Deliberately no `nonce`
|
|
52
|
+
* and no `responseMode`:
|
|
53
|
+
* - the confidential-client `getAuthCodeUrl` defaults to
|
|
54
|
+
* `response_mode=query`, which is what the setup localhost listener
|
|
55
|
+
* reads (GET `?code=`);
|
|
56
|
+
* - `acquireTokenByCode` (msal-node ≥ 5.6) validates the ID-token
|
|
57
|
+
* nonce strictly — if a nonce were sent here it would also have to be
|
|
58
|
+
* passed to the code exchange, otherwise the exchange fails with
|
|
59
|
+
* `nonce_mismatch`. Sending none keeps the two requests consistent.
|
|
60
|
+
* Pinned by tests/unit/msal_contract.test.ts.
|
|
61
|
+
*/
|
|
62
|
+
export function authCodeUrlRequest() {
|
|
63
|
+
return {
|
|
64
|
+
scopes: DELEGATED_SCOPES,
|
|
65
|
+
redirectUri: REDIRECT_URI,
|
|
66
|
+
prompt: "select_account",
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Code-exchange request used by `setup`; mirrors authCodeUrlRequest(). */
|
|
70
|
+
export function authCodeTokenRequest(code) {
|
|
71
|
+
return {
|
|
72
|
+
code,
|
|
73
|
+
scopes: DELEGATED_SCOPES,
|
|
74
|
+
redirectUri: REDIRECT_URI,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
50
77
|
/**
|
|
51
78
|
* Build the MSAL cache plugin for a given tenant. Exported so tests
|
|
52
79
|
* can drive the load/save lifecycle directly with a fake
|
|
@@ -68,17 +95,24 @@ export function makeCachePlugin(tenantId) {
|
|
|
68
95
|
},
|
|
69
96
|
};
|
|
70
97
|
}
|
|
71
|
-
export function makeMsalClient() {
|
|
98
|
+
export function makeMsalClient(overrides = {}) {
|
|
72
99
|
const tenantId = process.env.M365_TENANT_ID ?? "";
|
|
73
100
|
const config = {
|
|
74
101
|
auth: {
|
|
75
102
|
clientId: process.env.M365_CLIENT_ID ?? "",
|
|
76
103
|
clientSecret: process.env.M365_CLIENT_SECRET ?? "",
|
|
77
104
|
authority: `https://login.microsoftonline.com/${tenantId}`,
|
|
105
|
+
...(overrides.authorityMetadata !== undefined
|
|
106
|
+
? { authorityMetadata: overrides.authorityMetadata }
|
|
107
|
+
: {}),
|
|
108
|
+
...(overrides.cloudDiscoveryMetadata !== undefined
|
|
109
|
+
? { cloudDiscoveryMetadata: overrides.cloudDiscoveryMetadata }
|
|
110
|
+
: {}),
|
|
78
111
|
},
|
|
79
112
|
cache: {
|
|
80
113
|
cachePlugin: makeCachePlugin(tenantId),
|
|
81
114
|
},
|
|
115
|
+
...(overrides.system !== undefined ? { system: overrides.system } : {}),
|
|
82
116
|
};
|
|
83
117
|
return new ConfidentialClientApplication(config);
|
|
84
118
|
}
|
package/dist/auth/msal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"msal.js","sourceRoot":"","sources":["../../src/auth/msal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,6BAA6B,
|
|
1
|
+
{"version":3,"file":"msal.js","sourceRoot":"","sources":["../../src/auth/msal.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/auth/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/auth/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAuFH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CA4B9C"}
|
package/dist/auth/setup.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import { exec } from "node:child_process";
|
|
18
18
|
import http from "node:http";
|
|
19
19
|
import { URL } from "node:url";
|
|
20
|
-
import {
|
|
20
|
+
import { REDIRECT_URI, authCodeTokenRequest, authCodeUrlRequest, makeMsalClient, } from "./msal.js";
|
|
21
21
|
const CALLBACK_PORT = 3000;
|
|
22
22
|
const CALLBACK_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
23
23
|
function openInBrowser(url) {
|
|
@@ -78,11 +78,7 @@ function waitForAuthCode() {
|
|
|
78
78
|
}
|
|
79
79
|
export async function runSetup() {
|
|
80
80
|
const client = makeMsalClient();
|
|
81
|
-
const authUrl = await client.getAuthCodeUrl(
|
|
82
|
-
scopes: DELEGATED_SCOPES,
|
|
83
|
-
redirectUri: REDIRECT_URI,
|
|
84
|
-
prompt: "select_account",
|
|
85
|
-
});
|
|
81
|
+
const authUrl = await client.getAuthCodeUrl(authCodeUrlRequest());
|
|
86
82
|
console.error("[setup] Starting OAuth flow against tenant:", process.env.M365_TENANT_ID);
|
|
87
83
|
console.error("[setup] If your browser does not open automatically, visit:");
|
|
88
84
|
console.error("");
|
|
@@ -93,11 +89,7 @@ export async function runSetup() {
|
|
|
93
89
|
openInBrowser(authUrl);
|
|
94
90
|
const code = await waitForAuthCode();
|
|
95
91
|
console.error("[setup] Authorization code received. Exchanging for tokens…");
|
|
96
|
-
const tokenResponse = await client.acquireTokenByCode(
|
|
97
|
-
code,
|
|
98
|
-
scopes: DELEGATED_SCOPES,
|
|
99
|
-
redirectUri: REDIRECT_URI,
|
|
100
|
-
});
|
|
92
|
+
const tokenResponse = await client.acquireTokenByCode(authCodeTokenRequest(code));
|
|
101
93
|
if (!tokenResponse?.account) {
|
|
102
94
|
throw new Error("Token acquisition succeeded but no account info was returned.");
|
|
103
95
|
}
|
package/dist/auth/setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/auth/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,OAAO,
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/auth/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool: m365-graph:create_folder
|
|
3
|
+
*
|
|
4
|
+
* Create a folder in a drive (OneDrive primary by default; SharePoint
|
|
5
|
+
* document library via `drive_id`). Wraps Graph's synchronous
|
|
6
|
+
* children-POST:
|
|
7
|
+
*
|
|
8
|
+
* POST /me/drive/root/children (root of primary OneDrive)
|
|
9
|
+
* POST /me/drive/items/{parent-id}/children (nested)
|
|
10
|
+
* POST /drives/{drive-id}/root/children (non-default drive)
|
|
11
|
+
* POST /drives/{drive-id}/items/{parent-id}/children (nested)
|
|
12
|
+
*
|
|
13
|
+
* Body:
|
|
14
|
+
* {
|
|
15
|
+
* "name": "<name>",
|
|
16
|
+
* "folder": {},
|
|
17
|
+
* "@microsoft.graph.conflictBehavior": "fail" | "replace" | "rename"
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* Conflict behavior — deliberately restricted to two values:
|
|
21
|
+
* - `fail` (default) — refuse if an item with that name exists
|
|
22
|
+
* - `rename` — let Graph auto-suffix (`Foo` → `Foo 1`)
|
|
23
|
+
*
|
|
24
|
+
* `replace` is NOT exposed. Graph would accept it, but replacing an
|
|
25
|
+
* existing folder is a rare, near-destructive intent (the existing
|
|
26
|
+
* folder — potentially with content — is displaced) that would push
|
|
27
|
+
* this tool from `write_idempotent` toward `write_irreversible`
|
|
28
|
+
* semantics and force a two-phase confirmation gate. Excluded by
|
|
29
|
+
* design; if a caller truly needs replacement they compose it from
|
|
30
|
+
* `delete_file` (already two-phase-gated) + `create_folder`.
|
|
31
|
+
*
|
|
32
|
+
* Category: `write_idempotent` — a repeated call with
|
|
33
|
+
* `conflict_behavior: fail` returns an error rather than creating a
|
|
34
|
+
* duplicate; the created folder is reversible via `delete_file`. No
|
|
35
|
+
* two-phase confirmation needed (creation, not destruction).
|
|
36
|
+
*
|
|
37
|
+
* Required Graph scope: `Files.ReadWrite` (delegated) for OneDrive;
|
|
38
|
+
* `Sites.ReadWrite.All` (delegated) for SharePoint document libraries.
|
|
39
|
+
* Both are already requested by src/auth/msal.ts as of v0.4.0.
|
|
40
|
+
*
|
|
41
|
+
* Path/name notes:
|
|
42
|
+
* - We only address the parent by ID (`parent_item_id`), consistent
|
|
43
|
+
* with the rest of the file-tool surface. Path-string addressing
|
|
44
|
+
* is intentionally out of scope.
|
|
45
|
+
* - Names with leading underscore (`_SDI-ufficiali`) or spaces
|
|
46
|
+
* (`New Folder`) are legal in OneDrive/SharePoint doc libraries;
|
|
47
|
+
* we pass through unmodified. Reserved characters (`\ / : * ? " <
|
|
48
|
+
* > |`) and reserved DOS-style names (CON, PRN, etc.) are rejected
|
|
49
|
+
* by Graph with a 400 that surfaces back to the agent as a clear
|
|
50
|
+
* error — no client-side sanitization that would silently mutate
|
|
51
|
+
* the requested name.
|
|
52
|
+
*/
|
|
53
|
+
import type { Tool } from "../types/tool.js";
|
|
54
|
+
interface CreatedFolderSummary {
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
webUrl: string;
|
|
58
|
+
parent_id: string | null;
|
|
59
|
+
child_count: number;
|
|
60
|
+
}
|
|
61
|
+
export declare function summarizeCreatedFolder(item: Record<string, unknown>): CreatedFolderSummary;
|
|
62
|
+
export declare const createFolderTool: Tool;
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=create_folder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_folder.d.ts","sourceRoot":"","sources":["../../src/tools/create_folder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AASH,OAAO,KAAK,EAAE,IAAI,EAA6C,MAAM,kBAAkB,CAAC;AAsCxF,UAAU,oBAAoB;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,oBAAoB,CAU1F;AAmDD,eAAO,MAAM,gBAAgB,EAAE,IAA4D,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool: m365-graph:create_folder
|
|
3
|
+
*
|
|
4
|
+
* Create a folder in a drive (OneDrive primary by default; SharePoint
|
|
5
|
+
* document library via `drive_id`). Wraps Graph's synchronous
|
|
6
|
+
* children-POST:
|
|
7
|
+
*
|
|
8
|
+
* POST /me/drive/root/children (root of primary OneDrive)
|
|
9
|
+
* POST /me/drive/items/{parent-id}/children (nested)
|
|
10
|
+
* POST /drives/{drive-id}/root/children (non-default drive)
|
|
11
|
+
* POST /drives/{drive-id}/items/{parent-id}/children (nested)
|
|
12
|
+
*
|
|
13
|
+
* Body:
|
|
14
|
+
* {
|
|
15
|
+
* "name": "<name>",
|
|
16
|
+
* "folder": {},
|
|
17
|
+
* "@microsoft.graph.conflictBehavior": "fail" | "replace" | "rename"
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* Conflict behavior — deliberately restricted to two values:
|
|
21
|
+
* - `fail` (default) — refuse if an item with that name exists
|
|
22
|
+
* - `rename` — let Graph auto-suffix (`Foo` → `Foo 1`)
|
|
23
|
+
*
|
|
24
|
+
* `replace` is NOT exposed. Graph would accept it, but replacing an
|
|
25
|
+
* existing folder is a rare, near-destructive intent (the existing
|
|
26
|
+
* folder — potentially with content — is displaced) that would push
|
|
27
|
+
* this tool from `write_idempotent` toward `write_irreversible`
|
|
28
|
+
* semantics and force a two-phase confirmation gate. Excluded by
|
|
29
|
+
* design; if a caller truly needs replacement they compose it from
|
|
30
|
+
* `delete_file` (already two-phase-gated) + `create_folder`.
|
|
31
|
+
*
|
|
32
|
+
* Category: `write_idempotent` — a repeated call with
|
|
33
|
+
* `conflict_behavior: fail` returns an error rather than creating a
|
|
34
|
+
* duplicate; the created folder is reversible via `delete_file`. No
|
|
35
|
+
* two-phase confirmation needed (creation, not destruction).
|
|
36
|
+
*
|
|
37
|
+
* Required Graph scope: `Files.ReadWrite` (delegated) for OneDrive;
|
|
38
|
+
* `Sites.ReadWrite.All` (delegated) for SharePoint document libraries.
|
|
39
|
+
* Both are already requested by src/auth/msal.ts as of v0.4.0.
|
|
40
|
+
*
|
|
41
|
+
* Path/name notes:
|
|
42
|
+
* - We only address the parent by ID (`parent_item_id`), consistent
|
|
43
|
+
* with the rest of the file-tool surface. Path-string addressing
|
|
44
|
+
* is intentionally out of scope.
|
|
45
|
+
* - Names with leading underscore (`_SDI-ufficiali`) or spaces
|
|
46
|
+
* (`New Folder`) are legal in OneDrive/SharePoint doc libraries;
|
|
47
|
+
* we pass through unmodified. Reserved characters (`\ / : * ? " <
|
|
48
|
+
* > |`) and reserved DOS-style names (CON, PRN, etc.) are rejected
|
|
49
|
+
* by Graph with a 400 that surfaces back to the agent as a clear
|
|
50
|
+
* error — no client-side sanitization that would silently mutate
|
|
51
|
+
* the requested name.
|
|
52
|
+
*/
|
|
53
|
+
import { validateOptionalEnum, validateOptionalString, validateRequiredString, } from "../types/validators.js";
|
|
54
|
+
const CONFLICT_BEHAVIORS = ["fail", "rename"];
|
|
55
|
+
const definition = {
|
|
56
|
+
name: "m365-graph:create_folder",
|
|
57
|
+
description: "Create a folder in a drive (OneDrive primary by default; SharePoint document library via drive_id). Synchronous POST to /children. Default conflict behavior is 'fail' — set to 'rename' to auto-suffix on collision. 'replace' is intentionally not supported (replacing an existing folder is near-destructive; compose delete_file + create_folder if you truly need replacement). Returns the created folder's item ID so it can be passed as parent_item_id to a subsequent upload_file / create_folder call.",
|
|
58
|
+
inputSchema: {
|
|
59
|
+
type: "object",
|
|
60
|
+
properties: {
|
|
61
|
+
name: {
|
|
62
|
+
type: "string",
|
|
63
|
+
description: "Folder name to create. Passed through unmodified — Graph rejects reserved characters (\\ / : * ? \" < > |) with a 400 the agent can act on.",
|
|
64
|
+
},
|
|
65
|
+
parent_item_id: {
|
|
66
|
+
type: "string",
|
|
67
|
+
description: "Optional parent folder ID to create INTO. Defaults to the drive root. Get from list_items.",
|
|
68
|
+
},
|
|
69
|
+
drive_id: {
|
|
70
|
+
type: "string",
|
|
71
|
+
description: "Optional drive ID. Defaults to the user's primary OneDrive. Use for SharePoint document libraries.",
|
|
72
|
+
},
|
|
73
|
+
conflict_behavior: {
|
|
74
|
+
type: "string",
|
|
75
|
+
enum: ["fail", "rename"],
|
|
76
|
+
description: "What to do if an item with this name already exists in the parent. 'fail' (default) refuses; 'rename' lets Graph auto-suffix (Foo → Foo 1). 'replace' is intentionally not exposed — see tool description.",
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
required: ["name"],
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
export function summarizeCreatedFolder(item) {
|
|
83
|
+
const parent = item.parentReference;
|
|
84
|
+
const folder = item.folder;
|
|
85
|
+
return {
|
|
86
|
+
id: String(item.id ?? ""),
|
|
87
|
+
name: String(item.name ?? ""),
|
|
88
|
+
webUrl: String(item.webUrl ?? ""),
|
|
89
|
+
parent_id: parent?.id ?? null,
|
|
90
|
+
child_count: Number(folder?.childCount ?? 0),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const handler = async (graph, args) => {
|
|
94
|
+
const name = validateRequiredString(args.name, "name");
|
|
95
|
+
const parentItemId = validateOptionalString(args.parent_item_id, "parent_item_id");
|
|
96
|
+
const driveId = validateOptionalString(args.drive_id, "drive_id");
|
|
97
|
+
const conflictBehavior = validateOptionalEnum(args.conflict_behavior, "conflict_behavior", CONFLICT_BEHAVIORS, "fail");
|
|
98
|
+
const drivePath = driveId ? `/drives/${encodeURIComponent(driveId)}` : "/me/drive";
|
|
99
|
+
const parentPath = parentItemId
|
|
100
|
+
? `${drivePath}/items/${encodeURIComponent(parentItemId)}/children`
|
|
101
|
+
: `${drivePath}/root/children`;
|
|
102
|
+
const body = {
|
|
103
|
+
name,
|
|
104
|
+
folder: {},
|
|
105
|
+
"@microsoft.graph.conflictBehavior": conflictBehavior,
|
|
106
|
+
};
|
|
107
|
+
console.error(`[m365-graph-mcp-server] create_folder: ${drivePath}/${parentItemId ?? "<root>"}/${name} (conflict=${conflictBehavior})`);
|
|
108
|
+
const created = (await graph.api(parentPath).post(body));
|
|
109
|
+
return {
|
|
110
|
+
content: [
|
|
111
|
+
{
|
|
112
|
+
type: "text",
|
|
113
|
+
text: JSON.stringify({
|
|
114
|
+
drive_id: driveId ?? null,
|
|
115
|
+
parent_item_id: parentItemId ?? null,
|
|
116
|
+
created: summarizeCreatedFolder(created),
|
|
117
|
+
}, null, 2),
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
export const createFolderTool = { category: "write_idempotent", definition, handler };
|
|
123
|
+
//# sourceMappingURL=create_folder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_folder.js","sourceRoot":"","sources":["../../src/tools/create_folder.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AA2B7C,eAAO,MAAM,SAAS,EAAE,aAAa,CAAC,IAAI,CA0BzC,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAMxF"}
|
package/dist/tools/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { listItemsTool } from "./list_items.js";
|
|
|
14
14
|
import { searchFilesTool } from "./search_files.js";
|
|
15
15
|
// Files — write
|
|
16
16
|
import { copyFileTool } from "./copy_file.js";
|
|
17
|
+
import { createFolderTool } from "./create_folder.js";
|
|
17
18
|
import { deleteFileTool } from "./delete_file.js";
|
|
18
19
|
import { moveFileTool } from "./move_file.js";
|
|
19
20
|
import { uploadFileTool } from "./upload_file.js";
|
|
@@ -39,6 +40,7 @@ export const ALL_TOOLS = [
|
|
|
39
40
|
downloadFileTool,
|
|
40
41
|
// Files — write
|
|
41
42
|
uploadFileTool,
|
|
43
|
+
createFolderTool,
|
|
42
44
|
copyFileTool,
|
|
43
45
|
moveFileTool,
|
|
44
46
|
deleteFileTool,
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,eAAe;AACf,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,mBAAmB;AACnB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,gCAAgC;AAChC,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,CAAC,MAAM,SAAS,GAAwB;IAC5C,eAAe;IACf,cAAc;IACd,aAAa;IACb,eAAe;IACf,gBAAgB;IAChB,gBAAgB;IAChB,cAAc;IACd,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,mBAAmB;IACnB,iBAAiB;IACjB,cAAc;IACd,gBAAgB;IAChB,uBAAuB;IACvB,YAAY;IACZ,gCAAgC;IAChC,0BAA0B;IAC1B,iBAAiB;IACjB,oBAAoB;IACpB,eAAe;IACf,eAAe;IACf,eAAe;IACf,gBAAgB;CACjB,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,KAA0B;IACxD,MAAM,CAAC,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,eAAe;AACf,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,mBAAmB;AACnB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,gCAAgC;AAChC,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,CAAC,MAAM,SAAS,GAAwB;IAC5C,eAAe;IACf,cAAc;IACd,aAAa;IACb,eAAe;IACf,gBAAgB;IAChB,gBAAgB;IAChB,cAAc;IACd,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,mBAAmB;IACnB,iBAAiB;IACjB,cAAc;IACd,gBAAgB;IAChB,uBAAuB;IACvB,YAAY;IACZ,gCAAgC;IAChC,0BAA0B;IAC1B,iBAAiB;IACjB,oBAAoB;IACpB,eAAe;IACf,eAAe;IACf,eAAe;IACf,gBAAgB;CACjB,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,KAA0B;IACxD,MAAM,CAAC,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juvantlabs/m365-graph-mcp-server",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "Microsoft Graph MCP server — OneDrive, SharePoint, and Calendar read+write for Juvant OS agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Juvant Srls",
|
|
@@ -35,25 +35,26 @@
|
|
|
35
35
|
"audit": "npm audit --audit-level=moderate"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@azure/msal-node": "^
|
|
38
|
+
"@azure/msal-node": "^7.1.2",
|
|
39
39
|
"@microsoft/microsoft-graph-client": "^3.0.7",
|
|
40
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
40
|
+
"@modelcontextprotocol/sdk": "^1.32.2",
|
|
41
41
|
"@napi-rs/keyring": "^1.3.0",
|
|
42
42
|
"isomorphic-fetch": "^3.0.0"
|
|
43
43
|
},
|
|
44
44
|
"overrides": {
|
|
45
|
-
"ip-address": ">=10.2.0"
|
|
45
|
+
"ip-address": ">=10.2.0",
|
|
46
|
+
"minimatch": "^11.0.1"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@types/isomorphic-fetch": "^0.0.39",
|
|
49
50
|
"@types/node": "^20.0.0",
|
|
50
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
51
|
-
"@typescript-eslint/parser": "^8.
|
|
52
|
-
"@vitest/coverage-v8": "^
|
|
53
|
-
"eslint": "^
|
|
54
|
-
"tsx": "^4.
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^8.72.1",
|
|
52
|
+
"@typescript-eslint/parser": "^8.72.1",
|
|
53
|
+
"@vitest/coverage-v8": "^4.1.12",
|
|
54
|
+
"eslint": "^10.14.0",
|
|
55
|
+
"tsx": "^4.23.15",
|
|
55
56
|
"typescript": "^5.4.0",
|
|
56
|
-
"vitest": "^
|
|
57
|
+
"vitest": "^4.1.12"
|
|
57
58
|
},
|
|
58
59
|
"publishConfig": {
|
|
59
60
|
"access": "public"
|