@theronap/agnoclast-mcp 0.9.235 → 0.9.237

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/lib/grep_cli.mjs CHANGED
@@ -54,8 +54,12 @@ export function formatGrepHits(payload, query) {
54
54
  : `${hits.length} match${hits.length === 1 ? '' : 'es'} for "${query}":`
55
55
  const lines = [header, '']
56
56
  for (const h of hits) {
57
+ // Records (server 2026-10-15, ADR-0081) arrive in the same list, already labelled in the title.
58
+ const isRecord = h.kind === 'record'
57
59
  const head = h.heading ? ` > ${h.heading}` : ''
58
- lines.push(`- ${h.title}${head} [${h.tier}]`)
60
+ lines.push(isRecord
61
+ ? `- ${h.title}${h.brain && h.brain.name ? ` · ${h.brain.name}` : ''}\n read_record ${(h.record && h.record.id) || h.documentId}`
62
+ : `- [page] ${h.title}${head} [${h.tier}]`)
59
63
  if (h.snippet) lines.push(` ${String(h.snippet).replace(/\s+/g, ' ').trim()}`)
60
64
  // Cap the link list per hit. Median is 2 but the tail reaches 32, and at ~126 chars/hit the
61
65
  // link lists were the second-largest cost in the payload after snippets. The count is kept so
@@ -63,7 +67,7 @@ export function formatGrepHits(payload, query) {
63
67
  if (h.links && h.links.length) {
64
68
  const shown = h.links.slice(0, LINKS_PER_HIT)
65
69
  const more = h.links.length - shown.length
66
- lines.push(` -> ${shown.map((l) => `[[${l}]]`).join(' ')}${more > 0 ? ` (+${more} more)` : ''}`)
70
+ lines.push(` ${isRecord ? 'filed on' : '->'} ${shown.map((l) => `[[${l}]]`).join(' ')}${more > 0 ? ` (+${more} more)` : ''}`)
67
71
  }
68
72
  }
69
73
  return lines.join('\n')
@@ -50,7 +50,7 @@ export function renderRecord(rec, maxChars = READ_RECORD_DEFAULT_CHARS, part = '
50
50
  out.push('')
51
51
  }
52
52
  if (notes && want === 'notes') {
53
- out.push(`Full transcript: ${content.length.toLocaleString('en-US')} characters, not shown. Call read_record with part: "transcript" when you need the exact words; grep and search already cover it.`)
53
+ out.push(`Full transcript: ${content.length.toLocaleString('en-US')} characters, not shown. Call read_record with part: "transcript" when you need the exact words; grep and search cover the transcript too.`)
54
54
  } else if (!content.trim()) {
55
55
  out.push('(No content was captured for this record.)')
56
56
  } else if (content.length > cap) {
package/lib/server.mjs CHANGED
@@ -1998,9 +1998,9 @@ function renderNudge(payload) {
1998
1998
  server.registerTool(
1999
1999
  'grep',
2000
2000
  {
2001
- title: 'Grep the brain wiki',
2001
+ title: 'Grep pages and records',
2002
2002
  description:
2003
- 'Ranked keyword search across your visible brain wiki pages. Multi-word natural-language queries work (results are ranked by relevance). Pass mode:"substring" for an exact literal match of symbols, identifiers, or [[links]] — and for an English STOPWORD ("own", "not"), which ranked search drops. Returns matching sections with a context snippet and their outbound [[links]]. A broad query fans out across every brain you can see, so pass `max` when you only need to locate a page; the header always says how many matched in total, so a capped list is never mistaken for the whole answer.',
2003
+ 'Ranked keyword search across your visible brain wiki pages AND the records filed in your brains (meeting/lecture transcripts and their notes, emails, sessions, messages) — one list, each hit labelled [page] or [record · type · date] with its id and the pages it is filed on. An empty result means neither a page nor a record mentions it. Multi-word natural-language queries work (results are ranked by relevance). Pass mode:"substring" for an exact literal match of symbols, identifiers, or [[links]] — and for an English STOPWORD ("own", "not"), which ranked search drops. Returns matching sections with a context snippet and their outbound [[links]]. A broad query fans out across every brain you can see, so pass `max` when you only need to locate a page; the header always says how many matched in total, so a capped list is never mistaken for the whole answer.',
2004
2004
  inputSchema: {
2005
2005
  query: z.string().describe('search terms (natural language is fine)'),
2006
2006
  mode: z.enum(['substring', 'fts']).optional().describe("'fts' (default, ranked keyword) or 'substring' (exact literal — for identifiers / [[links]] / code)"),
@@ -4769,8 +4769,8 @@ function renderNudge(payload) {
4769
4769
  'that does not exist. ' +
4770
4770
  'A meeting or lecture transcript has TWO LAYERS: notes (the gist, decisions, action items) and the full ' +
4771
4771
  'transcript. By default you get the NOTES and the transcript\'s length; read the notes first, and ask for ' +
4772
- 'part: "transcript" only when you need the exact words. To FIND something said in a meeting, grep and ' +
4773
- 'search already cover the transcript.',
4772
+ 'part: "transcript" only when you need the exact words. To FIND something said in a meeting, grep ' +
4773
+ 'and search cover the transcript too (notes rank first).',
4774
4774
  inputSchema: {
4775
4775
  id: z.string().describe('the record id, from list_records, my_day, timeline_pull or another read_record'),
4776
4776
  max_chars: z.number().optional().describe(`cap on the content shown (default ${READ_RECORD_DEFAULT_CHARS}); the reply says how much was left out`),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theronap/agnoclast-mcp",
3
- "version": "0.9.235",
3
+ "version": "0.9.237",
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": {