@theronap/cortex-mcp 0.9.125 → 0.9.126

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 (2) hide show
  1. package/lib/server.mjs +53 -0
  2. package/package.json +1 -1
package/lib/server.mjs CHANGED
@@ -1940,6 +1940,59 @@ function renderNudge(payload) {
1940
1940
  },
1941
1941
  )
1942
1942
 
1943
+ server.registerTool(
1944
+ 'discard_staged',
1945
+ {
1946
+ title: 'Discard staged arrivals in bulk — reversibly',
1947
+ description: "Mark staged arrivals as discarded, addressed BY IDENTIFIER (every arrival that address is holding) or by explicit staged ids. The counterpart to `place_staged_record`, which takes one row at a time and needs pages — right for an arrival worth keeping, wrong for a queue where one unclaimed address holds 68-199 arrivals and most of them are simply not wanted. ⚠ REVERSIBLE, unlike `intake_discard`: this sets a state and destroys NOTHING (the row keeps its raw_body and the message is still in the source mailbox), so pass `restore: true` to undo. That is what makes a bulk verb safe here — classifying thousands of correspondents guarantees being wrong about some. ⚠ DRY-RUN BY DEFAULT: it reports what it WOULD change and changes nothing until you pass `apply: true`, and the dry-run count is the same set the apply writes. Use `staged_records` first to see the ranking.",
1948
+ inputSchema: {
1949
+ identifiers: z.array(z.string()).optional().describe('discard every pending arrival blocked on any of these, e.g. ["email:venmo@venmo.com"]'),
1950
+ staged_ids: z.array(z.string()).optional().describe('discard these specific arrivals'),
1951
+ apply: z.boolean().optional().describe('false/absent = dry run (default). true actually writes.'),
1952
+ restore: z.boolean().optional().describe('true = put previously discarded arrivals back in the queue'),
1953
+ },
1954
+ },
1955
+ async ({ identifiers, staged_ids, apply, restore }) => {
1956
+ if (!identifiers?.length && !staged_ids?.length) {
1957
+ return toolError('Pass `identifiers` or `staged_ids` — an empty call is refused rather than treated as "everything".')
1958
+ }
1959
+ let res
1960
+ try {
1961
+ res = await fetchCortex(`${BASE}/api/staged/discard`, {
1962
+ method: 'POST',
1963
+ headers: { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json' },
1964
+ body: JSON.stringify({ identifiers, stagedIds: staged_ids, apply: apply === true, restore: restore === true }),
1965
+ })
1966
+ } catch (e) {
1967
+ return toolError(`Could not reach the staged queue: ${e.message}`)
1968
+ }
1969
+ const out = await res.json().catch(() => null)
1970
+ if (!res.ok) return toolError(`Could not ${restore ? 'restore' : 'discard'}: ${out?.hint ?? out?.error ?? res.status}`)
1971
+ if (!out) return toolError('The server returned no body.')
1972
+
1973
+ const verb = out.restore ? 'restore' : 'discard'
1974
+ const lines = []
1975
+ if (out.mode === 'dry-run') {
1976
+ lines.push(`DRY RUN — nothing changed. Would ${verb} ${out.matched} arrival(s).`)
1977
+ lines.push('Re-run with apply: true to do it.')
1978
+ } else {
1979
+ lines.push(`${out.changed} arrival(s) ${out.restore ? 'restored to the queue' : 'discarded'}.`)
1980
+ if (!out.restore) lines.push('Reversible — discard_staged with restore: true puts them back.')
1981
+ }
1982
+ if (out.unmatchedIdentifiers?.length) {
1983
+ lines.push('', `⚠ matched NOTHING (already drained, or a typo): ${out.unmatchedIdentifiers.join(', ')}`)
1984
+ }
1985
+ if (out.sample?.length) {
1986
+ lines.push('', 'Sample:')
1987
+ for (const r of out.sample.slice(0, 10)) {
1988
+ lines.push(` ${r.occurredAt?.slice(0, 10) ?? ''} ${r.title ?? '(no subject)'}`)
1989
+ }
1990
+ if (out.matched > out.sample.length) lines.push(` … and ${out.matched - out.sample.length} more`)
1991
+ }
1992
+ return { content: [{ type: 'text', text: lines.join('\n') }] }
1993
+ },
1994
+ )
1995
+
1943
1996
  server.registerTool(
1944
1997
  'place_staged_record',
1945
1998
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theronap/cortex-mcp",
3
- "version": "0.9.125",
3
+ "version": "0.9.126",
4
4
  "description": "Connect your AI assistant to Cortex — your org's projects, activity, gaps, and directives, scoped to you.",
5
5
  "type": "module",
6
6
  "bin": {