@gmickel/gno 1.18.0 → 1.19.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.
- package/README.md +5 -3
- package/assets/skill/SKILL.md +27 -0
- package/package.json +2 -1
- package/spec/AGENTS.md +83 -0
- package/spec/CLAUDE.md +83 -0
- package/spec/bench-fixture.schema.json +137 -0
- package/spec/cli.md +2894 -0
- package/spec/db/schema.sql +442 -0
- package/spec/evals-agentic.md +510 -0
- package/spec/evals.md +1106 -0
- package/spec/mcp.md +2229 -0
- package/spec/output-schemas/activation-verification.schema.json +515 -0
- package/spec/output-schemas/ask.schema.json +366 -0
- package/spec/output-schemas/backlinks.schema.json +131 -0
- package/spec/output-schemas/bench-result.schema.json +120 -0
- package/spec/output-schemas/capture-receipt.schema.json +143 -0
- package/spec/output-schemas/collection-list.schema.json +45 -0
- package/spec/output-schemas/context-capsule-v1.schema.json +691 -0
- package/spec/output-schemas/context-capsule-verification.schema.json +1338 -0
- package/spec/output-schemas/context-list.schema.json +21 -0
- package/spec/output-schemas/doctor.schema.json +313 -0
- package/spec/output-schemas/error.schema.json +30 -0
- package/spec/output-schemas/expansion.schema.json +37 -0
- package/spec/output-schemas/get.schema.json +140 -0
- package/spec/output-schemas/graph-query.schema.json +99 -0
- package/spec/output-schemas/graph.schema.json +371 -0
- package/spec/output-schemas/links-list.schema.json +186 -0
- package/spec/output-schemas/mcp-add-collection-result.schema.json +23 -0
- package/spec/output-schemas/mcp-capture-result.schema.json +152 -0
- package/spec/output-schemas/mcp-http-error.schema.json +30 -0
- package/spec/output-schemas/mcp-job-list.schema.json +58 -0
- package/spec/output-schemas/mcp-job-status.schema.json +224 -0
- package/spec/output-schemas/mcp-remove-result.schema.json +39 -0
- package/spec/output-schemas/mcp-sync-result.schema.json +41 -0
- package/spec/output-schemas/mcp-tag-result.schema.json +33 -0
- package/spec/output-schemas/models-list.schema.json +93 -0
- package/spec/output-schemas/multi-get.schema.json +103 -0
- package/spec/output-schemas/process-status.schema.json +119 -0
- package/spec/output-schemas/query-diagnose.schema.json +123 -0
- package/spec/output-schemas/resident-status.schema.json +154 -0
- package/spec/output-schemas/retrieval-trace-common.schema.json +492 -0
- package/spec/output-schemas/retrieval-trace-delete.schema.json +16 -0
- package/spec/output-schemas/retrieval-trace-export.schema.json +61 -0
- package/spec/output-schemas/retrieval-trace-filters.schema.json +139 -0
- package/spec/output-schemas/retrieval-trace-judgment.schema.json +15 -0
- package/spec/output-schemas/retrieval-trace-list.schema.json +18 -0
- package/spec/output-schemas/retrieval-trace-payloads.schema.json +178 -0
- package/spec/output-schemas/retrieval-trace-purge.schema.json +31 -0
- package/spec/output-schemas/retrieval-trace-qrels.schema.json +303 -0
- package/spec/output-schemas/retrieval-trace-replay.schema.json +286 -0
- package/spec/output-schemas/retrieval-trace-show.schema.json +69 -0
- package/spec/output-schemas/retrieval-trace-summary.schema.json +65 -0
- package/spec/output-schemas/search-result.schema.json +154 -0
- package/spec/output-schemas/search-results.schema.json +338 -0
- package/spec/output-schemas/similar.schema.json +84 -0
- package/spec/output-schemas/status.schema.json +676 -0
- package/spec/output-schemas/tags-list.schema.json +48 -0
- package/src/app/context-runtime-types.ts +3 -0
- package/src/app/context-runtime.ts +15 -1
- package/src/cli/commands/ask.ts +106 -36
- package/src/cli/commands/context-build.ts +56 -9
- package/src/cli/commands/get.ts +64 -3
- package/src/cli/commands/query.ts +62 -23
- package/src/cli/commands/replay.ts +140 -0
- package/src/cli/commands/search.ts +48 -3
- package/src/cli/commands/shared.ts +3 -1
- package/src/cli/commands/trace.ts +200 -0
- package/src/cli/commands/vsearch.ts +75 -53
- package/src/cli/program.ts +255 -0
- package/src/config/index.ts +9 -0
- package/src/config/retrieval-traces.ts +56 -0
- package/src/config/types.ts +4 -0
- package/src/core/context-compiler.ts +11 -4
- package/src/core/retrieval-qrels.ts +405 -0
- package/src/core/retrieval-replay-candidate.ts +368 -0
- package/src/core/retrieval-replay-types.ts +109 -0
- package/src/core/retrieval-replay-validation.ts +89 -0
- package/src/core/retrieval-replay.ts +441 -0
- package/src/core/retrieval-trace-evidence-origin.ts +175 -0
- package/src/core/retrieval-trace-export.ts +113 -0
- package/src/core/retrieval-trace-filter-normalization.ts +27 -0
- package/src/core/retrieval-trace-filters.ts +19 -0
- package/src/core/retrieval-trace-management-helpers.ts +247 -0
- package/src/core/retrieval-trace-management-types.ts +132 -0
- package/src/core/retrieval-trace-management.ts +422 -0
- package/src/core/retrieval-trace-request.ts +141 -0
- package/src/core/retrieval-trace-session.ts +494 -0
- package/src/core/retrieval-trace.ts +472 -0
- package/src/mcp/tools/context.ts +59 -8
- package/src/mcp/tools/get.ts +35 -1
- package/src/mcp/tools/index.ts +74 -0
- package/src/mcp/tools/query.ts +95 -64
- package/src/mcp/tools/search.ts +36 -13
- package/src/mcp/tools/trace.ts +143 -0
- package/src/mcp/tools/vsearch.ts +71 -38
- package/src/pipeline/answer.ts +167 -26
- package/src/pipeline/graph-retrieval.ts +15 -1
- package/src/pipeline/hybrid.ts +151 -43
- package/src/pipeline/search.ts +36 -3
- package/src/pipeline/trace-metadata.ts +47 -0
- package/src/pipeline/types.ts +43 -0
- package/src/pipeline/vsearch.ts +101 -38
- package/src/sdk/client.ts +380 -71
- package/src/sdk/documents.ts +48 -1
- package/src/sdk/index.ts +17 -0
- package/src/sdk/types.ts +28 -0
- package/src/serve/context-capsule.ts +67 -8
- package/src/serve/public/app.tsx +12 -1
- package/src/serve/public/globals.built.css +1 -1
- package/src/serve/public/lib/workspace-tabs.ts +2 -0
- package/src/serve/public/pages/Dashboard.tsx +10 -0
- package/src/serve/public/pages/TraceHistory.tsx +478 -0
- package/src/serve/public/pages/trace-history-detail.tsx +224 -0
- package/src/serve/retrieval-trace.ts +28 -0
- package/src/serve/routes/api.ts +366 -72
- package/src/serve/routes/traces.ts +156 -0
- package/src/serve/server.ts +87 -2
- package/src/store/index.ts +31 -0
- package/src/store/migrations/014-retrieval-traces.ts +303 -0
- package/src/store/migrations/index.ts +2 -0
- package/src/store/retrieval-trace-codec.ts +384 -0
- package/src/store/sqlite/adapter.ts +153 -1
- package/src/store/sqlite/retrieval-trace-management-store.ts +341 -0
- package/src/store/sqlite/retrieval-trace-retention.ts +349 -0
- package/src/store/sqlite/retrieval-trace-rows.ts +267 -0
- package/src/store/sqlite/retrieval-trace-store.ts +515 -0
- package/src/store/types.ts +297 -0
- package/src/store/vector/sqlite-vec.ts +76 -1
- package/src/store/vector/types.ts +1 -1
package/spec/mcp.md
ADDED
|
@@ -0,0 +1,2229 @@
|
|
|
1
|
+
# GNO MCP Specification
|
|
2
|
+
|
|
3
|
+
**Version:** 1.0.0
|
|
4
|
+
**Last Updated:** 2026-04-24
|
|
5
|
+
**Protocol:** Model Context Protocol (MCP) 2025-11-25
|
|
6
|
+
**Transport:** JSON-RPC 2.0 over stdio or resident Streamable HTTP
|
|
7
|
+
|
|
8
|
+
This document specifies the MCP server interface for GNO.
|
|
9
|
+
|
|
10
|
+
## Server Information
|
|
11
|
+
|
|
12
|
+
| Property | Value |
|
|
13
|
+
| --------- | -------------------- |
|
|
14
|
+
| Name | `gno` |
|
|
15
|
+
| Version | `1.0.0` |
|
|
16
|
+
| Command | `gno mcp` |
|
|
17
|
+
| Transport | stdio (stdin/stdout) |
|
|
18
|
+
|
|
19
|
+
## Capabilities
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"capabilities": {
|
|
24
|
+
"tools": {
|
|
25
|
+
"listChanged": false
|
|
26
|
+
},
|
|
27
|
+
"resources": {
|
|
28
|
+
"subscribe": false,
|
|
29
|
+
"listChanged": false
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Security Model
|
|
38
|
+
|
|
39
|
+
### Write Tool Gating
|
|
40
|
+
|
|
41
|
+
Write tools are **disabled by default**. Enable explicitly:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
gno mcp --enable-write
|
|
45
|
+
# or
|
|
46
|
+
GNO_MCP_ENABLE_WRITE=1 gno mcp
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
When disabled, write tools are not registered and cannot be invoked.
|
|
50
|
+
|
|
51
|
+
### Collection Root Validation
|
|
52
|
+
|
|
53
|
+
`gno_add_collection` rejects dangerous roots to avoid indexing broad/system paths:
|
|
54
|
+
|
|
55
|
+
- `/` (root)
|
|
56
|
+
- `~` (entire home dir)
|
|
57
|
+
- `/etc`, `/usr`, `/bin`, `/var`, `/System`, `/Library`
|
|
58
|
+
- `~/.config`, `~/.local`, `~/.ssh`, `~/.gnupg`
|
|
59
|
+
|
|
60
|
+
### Write Lock
|
|
61
|
+
|
|
62
|
+
All write tools acquire an OS-backed advisory lock at `.mcp-write.lock` under the index directory.
|
|
63
|
+
If another process holds the lock, tools return `LOCKED`.
|
|
64
|
+
For async jobs, the lock is held for the full job duration.
|
|
65
|
+
|
|
66
|
+
### Resident Streamable HTTP boundary
|
|
67
|
+
|
|
68
|
+
`gno serve` and `gno daemon` mount the same stateful MCP surface at `/mcp`.
|
|
69
|
+
The default listener is the literal IPv4 loopback address `127.0.0.1`. Each
|
|
70
|
+
HTTP session owns one SDK server and transport while sharing the resident
|
|
71
|
+
store, jobs, and model lifecycle. POST, GET, and DELETE follow MCP 2025-11-25;
|
|
72
|
+
resumption is not advertised.
|
|
73
|
+
|
|
74
|
+
The external boundary runs before JSON parsing or SDK dispatch on every HTTP
|
|
75
|
+
method. It uses Bun `server.requestIP(request)` as the peer source and never
|
|
76
|
+
trusts `Forwarded` or `X-Forwarded-*`. Host and present Origin headers must
|
|
77
|
+
match exact allowlists. Loopback defaults allow only the selected port on
|
|
78
|
+
`127.0.0.1` and `localhost` (or explicit `::1`).
|
|
79
|
+
|
|
80
|
+
Wildcard and non-loopback binds fail startup unless all three controls exist:
|
|
81
|
+
|
|
82
|
+
- a bearer token file readable only by its owner (`0600` or stricter on POSIX),
|
|
83
|
+
- at least one exact Host value, and
|
|
84
|
+
- at least one exact HTTP(S) Origin.
|
|
85
|
+
|
|
86
|
+
An explicitly configured missing token file is generated with a random 256-bit
|
|
87
|
+
token and restrictive creation mode. The token is never printed or included in
|
|
88
|
+
errors. Rotation, deletion, invalid content, or permission relaxation revokes
|
|
89
|
+
existing authenticated sessions. Session IDs are bound to the identity that
|
|
90
|
+
initialized them, preventing reuse with a different bearer token.
|
|
91
|
+
|
|
92
|
+
Because `gno serve` shares this listener with its Web UI and REST API, it
|
|
93
|
+
remains loopback-only. Use the headless `gno daemon` command for an explicitly
|
|
94
|
+
authenticated non-loopback MCP listener.
|
|
95
|
+
|
|
96
|
+
HTTP MCP remains read-only unless `gateway.enableWrite: true` or
|
|
97
|
+
`--mcp-enable-write` is explicitly set. Bearer authentication alone does not
|
|
98
|
+
authorize mutation. Unauthorized calls to write tools fail with HTTP 403 before
|
|
99
|
+
SDK dispatch.
|
|
100
|
+
|
|
101
|
+
Boundary failures use the closed
|
|
102
|
+
[`mcp-http-error`](./output-schemas/mcp-http-error.schema.json) body with stable,
|
|
103
|
+
redacted statuses: 401 (authentication), 403 (peer/Host/Origin/write), 413
|
|
104
|
+
(declared or streamed body), 429 (rate/request/queue/session pressure), and 503
|
|
105
|
+
(shutdown, revoked credentials, or unavailable runtime). Defaults are 1 MiB per
|
|
106
|
+
POST body, 120 requests/minute per actual peer, 64 active requests, 16 queued
|
|
107
|
+
requests, 32 sessions, and a five-minute idle session timeout.
|
|
108
|
+
|
|
109
|
+
### Packaged gateway conformance
|
|
110
|
+
|
|
111
|
+
`bun run test:package` installs the generated npm tarball into an isolated
|
|
112
|
+
environment and exercises the shipped binary. It proves two concurrent HTTP
|
|
113
|
+
MCP clients plus one stdio client observe equivalent tools, resources, and
|
|
114
|
+
search results; repeated HTTP calls reuse the same resident store and model
|
|
115
|
+
lifecycle. The same run validates the redacted resident-status schema,
|
|
116
|
+
loopback-only app-status boundary, Host/Origin,
|
|
117
|
+
body-size, bearer-token, token-rotation, session-identity, and write-authorization
|
|
118
|
+
boundaries, daemon-only authenticated non-loopback binding, and detached
|
|
119
|
+
restart/shutdown behavior. Windows package and binary artifact jobs remain the
|
|
120
|
+
final platform-specific sweep for detach rejection and known interrupt exits.
|
|
121
|
+
|
|
122
|
+
## Collection Name Rules
|
|
123
|
+
|
|
124
|
+
Collection names are case-insensitive on input and normalized to lowercase in responses.
|
|
125
|
+
|
|
126
|
+
## Job Management
|
|
127
|
+
|
|
128
|
+
- Single active job per MCP server process
|
|
129
|
+
- Completed job retention: 1 hour, max 100 entries
|
|
130
|
+
- Jobs are in-memory per process (lost on restart)
|
|
131
|
+
- Poll with `gno_job_status`; if the job is missing after restart, return `NOT_FOUND`
|
|
132
|
+
|
|
133
|
+
## Tools
|
|
134
|
+
|
|
135
|
+
### Agent Retrieval Playbook
|
|
136
|
+
|
|
137
|
+
- Prefer `gno_context` when the agent needs a complete, bounded evidence handoff
|
|
138
|
+
for one goal. It compiles exact source spans, coverage gaps, omissions, and
|
|
139
|
+
verification fingerprints in one call.
|
|
140
|
+
- Prefer `gno_query` for normal questions. It is the default hybrid path and returns `uri`, `docid`, snippets, and `line` anchors for follow-up reads.
|
|
141
|
+
- Use `gno_search` for exact phrases, filenames, identifiers, error messages, and known symbols.
|
|
142
|
+
- Use `gno_vsearch` for semantic similarity when wording differs and embeddings are current.
|
|
143
|
+
- Use `intent` to disambiguate short or overloaded terms without changing the searched text.
|
|
144
|
+
- Use `queryModes` when the caller has typed retrieval text: `term` for lexical anchors, `intent` for disambiguation, and at most one `hyde` hypothetical answer/document.
|
|
145
|
+
- Use `gno_query_diagnose` when a specific important document is missing from results or when you need per-stage retrieval evidence before changing query strategy.
|
|
146
|
+
- Use `gno_graph_query` for bounded typed-edge traversal over `doc_edges`; keep `gno_graph_neighbors`/`gno_graph_path` for the legacy graph projection.
|
|
147
|
+
- After search/query returns a `line`, call `gno_get` with `fromLine` and `lineCount` before fetching whole documents.
|
|
148
|
+
- Use `gno_multi_get` to batch the top result refs. Keep `maxBytes` bounded to avoid flooding client context.
|
|
149
|
+
- Check `gno_status` when results look stale, vector search is unavailable, or embedding backlog may explain missing results.
|
|
150
|
+
|
|
151
|
+
### Private retrieval metadata
|
|
152
|
+
|
|
153
|
+
When local tracing is enabled, successful `gno_search`, `gno_vsearch`,
|
|
154
|
+
`gno_query`, `gno_get`, and `gno_context` results include non-model-visible
|
|
155
|
+
top-level response metadata:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"_meta": {
|
|
160
|
+
"gno": {
|
|
161
|
+
"retrievalTrace": {
|
|
162
|
+
"traceId": "..."
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`structuredContent` and model-visible `content` are unchanged. `gno_get`
|
|
170
|
+
accepts optional `traceId` to continue an open retrieval trace and records
|
|
171
|
+
evidence only when a valid exact line range is returned. Out-of-range and
|
|
172
|
+
failed gets never fabricate evidence. Disabled tracing omits `_meta` and does
|
|
173
|
+
no trace ID or fingerprint work.
|
|
174
|
+
|
|
175
|
+
Trace receipt management is split into read and mutation tool names so HTTP
|
|
176
|
+
authorization can reject mutations before dispatch:
|
|
177
|
+
|
|
178
|
+
| Tool | Class | Contract |
|
|
179
|
+
| ------------------ | -------- | ---------------------------------------------------------- |
|
|
180
|
+
| `gno_trace_list` | read | Bounded cursor page; summaries omit replay query/goal text |
|
|
181
|
+
| `gno_trace_show` | read | One bounded detail receipt with exact totals/truncation |
|
|
182
|
+
| `gno_trace_label` | mutation | Explicit relevant/irrelevant/missing_expected judgment |
|
|
183
|
+
| `gno_trace_export` | mutation | Deterministic multi-trace `agentic-receipt` |
|
|
184
|
+
| `gno_trace_delete` | mutation | Delete one trace and owned records |
|
|
185
|
+
| `gno_trace_purge` | mutation | Delete all receipts; requires `confirm: true` |
|
|
186
|
+
|
|
187
|
+
Read tools are always registered. Mutation tools are registered only when
|
|
188
|
+
`enableWrite` is true and every handler rechecks that state. HTTP MCP also
|
|
189
|
+
classifies all four mutation names in its pre-dispatch write set. A bearer
|
|
190
|
+
identity authenticates a principal but never grants trace-write authority.
|
|
191
|
+
Denied calls return `403`/`WRITE_DISABLED` without echoing trace content.
|
|
192
|
+
|
|
193
|
+
Relevant and irrelevant targets must resolve to exact recorded evidence.
|
|
194
|
+
`missing_expected` accepts only a safe document identity, never raw document
|
|
195
|
+
content or a filesystem path. Aggregate exports reject open/missing traces and
|
|
196
|
+
preserve each stored terminal state without treating partial, failed, or
|
|
197
|
+
cancelled as negative feedback.
|
|
198
|
+
|
|
199
|
+
### gno_context
|
|
200
|
+
|
|
201
|
+
Compile a deterministic, extractive Context Capsule. The active MCP server
|
|
202
|
+
supplies the canonical index name; callers cannot switch indexes in the request.
|
|
203
|
+
The complete canonical payload—not each document independently—must fit the
|
|
204
|
+
requested token and optional byte budget.
|
|
205
|
+
|
|
206
|
+
Required input:
|
|
207
|
+
|
|
208
|
+
```json
|
|
209
|
+
{
|
|
210
|
+
"goal": "Compare the launch proposals",
|
|
211
|
+
"budgetTokens": 12000
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Optional input fields are `query`, `collections`, `uriPrefix`, `queryModes`,
|
|
216
|
+
`tagsAll`, `tagsAny`, `categories`, `author`, `lang`, `since`, `until`, `graph`,
|
|
217
|
+
`limit`, `candidateLimit`, `budgetBytes`, `safetyMarginTokens`,
|
|
218
|
+
`safetyMarginBytes`, `depthPolicy` (`fast`, `balanced`, or `thorough`), and
|
|
219
|
+
`format` (`json` or `md`). Input objects are closed: unknown fields return
|
|
220
|
+
`invalid_input`. Unknown collections return `invalid_filter` before model or
|
|
221
|
+
retrieval setup. Tag filters are NFC-normalized, lowercased, deduplicated, and
|
|
222
|
+
validated before retrieval. `limit` and `candidateLimit` are global across all
|
|
223
|
+
requested collections: result admission is capped after merging, and
|
|
224
|
+
rerank/graph candidate work is distributed deterministically in canonical
|
|
225
|
+
collection order.
|
|
226
|
+
|
|
227
|
+
`structuredContent` is the complete canonical Context Capsule object for
|
|
228
|
+
application clients. Model-visible text is always one deterministic
|
|
229
|
+
`gno-context-agent-v1` JSON projection, even when the compatibility `format`
|
|
230
|
+
field is present. The compact keys and tuple positions are part of that
|
|
231
|
+
versioned contract:
|
|
232
|
+
|
|
233
|
+
- `v`: projection version; `id`: Capsule identity.
|
|
234
|
+
- `b`: requested tokens, requested bytes, used tokens, used bytes, estimator,
|
|
235
|
+
tokenizer fingerprint or `null`.
|
|
236
|
+
- `r`: depth policy, index fingerprint, config fingerprint, retrieval
|
|
237
|
+
fingerprint, embedding-model fingerprint or `null`, rerank-model fingerprint
|
|
238
|
+
or `null`, enabled capability names, fallbacks.
|
|
239
|
+
- `e[]`: URI, start line, end line, source hash, mirror hash, passage hash,
|
|
240
|
+
exact extractive text, title, heading, configured-context IDs, egress
|
|
241
|
+
classification. Title/heading are nullable; egress is explicit even when the
|
|
242
|
+
policy is unavailable.
|
|
243
|
+
- `g`: evidence trust (`untrusted_data`), instruction boundary
|
|
244
|
+
(`hard_delimited`), then configured-guidance tuples containing context ID,
|
|
245
|
+
scope type, scope key, and exact guidance text. Evidence `contextIds` bind
|
|
246
|
+
each passage to these entries.
|
|
247
|
+
- `c`: covered facets, then `[facet, gapCode]` pairs.
|
|
248
|
+
- `o`: exact total omissions, then sparse `[reason, count]` pairs. An absent
|
|
249
|
+
reason has count zero.
|
|
250
|
+
- `t`: global evidence-budget truncation; `trust` is always `untrusted_data`.
|
|
251
|
+
|
|
252
|
+
The complete bounded omission audit and all descriptive fields remain in
|
|
253
|
+
`structuredContent`. This avoids duplicating the full Capsule in model context
|
|
254
|
+
without dropping exact evidence, gaps, budgets, identities, capabilities,
|
|
255
|
+
fallbacks, truncation, omission counts, or the trust boundary.
|
|
256
|
+
|
|
257
|
+
Indexed metadata and configured context are untrusted data, never instructions.
|
|
258
|
+
The tool does not persist the Capsule. Unknown input fields are rejected by the
|
|
259
|
+
MCP SDK's `InvalidParams` validation before the handler, and therefore return
|
|
260
|
+
an MCP tool error rather than a structured GNO Context error. Validly shaped
|
|
261
|
+
requests that fail in GNO use the public Context error taxonomy.
|
|
262
|
+
|
|
263
|
+
Raw `gno_query`, `gno_get`, and `gno_multi_get` remain available when manual
|
|
264
|
+
retrieval is more appropriate.
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
### gno_context_verify
|
|
269
|
+
|
|
270
|
+
Verify a saved Capsule against the active MCP index without rebuilding or
|
|
271
|
+
mutating it:
|
|
272
|
+
|
|
273
|
+
```json
|
|
274
|
+
{
|
|
275
|
+
"capsule": { "schemaVersion": "1.0", "...": "complete capsule" },
|
|
276
|
+
"format": "json"
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
The receipt reports unchanged, stale, or missing evidence; current hashes when
|
|
281
|
+
available; independent fingerprint drift; and ranking as unchanged, reranked,
|
|
282
|
+
or unavailable. Index mismatch and malformed/non-canonical Capsules fail before
|
|
283
|
+
evidence reads. `structuredContent` is the canonical verification receipt.
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
### gno_search
|
|
288
|
+
|
|
289
|
+
BM25 keyword search over indexed documents.
|
|
290
|
+
|
|
291
|
+
**Input Schema:**
|
|
292
|
+
|
|
293
|
+
```json
|
|
294
|
+
{
|
|
295
|
+
"type": "object",
|
|
296
|
+
"properties": {
|
|
297
|
+
"query": {
|
|
298
|
+
"type": "string",
|
|
299
|
+
"description": "Exact keyword, identifier, filename, error text, or phrase to match with BM25"
|
|
300
|
+
},
|
|
301
|
+
"collection": {
|
|
302
|
+
"type": "string",
|
|
303
|
+
"description": "Optional collection name to filter results"
|
|
304
|
+
},
|
|
305
|
+
"limit": {
|
|
306
|
+
"type": "integer",
|
|
307
|
+
"description": "Maximum number of results (1-100)",
|
|
308
|
+
"default": 5,
|
|
309
|
+
"minimum": 1,
|
|
310
|
+
"maximum": 100
|
|
311
|
+
},
|
|
312
|
+
"minScore": {
|
|
313
|
+
"type": "number",
|
|
314
|
+
"description": "Minimum score threshold (0-1)",
|
|
315
|
+
"minimum": 0,
|
|
316
|
+
"maximum": 1
|
|
317
|
+
},
|
|
318
|
+
"lang": {
|
|
319
|
+
"type": "string",
|
|
320
|
+
"description": "Language filter (BCP-47 code)"
|
|
321
|
+
},
|
|
322
|
+
"since": {
|
|
323
|
+
"type": "string",
|
|
324
|
+
"description": "Modified-at lower bound (ISO date/time or relative token)"
|
|
325
|
+
},
|
|
326
|
+
"until": {
|
|
327
|
+
"type": "string",
|
|
328
|
+
"description": "Modified-at upper bound (ISO date/time or relative token)"
|
|
329
|
+
},
|
|
330
|
+
"categories": {
|
|
331
|
+
"type": "array",
|
|
332
|
+
"items": { "type": "string" },
|
|
333
|
+
"description": "Only include docs matching any category/content type"
|
|
334
|
+
},
|
|
335
|
+
"author": {
|
|
336
|
+
"type": "string",
|
|
337
|
+
"description": "Only include docs where author contains this value"
|
|
338
|
+
},
|
|
339
|
+
"tagsAll": {
|
|
340
|
+
"type": "array",
|
|
341
|
+
"items": { "type": "string" },
|
|
342
|
+
"description": "Only include docs with ALL specified tags"
|
|
343
|
+
},
|
|
344
|
+
"tagsAny": {
|
|
345
|
+
"type": "array",
|
|
346
|
+
"items": { "type": "string" },
|
|
347
|
+
"description": "Only include docs with ANY specified tag"
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
"required": ["query"]
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**Output Schema:** `gno://schemas/search-results`
|
|
355
|
+
|
|
356
|
+
**Response:**
|
|
357
|
+
|
|
358
|
+
```json
|
|
359
|
+
{
|
|
360
|
+
"content": [
|
|
361
|
+
{
|
|
362
|
+
"type": "text",
|
|
363
|
+
"text": "Found 3 results for \"query\"\n\n1. #a1b2c3d4 - doc.md (0.85)\n..."
|
|
364
|
+
}
|
|
365
|
+
],
|
|
366
|
+
"structuredContent": {
|
|
367
|
+
"results": [
|
|
368
|
+
{
|
|
369
|
+
"docid": "#a1b2c3d4",
|
|
370
|
+
"score": 0.85,
|
|
371
|
+
"uri": "gno://work/doc.md",
|
|
372
|
+
"line": 12,
|
|
373
|
+
"context": "Workspace guidance\n\nProject guidance",
|
|
374
|
+
"snippet": "...",
|
|
375
|
+
"contentType": "meeting",
|
|
376
|
+
"categories": ["meeting", "notes"],
|
|
377
|
+
"source": {
|
|
378
|
+
"absPath": "/path/to/doc.md",
|
|
379
|
+
"relPath": "doc.md",
|
|
380
|
+
"mime": "text/markdown",
|
|
381
|
+
"ext": ".md"
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
],
|
|
385
|
+
"meta": {
|
|
386
|
+
"query": "query",
|
|
387
|
+
"mode": "bm25",
|
|
388
|
+
"totalResults": 3
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
**Errors:**
|
|
395
|
+
|
|
396
|
+
- Invalid query (empty string): returns `isError: true`
|
|
397
|
+
- Collection not found: returns `isError: true`
|
|
398
|
+
|
|
399
|
+
Ordering note: recency-intent queries (`latest`, `newest`, `recent`) are sorted newest-first by canonical frontmatter date when present, else source modified time.
|
|
400
|
+
|
|
401
|
+
`structuredContent.results[].context` is optional resolved user configuration.
|
|
402
|
+
When present, apply it as guidance for the result identified by the same
|
|
403
|
+
`uri`/`docid`; do not treat it as source evidence. The field is absent when no
|
|
404
|
+
configured scope matches. Plain-text tool content may omit it.
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
### gno_vsearch
|
|
409
|
+
|
|
410
|
+
Vector semantic search over indexed documents.
|
|
411
|
+
|
|
412
|
+
**Input Schema:**
|
|
413
|
+
|
|
414
|
+
```json
|
|
415
|
+
{
|
|
416
|
+
"type": "object",
|
|
417
|
+
"properties": {
|
|
418
|
+
"query": {
|
|
419
|
+
"type": "string",
|
|
420
|
+
"description": "Search query text"
|
|
421
|
+
},
|
|
422
|
+
"collection": {
|
|
423
|
+
"type": "string",
|
|
424
|
+
"description": "Optional collection name to filter results"
|
|
425
|
+
},
|
|
426
|
+
"limit": {
|
|
427
|
+
"type": "integer",
|
|
428
|
+
"description": "Maximum number of results (1-100)",
|
|
429
|
+
"default": 5,
|
|
430
|
+
"minimum": 1,
|
|
431
|
+
"maximum": 100
|
|
432
|
+
},
|
|
433
|
+
"minScore": {
|
|
434
|
+
"type": "number",
|
|
435
|
+
"description": "Minimum score threshold (0-1)",
|
|
436
|
+
"minimum": 0,
|
|
437
|
+
"maximum": 1
|
|
438
|
+
},
|
|
439
|
+
"lang": {
|
|
440
|
+
"type": "string",
|
|
441
|
+
"description": "Language hint for query (BCP-47 code)"
|
|
442
|
+
},
|
|
443
|
+
"intent": {
|
|
444
|
+
"type": "string",
|
|
445
|
+
"description": "Optional disambiguating context for ambiguous queries"
|
|
446
|
+
},
|
|
447
|
+
"exclude": {
|
|
448
|
+
"type": "array",
|
|
449
|
+
"items": { "type": "string" },
|
|
450
|
+
"description": "Hard-prune docs containing any excluded term in title/path/body"
|
|
451
|
+
},
|
|
452
|
+
"since": {
|
|
453
|
+
"type": "string",
|
|
454
|
+
"description": "Modified-at lower bound (ISO date/time or relative token)"
|
|
455
|
+
},
|
|
456
|
+
"until": {
|
|
457
|
+
"type": "string",
|
|
458
|
+
"description": "Modified-at upper bound (ISO date/time or relative token)"
|
|
459
|
+
},
|
|
460
|
+
"categories": {
|
|
461
|
+
"type": "array",
|
|
462
|
+
"items": { "type": "string" },
|
|
463
|
+
"description": "Only include docs matching any category/content type"
|
|
464
|
+
},
|
|
465
|
+
"author": {
|
|
466
|
+
"type": "string",
|
|
467
|
+
"description": "Only include docs where author contains this value"
|
|
468
|
+
},
|
|
469
|
+
"tagsAll": {
|
|
470
|
+
"type": "array",
|
|
471
|
+
"items": { "type": "string" },
|
|
472
|
+
"description": "Only include docs with ALL specified tags"
|
|
473
|
+
},
|
|
474
|
+
"tagsAny": {
|
|
475
|
+
"type": "array",
|
|
476
|
+
"items": { "type": "string" },
|
|
477
|
+
"description": "Only include docs with ANY specified tag"
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
"required": ["query"]
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Output Schema:** `gno://schemas/search-results`
|
|
485
|
+
|
|
486
|
+
**Errors:**
|
|
487
|
+
|
|
488
|
+
- Vectors not available: returns `isError: true` with message suggesting `gno index`
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
### gno_query
|
|
493
|
+
|
|
494
|
+
Hybrid search combining BM25 and vector retrieval with optional expansion and reranking. Recommended default for agent retrieval.
|
|
495
|
+
|
|
496
|
+
**Input Schema:**
|
|
497
|
+
|
|
498
|
+
```json
|
|
499
|
+
{
|
|
500
|
+
"type": "object",
|
|
501
|
+
"properties": {
|
|
502
|
+
"query": {
|
|
503
|
+
"type": "string",
|
|
504
|
+
"description": "Primary user query; combine with intent or queryModes for ambiguous requests"
|
|
505
|
+
},
|
|
506
|
+
"collection": {
|
|
507
|
+
"type": "string",
|
|
508
|
+
"description": "Optional collection name to filter results"
|
|
509
|
+
},
|
|
510
|
+
"limit": {
|
|
511
|
+
"type": "integer",
|
|
512
|
+
"description": "Maximum number of results (1-100)",
|
|
513
|
+
"default": 5,
|
|
514
|
+
"minimum": 1,
|
|
515
|
+
"maximum": 100
|
|
516
|
+
},
|
|
517
|
+
"minScore": {
|
|
518
|
+
"type": "number",
|
|
519
|
+
"description": "Minimum score threshold (0-1)",
|
|
520
|
+
"minimum": 0,
|
|
521
|
+
"maximum": 1
|
|
522
|
+
},
|
|
523
|
+
"lang": {
|
|
524
|
+
"type": "string",
|
|
525
|
+
"description": "Language hint for query (BCP-47 code)"
|
|
526
|
+
},
|
|
527
|
+
"intent": {
|
|
528
|
+
"type": "string",
|
|
529
|
+
"description": "Disambiguating context; steers expansion, rerank, and snippet choice without being searched directly"
|
|
530
|
+
},
|
|
531
|
+
"candidateLimit": {
|
|
532
|
+
"type": "integer",
|
|
533
|
+
"description": "Maximum candidates sent to reranking (1-100); raise for recall, lower for latency",
|
|
534
|
+
"minimum": 1,
|
|
535
|
+
"maximum": 100
|
|
536
|
+
},
|
|
537
|
+
"exclude": {
|
|
538
|
+
"type": "array",
|
|
539
|
+
"items": { "type": "string" },
|
|
540
|
+
"description": "Hard-prune docs containing any excluded term in title/path/body"
|
|
541
|
+
},
|
|
542
|
+
"since": {
|
|
543
|
+
"type": "string",
|
|
544
|
+
"description": "Modified-at lower bound (ISO date/time or relative token)"
|
|
545
|
+
},
|
|
546
|
+
"until": {
|
|
547
|
+
"type": "string",
|
|
548
|
+
"description": "Modified-at upper bound (ISO date/time or relative token)"
|
|
549
|
+
},
|
|
550
|
+
"categories": {
|
|
551
|
+
"type": "array",
|
|
552
|
+
"items": { "type": "string" },
|
|
553
|
+
"description": "Only include docs matching any category/content type"
|
|
554
|
+
},
|
|
555
|
+
"author": {
|
|
556
|
+
"type": "string",
|
|
557
|
+
"description": "Only include docs where author contains this value"
|
|
558
|
+
},
|
|
559
|
+
"queryModes": {
|
|
560
|
+
"type": "array",
|
|
561
|
+
"description": "Typed retrieval entries: term anchors, intent disambiguation, and at most one hyde hypothetical document",
|
|
562
|
+
"items": {
|
|
563
|
+
"type": "object",
|
|
564
|
+
"properties": {
|
|
565
|
+
"mode": {
|
|
566
|
+
"type": "string",
|
|
567
|
+
"enum": ["term", "intent", "hyde"]
|
|
568
|
+
},
|
|
569
|
+
"text": {
|
|
570
|
+
"type": "string",
|
|
571
|
+
"minLength": 1
|
|
572
|
+
}
|
|
573
|
+
},
|
|
574
|
+
"required": ["mode", "text"]
|
|
575
|
+
}
|
|
576
|
+
},
|
|
577
|
+
"expand": {
|
|
578
|
+
"type": "boolean",
|
|
579
|
+
"description": "Enable query expansion (slower, better recall)",
|
|
580
|
+
"default": false
|
|
581
|
+
},
|
|
582
|
+
"rerank": {
|
|
583
|
+
"type": "boolean",
|
|
584
|
+
"description": "Enable cross-encoder reranking",
|
|
585
|
+
"default": true
|
|
586
|
+
},
|
|
587
|
+
"noGraph": {
|
|
588
|
+
"type": "boolean",
|
|
589
|
+
"description": "Compatibility no-op unless graph is also true",
|
|
590
|
+
"default": false
|
|
591
|
+
},
|
|
592
|
+
"graph": {
|
|
593
|
+
"type": "boolean",
|
|
594
|
+
"description": "Enable bounded one-hop graph neighbor expansion",
|
|
595
|
+
"default": false
|
|
596
|
+
},
|
|
597
|
+
"fast": {
|
|
598
|
+
"type": "boolean",
|
|
599
|
+
"description": "Fast mode: skip expansion and reranking (~0.7s)",
|
|
600
|
+
"default": false
|
|
601
|
+
},
|
|
602
|
+
"thorough": {
|
|
603
|
+
"type": "boolean",
|
|
604
|
+
"description": "Thorough mode: enable expansion for broad research or missed recall (~5-8s)",
|
|
605
|
+
"default": false
|
|
606
|
+
},
|
|
607
|
+
"tagsAll": {
|
|
608
|
+
"type": "array",
|
|
609
|
+
"items": { "type": "string" },
|
|
610
|
+
"description": "Only include docs with ALL specified tags"
|
|
611
|
+
},
|
|
612
|
+
"tagsAny": {
|
|
613
|
+
"type": "array",
|
|
614
|
+
"items": { "type": "string" },
|
|
615
|
+
"description": "Only include docs with ANY specified tag"
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
"required": ["query"]
|
|
619
|
+
}
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
**Output Schema:** `gno://schemas/search-results`
|
|
623
|
+
|
|
624
|
+
Validation note: `queryModes[].text` is trimmed and must remain non-empty; only one `mode: "hyde"` entry is allowed.
|
|
625
|
+
|
|
626
|
+
Search result items include `contentType` when available and always include
|
|
627
|
+
`categories` as the category/content-type filter set. Text output remains
|
|
628
|
+
human-oriented; structured clients should read `structuredContent.results`.
|
|
629
|
+
Structured result items also preserve optional `context` guidance in
|
|
630
|
+
global-to-specific order without changing the result `uri` or `docid`.
|
|
631
|
+
|
|
632
|
+
Compatibility / migration notes:
|
|
633
|
+
|
|
634
|
+
- Existing `gno_query` tool calls remain valid without `queryModes`.
|
|
635
|
+
- `intent` is orthogonal to `queryModes`: intent steers scoring/prompting, while query modes inject caller-provided retrieval expansions.
|
|
636
|
+
- `candidateLimit` tunes rerank cost without changing retrieval contracts.
|
|
637
|
+
- `exclude` hard-prunes matching docs after retrieval using title/path/body text.
|
|
638
|
+
- `gno_query` does not use graph expansion by default. Set `graph: true` to add capped one-hop graph neighbors after initial retrieval. Explicit links receive stronger treatment than inferred, ambiguous, or similarity edges.
|
|
639
|
+
- `queryModes` is optional; use it only when clients need explicit retrieval intent control.
|
|
640
|
+
- When `queryModes` is present, generated expansion is skipped and provided entries are used directly.
|
|
641
|
+
|
|
642
|
+
**Response structuredContent includes:**
|
|
643
|
+
|
|
644
|
+
```json
|
|
645
|
+
{
|
|
646
|
+
"results": [
|
|
647
|
+
{
|
|
648
|
+
"docid": "#a1b2c3d4",
|
|
649
|
+
"uri": "gno://work/doc.md",
|
|
650
|
+
"context": "Workspace guidance\n\nProject guidance",
|
|
651
|
+
"contentType": "meeting",
|
|
652
|
+
"categories": ["meeting", "notes"],
|
|
653
|
+
"score": 0.92
|
|
654
|
+
}
|
|
655
|
+
],
|
|
656
|
+
"meta": {
|
|
657
|
+
"query": "query",
|
|
658
|
+
"mode": "hybrid",
|
|
659
|
+
"expanded": true,
|
|
660
|
+
"reranked": true,
|
|
661
|
+
"vectorsUsed": true,
|
|
662
|
+
"totalResults": 5
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
**Graceful Degradation:**
|
|
668
|
+
|
|
669
|
+
- If vectors unavailable: `mode: "bm25_only"`, `vectorsUsed: false`
|
|
670
|
+
- If expansion model unavailable: `expanded: false`
|
|
671
|
+
- If rerank model unavailable: `reranked: false`
|
|
672
|
+
|
|
673
|
+
---
|
|
674
|
+
|
|
675
|
+
### gno_query_diagnose
|
|
676
|
+
|
|
677
|
+
Targeted retrieval diagnostics for one named document. This read-only tool wraps
|
|
678
|
+
`diagnoseQueryTarget()` and uses the same query/filter controls as `gno_query`
|
|
679
|
+
plus a required `target` reference.
|
|
680
|
+
|
|
681
|
+
**Input Schema:** same fields as `gno_query`, plus:
|
|
682
|
+
|
|
683
|
+
```json
|
|
684
|
+
{
|
|
685
|
+
"target": "gno://notes/people/alice.md"
|
|
686
|
+
}
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
- `target`: URI, `#docid`, or `collection/path` for the document to diagnose.
|
|
690
|
+
- `query`, filters, `queryModes`, `fast`/`thorough`, `graph`, and rerank/expand controls behave like `gno_query`.
|
|
691
|
+
|
|
692
|
+
**Output Schema:** `gno://schemas/query-diagnose@1.0`
|
|
693
|
+
|
|
694
|
+
Structured content includes `schemaVersion`, normalized `query`, `target`
|
|
695
|
+
metadata/status (`not_found`, `inactive`, `no_indexed_content`,
|
|
696
|
+
`filtered_out`, or `diagnosed`), `stages` for BM25/vector/fusion/graph/rerank,
|
|
697
|
+
the selected target `chunk`, and retrieval `meta`.
|
|
698
|
+
|
|
699
|
+
Use when an expected target is missing from `gno_query`, when filters may have
|
|
700
|
+
excluded it, or when an agent needs evidence before raising `candidateLimit`,
|
|
701
|
+
changing `queryModes`, enabling graph expansion, or fetching more context.
|
|
702
|
+
For low-latency or CPU-only diagnosis, `fast: true` keeps this MCP tool
|
|
703
|
+
BM25-only and avoids initializing embedding/rerank models.
|
|
704
|
+
|
|
705
|
+
---
|
|
706
|
+
|
|
707
|
+
### gno_get
|
|
708
|
+
|
|
709
|
+
Retrieve a single document by reference.
|
|
710
|
+
|
|
711
|
+
**Input Schema:**
|
|
712
|
+
|
|
713
|
+
```json
|
|
714
|
+
{
|
|
715
|
+
"type": "object",
|
|
716
|
+
"properties": {
|
|
717
|
+
"ref": {
|
|
718
|
+
"type": "string",
|
|
719
|
+
"description": "Document reference: gno:// URI, collection/path, or #docid"
|
|
720
|
+
},
|
|
721
|
+
"fromLine": {
|
|
722
|
+
"type": "integer",
|
|
723
|
+
"description": "Start at line number (1-indexed); use search/query result line anchors",
|
|
724
|
+
"minimum": 1
|
|
725
|
+
},
|
|
726
|
+
"lineCount": {
|
|
727
|
+
"type": "integer",
|
|
728
|
+
"description": "Number of lines to return; prefer a small range before fetching full docs",
|
|
729
|
+
"minimum": 1
|
|
730
|
+
},
|
|
731
|
+
"lineNumbers": {
|
|
732
|
+
"type": "boolean",
|
|
733
|
+
"description": "Include line numbers in content",
|
|
734
|
+
"default": true
|
|
735
|
+
}
|
|
736
|
+
},
|
|
737
|
+
"required": ["ref"]
|
|
738
|
+
}
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
**Output Schema:** `gno://schemas/get`
|
|
742
|
+
|
|
743
|
+
**Response:**
|
|
744
|
+
|
|
745
|
+
```json
|
|
746
|
+
{
|
|
747
|
+
"content": [
|
|
748
|
+
{
|
|
749
|
+
"type": "text",
|
|
750
|
+
"text": "1: # Document Title\n2: \n3: Content here..."
|
|
751
|
+
}
|
|
752
|
+
],
|
|
753
|
+
"structuredContent": {
|
|
754
|
+
"docid": "#a1b2c3d4",
|
|
755
|
+
"uri": "gno://work/doc.md",
|
|
756
|
+
"title": "Document Title",
|
|
757
|
+
"content": "# Document Title\n\nContent here...",
|
|
758
|
+
"totalLines": 150,
|
|
759
|
+
"returnedLines": { "start": 1, "end": 150 },
|
|
760
|
+
"source": {
|
|
761
|
+
"absPath": "/path/to/doc.md",
|
|
762
|
+
"relPath": "doc.md",
|
|
763
|
+
"mime": "text/markdown",
|
|
764
|
+
"ext": ".md",
|
|
765
|
+
"modifiedAt": "2025-12-23T10:00:00Z",
|
|
766
|
+
"sizeBytes": 4096
|
|
767
|
+
},
|
|
768
|
+
"capabilities": {
|
|
769
|
+
"editable": true,
|
|
770
|
+
"tagsEditable": true,
|
|
771
|
+
"tagsWriteback": true,
|
|
772
|
+
"canCreateEditableCopy": false,
|
|
773
|
+
"mode": "editable"
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
**Errors:**
|
|
780
|
+
|
|
781
|
+
- Document not found: returns `isError: true`
|
|
782
|
+
- Invalid ref format: returns `isError: true`
|
|
783
|
+
- Indexed URI names a missing index: returns `isError: true` without creating it
|
|
784
|
+
|
|
785
|
+
For `gno://...?...index=<name>` refs, the tool reads the named index rather than
|
|
786
|
+
the MCP server's active index.
|
|
787
|
+
|
|
788
|
+
`<name>` follows the CLI index-name contract: 1–64 UTF-16 code units drawn from
|
|
789
|
+
Unicode letters, marks, numbers, internal ASCII spaces, `.`, `_`, or `-`; it
|
|
790
|
+
starts with a letter or number, cannot end with a space or `.`, and cannot
|
|
791
|
+
contain `..`. Invalid names are rejected before filesystem access. NFC/case-
|
|
792
|
+
folded equivalents share one logical identity. The canonical identity is
|
|
793
|
+
limited to 242 UTF-8 bytes so `index-<identity>.sqlite` stays within the portable
|
|
794
|
+
255-byte filename-component limit.
|
|
795
|
+
|
|
796
|
+
---
|
|
797
|
+
|
|
798
|
+
### gno_multi_get
|
|
799
|
+
|
|
800
|
+
Retrieve multiple documents by pattern or list.
|
|
801
|
+
|
|
802
|
+
**Input Schema:**
|
|
803
|
+
|
|
804
|
+
```json
|
|
805
|
+
{
|
|
806
|
+
"type": "object",
|
|
807
|
+
"properties": {
|
|
808
|
+
"refs": {
|
|
809
|
+
"type": "array",
|
|
810
|
+
"description": "Array of document references from search/query results (gno:// URIs or docids)",
|
|
811
|
+
"items": {
|
|
812
|
+
"type": "string"
|
|
813
|
+
}
|
|
814
|
+
},
|
|
815
|
+
"pattern": {
|
|
816
|
+
"type": "string",
|
|
817
|
+
"description": "Glob pattern to match documents (alternative to refs)"
|
|
818
|
+
},
|
|
819
|
+
"maxBytes": {
|
|
820
|
+
"type": "integer",
|
|
821
|
+
"description": "Maximum bytes per document before truncation; lower when batching many refs",
|
|
822
|
+
"default": 10240
|
|
823
|
+
},
|
|
824
|
+
"lineNumbers": {
|
|
825
|
+
"type": "boolean",
|
|
826
|
+
"description": "Include line numbers in content",
|
|
827
|
+
"default": true
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
**Note:** Provide either `refs` or `pattern`, not both.
|
|
834
|
+
|
|
835
|
+
All refs in one request must resolve to one index. Explicit refs for different
|
|
836
|
+
indexes, or indexed refs mixed with unindexed refs from another active index,
|
|
837
|
+
return `isError: true`; callers must split the batch by index.
|
|
838
|
+
|
|
839
|
+
**Output Schema:** `gno://schemas/multi-get`
|
|
840
|
+
|
|
841
|
+
**Response:**
|
|
842
|
+
|
|
843
|
+
```json
|
|
844
|
+
{
|
|
845
|
+
"content": [
|
|
846
|
+
{
|
|
847
|
+
"type": "text",
|
|
848
|
+
"text": "Retrieved 3 documents (1 skipped due to size limit)"
|
|
849
|
+
}
|
|
850
|
+
],
|
|
851
|
+
"structuredContent": {
|
|
852
|
+
"documents": [...],
|
|
853
|
+
"skipped": [
|
|
854
|
+
{
|
|
855
|
+
"ref": "gno://work/large.pdf",
|
|
856
|
+
"reason": "exceeds maxBytes"
|
|
857
|
+
}
|
|
858
|
+
],
|
|
859
|
+
"meta": {
|
|
860
|
+
"requested": 4,
|
|
861
|
+
"returned": 3,
|
|
862
|
+
"skipped": 1
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
---
|
|
869
|
+
|
|
870
|
+
### gno_status
|
|
871
|
+
|
|
872
|
+
Get index status and health information.
|
|
873
|
+
|
|
874
|
+
`structuredContent.resident` uses
|
|
875
|
+
`gno://schemas/resident-status@1.0`. HTTP sessions observe the shared
|
|
876
|
+
serve/daemon runtime counters. Stdio remains a standalone lifecycle and reports
|
|
877
|
+
`mode:"stdio"`, `resident:false`, no listener, and zero resident transport
|
|
878
|
+
counters; it never claims attachment to another process.
|
|
879
|
+
|
|
880
|
+
**Input Schema:**
|
|
881
|
+
|
|
882
|
+
```json
|
|
883
|
+
{
|
|
884
|
+
"type": "object",
|
|
885
|
+
"properties": {}
|
|
886
|
+
}
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
**Output Schema:** `gno://schemas/status`
|
|
890
|
+
|
|
891
|
+
**Response:**
|
|
892
|
+
|
|
893
|
+
```json
|
|
894
|
+
{
|
|
895
|
+
"content": [
|
|
896
|
+
{
|
|
897
|
+
"type": "text",
|
|
898
|
+
"text": "Index: default\nCollections: 2\nDocuments: 150\nChunks: 800\nEmbedding backlog: 0"
|
|
899
|
+
}
|
|
900
|
+
],
|
|
901
|
+
"structuredContent": {
|
|
902
|
+
"indexName": "default",
|
|
903
|
+
"collections": [
|
|
904
|
+
{
|
|
905
|
+
"name": "work",
|
|
906
|
+
"documentCount": 100,
|
|
907
|
+
"chunkCount": 500,
|
|
908
|
+
"embeddedCount": 500
|
|
909
|
+
}
|
|
910
|
+
],
|
|
911
|
+
"totalDocuments": 150,
|
|
912
|
+
"totalChunks": 800,
|
|
913
|
+
"embeddingBacklog": 0,
|
|
914
|
+
"healthy": true
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
```
|
|
918
|
+
|
|
919
|
+
---
|
|
920
|
+
|
|
921
|
+
### gno_capture
|
|
922
|
+
|
|
923
|
+
Create a new document in a collection (write-enabled).
|
|
924
|
+
|
|
925
|
+
**Input Schema:**
|
|
926
|
+
|
|
927
|
+
```json
|
|
928
|
+
{
|
|
929
|
+
"type": "object",
|
|
930
|
+
"properties": {
|
|
931
|
+
"collection": {
|
|
932
|
+
"type": "string",
|
|
933
|
+
"description": "Target collection name"
|
|
934
|
+
},
|
|
935
|
+
"content": {
|
|
936
|
+
"type": "string",
|
|
937
|
+
"description": "Document content (markdown). Optional when presetId provides the scaffold."
|
|
938
|
+
},
|
|
939
|
+
"title": {
|
|
940
|
+
"type": "string",
|
|
941
|
+
"description": "Optional title used for filename generation"
|
|
942
|
+
},
|
|
943
|
+
"path": {
|
|
944
|
+
"type": "string",
|
|
945
|
+
"description": "Optional relative path within the collection"
|
|
946
|
+
},
|
|
947
|
+
"folderPath": {
|
|
948
|
+
"type": "string",
|
|
949
|
+
"description": "Optional folder path within the collection"
|
|
950
|
+
},
|
|
951
|
+
"collisionPolicy": {
|
|
952
|
+
"type": "string",
|
|
953
|
+
"enum": ["error", "open_existing", "create_with_suffix"],
|
|
954
|
+
"description": "How to handle name collisions"
|
|
955
|
+
},
|
|
956
|
+
"presetId": {
|
|
957
|
+
"type": "string",
|
|
958
|
+
"enum": [
|
|
959
|
+
"blank",
|
|
960
|
+
"project-note",
|
|
961
|
+
"research-note",
|
|
962
|
+
"decision-note",
|
|
963
|
+
"prompt-pattern",
|
|
964
|
+
"source-summary",
|
|
965
|
+
"idea-original",
|
|
966
|
+
"person",
|
|
967
|
+
"company-project",
|
|
968
|
+
"meeting"
|
|
969
|
+
],
|
|
970
|
+
"description": "Optional note preset scaffold"
|
|
971
|
+
},
|
|
972
|
+
"overwrite": {
|
|
973
|
+
"type": "boolean",
|
|
974
|
+
"description": "Overwrite existing file if true",
|
|
975
|
+
"default": false
|
|
976
|
+
},
|
|
977
|
+
"tags": {
|
|
978
|
+
"type": "array",
|
|
979
|
+
"items": { "type": "string" },
|
|
980
|
+
"description": "Tags to apply to the document"
|
|
981
|
+
},
|
|
982
|
+
"source": {
|
|
983
|
+
"type": "object",
|
|
984
|
+
"description": "Optional provenance metadata; written under structured source frontmatter",
|
|
985
|
+
"properties": {
|
|
986
|
+
"kind": {
|
|
987
|
+
"type": "string",
|
|
988
|
+
"enum": [
|
|
989
|
+
"direct",
|
|
990
|
+
"web",
|
|
991
|
+
"email",
|
|
992
|
+
"meeting",
|
|
993
|
+
"chat",
|
|
994
|
+
"file",
|
|
995
|
+
"api",
|
|
996
|
+
"unknown"
|
|
997
|
+
]
|
|
998
|
+
},
|
|
999
|
+
"title": { "type": "string" },
|
|
1000
|
+
"url": { "type": "string", "format": "uri" },
|
|
1001
|
+
"uri": { "type": "string" },
|
|
1002
|
+
"docid": { "type": "string" },
|
|
1003
|
+
"mime": { "type": "string" },
|
|
1004
|
+
"ext": { "type": "string" },
|
|
1005
|
+
"author": { "type": "string" },
|
|
1006
|
+
"observedAt": { "type": "string", "format": "date-time" },
|
|
1007
|
+
"capturedAt": { "type": "string", "format": "date-time" },
|
|
1008
|
+
"externalId": { "type": "string" }
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
},
|
|
1012
|
+
"required": ["collection"]
|
|
1013
|
+
}
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
**Notes:**
|
|
1017
|
+
|
|
1018
|
+
- Paths must be relative, no `..` escapes, no NUL bytes
|
|
1019
|
+
- Sensitive subpaths are rejected (`.ssh`, `.gnupg`, `.git`, `node_modules`, etc.)
|
|
1020
|
+
- If `path` is omitted, a `.md` filename is generated from the title or heading
|
|
1021
|
+
- `folderPath` lets clients create inside a specific subfolder
|
|
1022
|
+
- `collisionPolicy` supports `error`, `open_existing`, or `create_with_suffix`
|
|
1023
|
+
- Legacy `overwrite: true` overwrites an existing target path and returns
|
|
1024
|
+
`collisionPolicyResult: "overwritten"`; otherwise existing targets follow
|
|
1025
|
+
`collisionPolicy`
|
|
1026
|
+
- `presetId` applies a structured note scaffold before write
|
|
1027
|
+
- Content is required unless `presetId` can scaffold a non-empty note
|
|
1028
|
+
- Content must be text; NUL or binary-like control bytes are rejected
|
|
1029
|
+
- Default generated captures use `inbox/YYYY-MM-DD/capture-<body-hash>.md`
|
|
1030
|
+
- Collision checks include indexed documents and disk-only files
|
|
1031
|
+
- Non-overwrite captures fail instead of replacing a file that appears after
|
|
1032
|
+
planning
|
|
1033
|
+
- Capture writes structured `source:` frontmatter with `kind`, `capturedAt`,
|
|
1034
|
+
and optional `url`, `uri`, `docid`, `mime`, `ext`, `author`, `observedAt`,
|
|
1035
|
+
`externalId`, and `title`
|
|
1036
|
+
- Tags are validated and normalized to lowercase
|
|
1037
|
+
- For Markdown files, tags are added to frontmatter
|
|
1038
|
+
- For non-Markdown files, tags are stored as user-source in the database
|
|
1039
|
+
- Receipts distinguish write result from sync and embedding state; capture does
|
|
1040
|
+
not imply embedding unless `embed.status` is `completed`
|
|
1041
|
+
- Writes run under the MCP write lock and are only registered when the server
|
|
1042
|
+
starts with `--enable-write` or `GNO_MCP_ENABLE_WRITE=1`
|
|
1043
|
+
|
|
1044
|
+
**Output Schema:** `gno://schemas/mcp-capture-result@1.0`, compatible with the
|
|
1045
|
+
shared `gno://schemas/capture-receipt@1.0` contract.
|
|
1046
|
+
|
|
1047
|
+
---
|
|
1048
|
+
|
|
1049
|
+
### gno_list_tags
|
|
1050
|
+
|
|
1051
|
+
List all tags with document counts.
|
|
1052
|
+
|
|
1053
|
+
**Input Schema:**
|
|
1054
|
+
|
|
1055
|
+
```json
|
|
1056
|
+
{
|
|
1057
|
+
"type": "object",
|
|
1058
|
+
"properties": {
|
|
1059
|
+
"collection": {
|
|
1060
|
+
"type": "string",
|
|
1061
|
+
"description": "Filter by collection name"
|
|
1062
|
+
},
|
|
1063
|
+
"prefix": {
|
|
1064
|
+
"type": "string",
|
|
1065
|
+
"description": "Filter by tag prefix (e.g., 'work/' matches 'work/project')"
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
```
|
|
1070
|
+
|
|
1071
|
+
**Output Schema:** `gno://schemas/tags-list@1.0`
|
|
1072
|
+
|
|
1073
|
+
**Response:**
|
|
1074
|
+
|
|
1075
|
+
```json
|
|
1076
|
+
{
|
|
1077
|
+
"content": [
|
|
1078
|
+
{
|
|
1079
|
+
"type": "text",
|
|
1080
|
+
"text": "Found 5 tags:\n\n work (10)\n personal (5)\n ..."
|
|
1081
|
+
}
|
|
1082
|
+
],
|
|
1083
|
+
"structuredContent": {
|
|
1084
|
+
"tags": [
|
|
1085
|
+
{ "tag": "work", "count": 10 },
|
|
1086
|
+
{ "tag": "personal", "count": 5 }
|
|
1087
|
+
],
|
|
1088
|
+
"meta": {
|
|
1089
|
+
"collection": null,
|
|
1090
|
+
"prefix": null,
|
|
1091
|
+
"totalTags": 5
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
```
|
|
1096
|
+
|
|
1097
|
+
---
|
|
1098
|
+
|
|
1099
|
+
### gno_links
|
|
1100
|
+
|
|
1101
|
+
Get outgoing links from a document.
|
|
1102
|
+
|
|
1103
|
+
**Input Schema:**
|
|
1104
|
+
|
|
1105
|
+
```json
|
|
1106
|
+
{
|
|
1107
|
+
"type": "object",
|
|
1108
|
+
"properties": {
|
|
1109
|
+
"ref": {
|
|
1110
|
+
"type": "string",
|
|
1111
|
+
"description": "Document reference: gno:// URI, collection/path, or #docid"
|
|
1112
|
+
},
|
|
1113
|
+
"type": {
|
|
1114
|
+
"type": "string",
|
|
1115
|
+
"enum": ["wiki", "markdown"],
|
|
1116
|
+
"description": "Filter by link type"
|
|
1117
|
+
}
|
|
1118
|
+
},
|
|
1119
|
+
"required": ["ref"]
|
|
1120
|
+
}
|
|
1121
|
+
```
|
|
1122
|
+
|
|
1123
|
+
**Output Schema:** `gno://schemas/links@1.0`
|
|
1124
|
+
|
|
1125
|
+
**Response:**
|
|
1126
|
+
|
|
1127
|
+
```json
|
|
1128
|
+
{
|
|
1129
|
+
"content": [
|
|
1130
|
+
{
|
|
1131
|
+
"type": "text",
|
|
1132
|
+
"text": "Found 3 outgoing links in gno://notes/index.md:\n\n [wiki] Target Note (line 5)\n ..."
|
|
1133
|
+
}
|
|
1134
|
+
],
|
|
1135
|
+
"structuredContent": {
|
|
1136
|
+
"links": [
|
|
1137
|
+
{
|
|
1138
|
+
"targetRef": "Target Note",
|
|
1139
|
+
"targetAnchor": "section-1",
|
|
1140
|
+
"targetCollection": "notes",
|
|
1141
|
+
"linkType": "wiki",
|
|
1142
|
+
"linkText": "see target",
|
|
1143
|
+
"position": { "startLine": 5, "startCol": 10 }
|
|
1144
|
+
}
|
|
1145
|
+
],
|
|
1146
|
+
"meta": {
|
|
1147
|
+
"docid": "#a1b2c3d4",
|
|
1148
|
+
"uri": "gno://notes/index.md",
|
|
1149
|
+
"title": "Index",
|
|
1150
|
+
"totalLinks": 3,
|
|
1151
|
+
"filterType": null
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
```
|
|
1156
|
+
|
|
1157
|
+
**Errors:**
|
|
1158
|
+
|
|
1159
|
+
- Document not found: returns `isError: true`
|
|
1160
|
+
- Invalid ref format: returns `isError: true`
|
|
1161
|
+
|
|
1162
|
+
---
|
|
1163
|
+
|
|
1164
|
+
### gno_backlinks
|
|
1165
|
+
|
|
1166
|
+
Get documents linking TO a document.
|
|
1167
|
+
|
|
1168
|
+
**Input Schema:**
|
|
1169
|
+
|
|
1170
|
+
```json
|
|
1171
|
+
{
|
|
1172
|
+
"type": "object",
|
|
1173
|
+
"properties": {
|
|
1174
|
+
"ref": {
|
|
1175
|
+
"type": "string",
|
|
1176
|
+
"description": "Document reference: gno:// URI, collection/path, or #docid"
|
|
1177
|
+
},
|
|
1178
|
+
"collection": {
|
|
1179
|
+
"type": "string",
|
|
1180
|
+
"description": "Filter source documents by collection"
|
|
1181
|
+
}
|
|
1182
|
+
},
|
|
1183
|
+
"required": ["ref"]
|
|
1184
|
+
}
|
|
1185
|
+
```
|
|
1186
|
+
|
|
1187
|
+
**Output Schema:** `gno://schemas/backlinks@1.0`
|
|
1188
|
+
|
|
1189
|
+
**Response:**
|
|
1190
|
+
|
|
1191
|
+
```json
|
|
1192
|
+
{
|
|
1193
|
+
"content": [
|
|
1194
|
+
{
|
|
1195
|
+
"type": "text",
|
|
1196
|
+
"text": "Found 2 backlinks to gno://notes/target.md:\n\n gno://notes/index.md \"Index\" (line 10)\n ..."
|
|
1197
|
+
}
|
|
1198
|
+
],
|
|
1199
|
+
"structuredContent": {
|
|
1200
|
+
"backlinks": [
|
|
1201
|
+
{
|
|
1202
|
+
"sourceDocUri": "gno://notes/index.md",
|
|
1203
|
+
"sourceDocTitle": "Index",
|
|
1204
|
+
"linkText": "Target Note",
|
|
1205
|
+
"position": { "startLine": 10, "startCol": 5 }
|
|
1206
|
+
}
|
|
1207
|
+
],
|
|
1208
|
+
"meta": {
|
|
1209
|
+
"docid": "#a1b2c3d4",
|
|
1210
|
+
"uri": "gno://notes/target.md",
|
|
1211
|
+
"title": "Target Note",
|
|
1212
|
+
"totalBacklinks": 2,
|
|
1213
|
+
"filterCollection": null
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
```
|
|
1218
|
+
|
|
1219
|
+
**Errors:**
|
|
1220
|
+
|
|
1221
|
+
- Document not found: returns `isError: true`
|
|
1222
|
+
- Collection not found: returns `isError: true`
|
|
1223
|
+
- Invalid ref format: returns `isError: true`
|
|
1224
|
+
|
|
1225
|
+
---
|
|
1226
|
+
|
|
1227
|
+
### gno_similar
|
|
1228
|
+
|
|
1229
|
+
Find semantically similar documents using vector embeddings.
|
|
1230
|
+
|
|
1231
|
+
**Input Schema:**
|
|
1232
|
+
|
|
1233
|
+
```json
|
|
1234
|
+
{
|
|
1235
|
+
"type": "object",
|
|
1236
|
+
"properties": {
|
|
1237
|
+
"ref": {
|
|
1238
|
+
"type": "string",
|
|
1239
|
+
"description": "Document reference: gno:// URI, collection/path, or #docid"
|
|
1240
|
+
},
|
|
1241
|
+
"limit": {
|
|
1242
|
+
"type": "integer",
|
|
1243
|
+
"description": "Maximum number of similar documents (1-50)",
|
|
1244
|
+
"default": 5,
|
|
1245
|
+
"minimum": 1,
|
|
1246
|
+
"maximum": 50
|
|
1247
|
+
},
|
|
1248
|
+
"threshold": {
|
|
1249
|
+
"type": "number",
|
|
1250
|
+
"description": "Minimum similarity score (0-1)",
|
|
1251
|
+
"minimum": 0,
|
|
1252
|
+
"maximum": 1
|
|
1253
|
+
},
|
|
1254
|
+
"crossCollection": {
|
|
1255
|
+
"type": "boolean",
|
|
1256
|
+
"description": "Include documents from other collections",
|
|
1257
|
+
"default": false
|
|
1258
|
+
}
|
|
1259
|
+
},
|
|
1260
|
+
"required": ["ref"]
|
|
1261
|
+
}
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1264
|
+
**Output Schema:** `gno://schemas/similar@1.0`
|
|
1265
|
+
|
|
1266
|
+
**Response:**
|
|
1267
|
+
|
|
1268
|
+
```json
|
|
1269
|
+
{
|
|
1270
|
+
"content": [
|
|
1271
|
+
{
|
|
1272
|
+
"type": "text",
|
|
1273
|
+
"text": "Found 3 similar documents for gno://notes/readme.md:\n\n [#def5678] gno://notes/guide.md (0.85)\n ..."
|
|
1274
|
+
}
|
|
1275
|
+
],
|
|
1276
|
+
"structuredContent": {
|
|
1277
|
+
"similar": [
|
|
1278
|
+
{
|
|
1279
|
+
"docid": "#def5678",
|
|
1280
|
+
"uri": "gno://notes/guide.md",
|
|
1281
|
+
"title": "Guide",
|
|
1282
|
+
"score": 0.85,
|
|
1283
|
+
"absPath": "/path/to/notes/guide.md"
|
|
1284
|
+
}
|
|
1285
|
+
],
|
|
1286
|
+
"meta": {
|
|
1287
|
+
"docid": "#a1b2c3d4",
|
|
1288
|
+
"uri": "gno://notes/readme.md",
|
|
1289
|
+
"title": "README",
|
|
1290
|
+
"totalSimilar": 3,
|
|
1291
|
+
"threshold": null,
|
|
1292
|
+
"crossCollection": false
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
```
|
|
1297
|
+
|
|
1298
|
+
**Algorithm:**
|
|
1299
|
+
|
|
1300
|
+
1. Get all chunks for the source document
|
|
1301
|
+
2. Retrieve embeddings for each chunk from content_vectors
|
|
1302
|
+
3. Compute average embedding across all chunks
|
|
1303
|
+
4. Search for nearest neighbors using sqlite-vec
|
|
1304
|
+
5. Exclude self and filter by collection if not crossCollection
|
|
1305
|
+
6. Return top N similar documents with scores
|
|
1306
|
+
|
|
1307
|
+
**Errors:**
|
|
1308
|
+
|
|
1309
|
+
- Document not found: returns `isError: true`
|
|
1310
|
+
- Document has no content: returns `isError: true`
|
|
1311
|
+
- Document has no embeddings: returns `isError: true`
|
|
1312
|
+
- Vector search unavailable (sqlite-vec not loaded): returns `isError: true`
|
|
1313
|
+
- Invalid ref format: returns `isError: true`
|
|
1314
|
+
|
|
1315
|
+
---
|
|
1316
|
+
|
|
1317
|
+
### gno_graph
|
|
1318
|
+
|
|
1319
|
+
Get knowledge graph of document connections plus graph-health report fields.
|
|
1320
|
+
|
|
1321
|
+
**Input Schema:**
|
|
1322
|
+
|
|
1323
|
+
```json
|
|
1324
|
+
{
|
|
1325
|
+
"type": "object",
|
|
1326
|
+
"properties": {
|
|
1327
|
+
"collection": {
|
|
1328
|
+
"type": "string",
|
|
1329
|
+
"description": "Filter to single collection"
|
|
1330
|
+
},
|
|
1331
|
+
"limit": {
|
|
1332
|
+
"type": "integer",
|
|
1333
|
+
"description": "Maximum nodes (1-5000)",
|
|
1334
|
+
"default": 2000,
|
|
1335
|
+
"minimum": 1,
|
|
1336
|
+
"maximum": 5000
|
|
1337
|
+
},
|
|
1338
|
+
"edgeLimit": {
|
|
1339
|
+
"type": "integer",
|
|
1340
|
+
"description": "Maximum edges (1-50000)",
|
|
1341
|
+
"default": 10000,
|
|
1342
|
+
"minimum": 1,
|
|
1343
|
+
"maximum": 50000
|
|
1344
|
+
},
|
|
1345
|
+
"includeSimilar": {
|
|
1346
|
+
"type": "boolean",
|
|
1347
|
+
"description": "Include semantic similarity edges",
|
|
1348
|
+
"default": false
|
|
1349
|
+
},
|
|
1350
|
+
"threshold": {
|
|
1351
|
+
"type": "number",
|
|
1352
|
+
"description": "Similarity threshold (0-1)",
|
|
1353
|
+
"default": 0.7,
|
|
1354
|
+
"minimum": 0,
|
|
1355
|
+
"maximum": 1
|
|
1356
|
+
},
|
|
1357
|
+
"linkedOnly": {
|
|
1358
|
+
"type": "boolean",
|
|
1359
|
+
"description": "Exclude isolated nodes (no connections)",
|
|
1360
|
+
"default": true
|
|
1361
|
+
},
|
|
1362
|
+
"similarTopK": {
|
|
1363
|
+
"type": "integer",
|
|
1364
|
+
"description": "Similar documents per node (1-20)",
|
|
1365
|
+
"default": 5,
|
|
1366
|
+
"minimum": 1,
|
|
1367
|
+
"maximum": 20
|
|
1368
|
+
}
|
|
1369
|
+
},
|
|
1370
|
+
"required": []
|
|
1371
|
+
}
|
|
1372
|
+
```
|
|
1373
|
+
|
|
1374
|
+
**Output Schema:** `gno://schemas/graph@1.0`
|
|
1375
|
+
|
|
1376
|
+
The structured response includes `report.hubs`, `report.bridgeCandidates`,
|
|
1377
|
+
`report.isolated`, `report.unresolvedLinks`, `report.edgeTypes`,
|
|
1378
|
+
`report.edgeConfidence`, `report.communities`, node `communityId` assignments,
|
|
1379
|
+
and per-edge `confidence` / `audit` metadata so agents can assess graph health,
|
|
1380
|
+
clusters, and trust before deeper traversal.
|
|
1381
|
+
|
|
1382
|
+
**Response:**
|
|
1383
|
+
|
|
1384
|
+
```json
|
|
1385
|
+
{
|
|
1386
|
+
"content": [
|
|
1387
|
+
{
|
|
1388
|
+
"type": "text",
|
|
1389
|
+
"text": "Knowledge Graph: 150 nodes, 320 edges\n\nTop nodes by degree:\n [#abc123] gno://notes/readme.md \"README\" (degree: 12)\n ..."
|
|
1390
|
+
}
|
|
1391
|
+
],
|
|
1392
|
+
"structuredContent": {
|
|
1393
|
+
"nodes": [
|
|
1394
|
+
{
|
|
1395
|
+
"id": "#abc123",
|
|
1396
|
+
"uri": "gno://notes/readme.md",
|
|
1397
|
+
"title": "README",
|
|
1398
|
+
"collection": "notes",
|
|
1399
|
+
"relPath": "readme.md",
|
|
1400
|
+
"degree": 12,
|
|
1401
|
+
"communityId": "c1"
|
|
1402
|
+
}
|
|
1403
|
+
],
|
|
1404
|
+
"links": [
|
|
1405
|
+
{
|
|
1406
|
+
"source": "#abc123",
|
|
1407
|
+
"target": "#def456",
|
|
1408
|
+
"type": "wiki",
|
|
1409
|
+
"weight": 1
|
|
1410
|
+
}
|
|
1411
|
+
],
|
|
1412
|
+
"meta": {
|
|
1413
|
+
"collection": null,
|
|
1414
|
+
"nodeLimit": 2000,
|
|
1415
|
+
"edgeLimit": 10000,
|
|
1416
|
+
"totalNodes": 150,
|
|
1417
|
+
"totalEdges": 320,
|
|
1418
|
+
"returnedNodes": 150,
|
|
1419
|
+
"returnedEdges": 320,
|
|
1420
|
+
"truncated": false,
|
|
1421
|
+
"linkedOnly": true,
|
|
1422
|
+
"includedSimilar": false
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
```
|
|
1427
|
+
|
|
1428
|
+
**Edge Types:**
|
|
1429
|
+
|
|
1430
|
+
- `wiki`: Wiki link (`[[Target]]`)
|
|
1431
|
+
- `markdown`: Markdown link (`[text](path.md)`)
|
|
1432
|
+
- `similar`: Semantic similarity (only when `includeSimilar: true`)
|
|
1433
|
+
|
|
1434
|
+
**Errors:**
|
|
1435
|
+
|
|
1436
|
+
- Collection not found: returns `isError: true`
|
|
1437
|
+
|
|
1438
|
+
---
|
|
1439
|
+
|
|
1440
|
+
### gno_graph_query
|
|
1441
|
+
|
|
1442
|
+
Bounded typed-edge traversal over the `doc_edges` relationship layer. This
|
|
1443
|
+
read-only tool wraps the shared graph-query core.
|
|
1444
|
+
|
|
1445
|
+
**Input Schema:**
|
|
1446
|
+
|
|
1447
|
+
```json
|
|
1448
|
+
{
|
|
1449
|
+
"ref": "gno://notes/people/alice.md",
|
|
1450
|
+
"direction": "both",
|
|
1451
|
+
"edgeType": "works_at",
|
|
1452
|
+
"maxDepth": 2,
|
|
1453
|
+
"maxNodes": 100,
|
|
1454
|
+
"frontierLimit": 100,
|
|
1455
|
+
"visitedLimit": 500
|
|
1456
|
+
}
|
|
1457
|
+
```
|
|
1458
|
+
|
|
1459
|
+
- `ref`: root document ref (URI, `#docid`, or `collection/path`).
|
|
1460
|
+
- `direction`: `out`, `in`, or `both` (default `both`).
|
|
1461
|
+
- `edgeType`: optional semantic edge type filter.
|
|
1462
|
+
- `relation`: alias for `edgeType`; if both are set they must match.
|
|
1463
|
+
- `maxDepth`: 1-6, default 2.
|
|
1464
|
+
- `maxNodes`: 1-1000, default 100.
|
|
1465
|
+
- `frontierLimit`: 1-1000, default 100.
|
|
1466
|
+
- `visitedLimit`: 1-5000, default 500.
|
|
1467
|
+
|
|
1468
|
+
**Output Schema:** `gno://schemas/graph-query@1.0`
|
|
1469
|
+
|
|
1470
|
+
Structured content includes `schemaVersion`, resolved `root`, typed `nodes`
|
|
1471
|
+
with graph hints, typed `edges` with `edgeType`/`relationType`/`confidence`/
|
|
1472
|
+
`edgeSource`, and `meta` with direction, caps, returned counts, warnings, and
|
|
1473
|
+
`truncated`.
|
|
1474
|
+
|
|
1475
|
+
Use for explicit relationship questions over typed edges such as `works_at`,
|
|
1476
|
+
`attended`, or `mentions` after a seed ref is known. Use `gno_query` first if
|
|
1477
|
+
the seed document is unknown.
|
|
1478
|
+
|
|
1479
|
+
---
|
|
1480
|
+
|
|
1481
|
+
### gno_graph_neighbors
|
|
1482
|
+
|
|
1483
|
+
Find incoming and outgoing graph neighbors for one document/node.
|
|
1484
|
+
|
|
1485
|
+
**Input Schema:** same graph filter fields as `gno_graph`, plus:
|
|
1486
|
+
|
|
1487
|
+
```json
|
|
1488
|
+
{
|
|
1489
|
+
"ref": "notes/readme.md",
|
|
1490
|
+
"direction": "both"
|
|
1491
|
+
}
|
|
1492
|
+
```
|
|
1493
|
+
|
|
1494
|
+
- `ref`: URI, `#docid`, `collection/path`, `relPath`, or exact title.
|
|
1495
|
+
- `direction`: `both`, `out`, or `in` (default: `both`).
|
|
1496
|
+
|
|
1497
|
+
Use for relationship questions, missed related docs, and corpus navigation after
|
|
1498
|
+
`gno_query` finds a seed document. Follow with `gno_get` for evidence.
|
|
1499
|
+
|
|
1500
|
+
---
|
|
1501
|
+
|
|
1502
|
+
### gno_graph_path
|
|
1503
|
+
|
|
1504
|
+
Find the shortest relationship path between two documents/nodes.
|
|
1505
|
+
|
|
1506
|
+
**Input Schema:** same graph filter fields as `gno_graph`, plus:
|
|
1507
|
+
|
|
1508
|
+
```json
|
|
1509
|
+
{
|
|
1510
|
+
"from": "notes/a.md",
|
|
1511
|
+
"to": "notes/b.md",
|
|
1512
|
+
"maxDepth": 6
|
|
1513
|
+
}
|
|
1514
|
+
```
|
|
1515
|
+
|
|
1516
|
+
- `from`, `to`: URI, `#docid`, `collection/path`, `relPath`, or exact title.
|
|
1517
|
+
- `maxDepth`: maximum hops to search (1-12, default: 6).
|
|
1518
|
+
|
|
1519
|
+
Use for "how are X and Y connected?" prompts. Run `gno_query` first when either
|
|
1520
|
+
endpoint is unknown, then read path nodes with `gno_get`.
|
|
1521
|
+
|
|
1522
|
+
---
|
|
1523
|
+
|
|
1524
|
+
### gno_add_collection
|
|
1525
|
+
|
|
1526
|
+
Add a folder as a new collection and start indexing (write-enabled).
|
|
1527
|
+
|
|
1528
|
+
**Input Schema:**
|
|
1529
|
+
|
|
1530
|
+
```json
|
|
1531
|
+
{
|
|
1532
|
+
"type": "object",
|
|
1533
|
+
"properties": {
|
|
1534
|
+
"path": {
|
|
1535
|
+
"type": "string",
|
|
1536
|
+
"description": "Absolute or ~-expanded folder path"
|
|
1537
|
+
},
|
|
1538
|
+
"name": {
|
|
1539
|
+
"type": "string",
|
|
1540
|
+
"description": "Optional collection name (defaults to folder name)"
|
|
1541
|
+
},
|
|
1542
|
+
"pattern": {
|
|
1543
|
+
"type": "string",
|
|
1544
|
+
"description": "Glob pattern (default: **/*.md)"
|
|
1545
|
+
},
|
|
1546
|
+
"include": {
|
|
1547
|
+
"type": "array",
|
|
1548
|
+
"items": { "type": "string" },
|
|
1549
|
+
"description": "Additional include patterns"
|
|
1550
|
+
},
|
|
1551
|
+
"exclude": {
|
|
1552
|
+
"type": "array",
|
|
1553
|
+
"items": { "type": "string" },
|
|
1554
|
+
"description": "Exclude patterns"
|
|
1555
|
+
},
|
|
1556
|
+
"gitPull": {
|
|
1557
|
+
"type": "boolean",
|
|
1558
|
+
"description": "Run git pull before indexing",
|
|
1559
|
+
"default": false
|
|
1560
|
+
}
|
|
1561
|
+
},
|
|
1562
|
+
"required": ["path"]
|
|
1563
|
+
}
|
|
1564
|
+
```
|
|
1565
|
+
|
|
1566
|
+
**Output Schema:** `gno://schemas/mcp-add-collection-result@1.0`
|
|
1567
|
+
|
|
1568
|
+
---
|
|
1569
|
+
|
|
1570
|
+
### gno_create_folder
|
|
1571
|
+
|
|
1572
|
+
Create a folder inside an existing collection (write-enabled).
|
|
1573
|
+
|
|
1574
|
+
**Input Schema:**
|
|
1575
|
+
|
|
1576
|
+
```json
|
|
1577
|
+
{
|
|
1578
|
+
"type": "object",
|
|
1579
|
+
"properties": {
|
|
1580
|
+
"collection": { "type": "string" },
|
|
1581
|
+
"name": { "type": "string" },
|
|
1582
|
+
"parentPath": { "type": "string" }
|
|
1583
|
+
},
|
|
1584
|
+
"required": ["collection", "name"]
|
|
1585
|
+
}
|
|
1586
|
+
```
|
|
1587
|
+
|
|
1588
|
+
---
|
|
1589
|
+
|
|
1590
|
+
### gno_rename_note
|
|
1591
|
+
|
|
1592
|
+
Rename an editable note in place (write-enabled).
|
|
1593
|
+
|
|
1594
|
+
**Input Schema:**
|
|
1595
|
+
|
|
1596
|
+
```json
|
|
1597
|
+
{
|
|
1598
|
+
"type": "object",
|
|
1599
|
+
"properties": {
|
|
1600
|
+
"ref": { "type": "string" },
|
|
1601
|
+
"name": { "type": "string" }
|
|
1602
|
+
},
|
|
1603
|
+
"required": ["ref", "name"]
|
|
1604
|
+
}
|
|
1605
|
+
```
|
|
1606
|
+
|
|
1607
|
+
---
|
|
1608
|
+
|
|
1609
|
+
### gno_move_note
|
|
1610
|
+
|
|
1611
|
+
Move an editable note to another folder in the same collection (write-enabled).
|
|
1612
|
+
|
|
1613
|
+
**Input Schema:**
|
|
1614
|
+
|
|
1615
|
+
```json
|
|
1616
|
+
{
|
|
1617
|
+
"type": "object",
|
|
1618
|
+
"properties": {
|
|
1619
|
+
"ref": { "type": "string" },
|
|
1620
|
+
"folderPath": { "type": "string" },
|
|
1621
|
+
"name": { "type": "string" }
|
|
1622
|
+
},
|
|
1623
|
+
"required": ["ref", "folderPath"]
|
|
1624
|
+
}
|
|
1625
|
+
```
|
|
1626
|
+
|
|
1627
|
+
---
|
|
1628
|
+
|
|
1629
|
+
### gno_duplicate_note
|
|
1630
|
+
|
|
1631
|
+
Duplicate an editable note into the current or another folder (write-enabled).
|
|
1632
|
+
|
|
1633
|
+
**Input Schema:**
|
|
1634
|
+
|
|
1635
|
+
```json
|
|
1636
|
+
{
|
|
1637
|
+
"type": "object",
|
|
1638
|
+
"properties": {
|
|
1639
|
+
"ref": { "type": "string" },
|
|
1640
|
+
"folderPath": { "type": "string" },
|
|
1641
|
+
"name": { "type": "string" }
|
|
1642
|
+
},
|
|
1643
|
+
"required": ["ref"]
|
|
1644
|
+
}
|
|
1645
|
+
```
|
|
1646
|
+
|
|
1647
|
+
---
|
|
1648
|
+
|
|
1649
|
+
### gno_sync
|
|
1650
|
+
|
|
1651
|
+
Reindex one or all collections (write-enabled).
|
|
1652
|
+
|
|
1653
|
+
**Input Schema:**
|
|
1654
|
+
|
|
1655
|
+
```json
|
|
1656
|
+
{
|
|
1657
|
+
"type": "object",
|
|
1658
|
+
"properties": {
|
|
1659
|
+
"collection": {
|
|
1660
|
+
"type": "string",
|
|
1661
|
+
"description": "Collection to sync (all if omitted)"
|
|
1662
|
+
},
|
|
1663
|
+
"gitPull": {
|
|
1664
|
+
"type": "boolean",
|
|
1665
|
+
"description": "Run git pull before indexing",
|
|
1666
|
+
"default": false
|
|
1667
|
+
},
|
|
1668
|
+
"runUpdateCmd": {
|
|
1669
|
+
"type": "boolean",
|
|
1670
|
+
"description": "Run updateCmd before indexing (default: false for MCP)",
|
|
1671
|
+
"default": false
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
```
|
|
1676
|
+
|
|
1677
|
+
**Output Schema:** `gno://schemas/mcp-sync-result@1.0`
|
|
1678
|
+
|
|
1679
|
+
---
|
|
1680
|
+
|
|
1681
|
+
### gno_embed
|
|
1682
|
+
|
|
1683
|
+
Generate embeddings for unembedded chunks (write-enabled). Runs as background job.
|
|
1684
|
+
|
|
1685
|
+
**Input Schema:**
|
|
1686
|
+
|
|
1687
|
+
```json
|
|
1688
|
+
{
|
|
1689
|
+
"type": "object",
|
|
1690
|
+
"properties": {
|
|
1691
|
+
"collection": {
|
|
1692
|
+
"type": "string",
|
|
1693
|
+
"description": "Optional collection name to embed"
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
```
|
|
1698
|
+
|
|
1699
|
+
**Output Schema:** `gno://schemas/mcp-embed-result@1.0`
|
|
1700
|
+
|
|
1701
|
+
**Response:**
|
|
1702
|
+
|
|
1703
|
+
```json
|
|
1704
|
+
{
|
|
1705
|
+
"content": [
|
|
1706
|
+
{
|
|
1707
|
+
"type": "text",
|
|
1708
|
+
"text": "Job: <uuid>\nStatus: started\nModel: <model-uri>"
|
|
1709
|
+
}
|
|
1710
|
+
],
|
|
1711
|
+
"structuredContent": {
|
|
1712
|
+
"jobId": "<uuid>",
|
|
1713
|
+
"status": "started",
|
|
1714
|
+
"model": "<model-uri>"
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
```
|
|
1718
|
+
|
|
1719
|
+
**Notes:**
|
|
1720
|
+
|
|
1721
|
+
- Requires `--enable-write` flag
|
|
1722
|
+
- Fails fast if embedding model not cached (run `gno models pull embed` first)
|
|
1723
|
+
- Poll job status with `gno_job_status`
|
|
1724
|
+
|
|
1725
|
+
---
|
|
1726
|
+
|
|
1727
|
+
### gno_clear_collection_embeddings
|
|
1728
|
+
|
|
1729
|
+
Clear stale or all embeddings for one collection (write-enabled).
|
|
1730
|
+
|
|
1731
|
+
**Input Schema:**
|
|
1732
|
+
|
|
1733
|
+
```json
|
|
1734
|
+
{
|
|
1735
|
+
"type": "object",
|
|
1736
|
+
"required": ["collection"],
|
|
1737
|
+
"properties": {
|
|
1738
|
+
"collection": {
|
|
1739
|
+
"type": "string",
|
|
1740
|
+
"description": "Collection name"
|
|
1741
|
+
},
|
|
1742
|
+
"mode": {
|
|
1743
|
+
"type": "string",
|
|
1744
|
+
"enum": ["stale", "all"],
|
|
1745
|
+
"default": "stale"
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
```
|
|
1750
|
+
|
|
1751
|
+
---
|
|
1752
|
+
|
|
1753
|
+
### gno_index
|
|
1754
|
+
|
|
1755
|
+
Full index: sync files + generate embeddings (write-enabled). Runs as background job.
|
|
1756
|
+
|
|
1757
|
+
**Input Schema:**
|
|
1758
|
+
|
|
1759
|
+
```json
|
|
1760
|
+
{
|
|
1761
|
+
"type": "object",
|
|
1762
|
+
"properties": {
|
|
1763
|
+
"collection": {
|
|
1764
|
+
"type": "string",
|
|
1765
|
+
"description": "Collection to index (all if omitted)"
|
|
1766
|
+
},
|
|
1767
|
+
"gitPull": {
|
|
1768
|
+
"type": "boolean",
|
|
1769
|
+
"description": "Run git pull before sync",
|
|
1770
|
+
"default": false
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
```
|
|
1775
|
+
|
|
1776
|
+
**Output Schema:** `gno://schemas/mcp-index-result@1.0`
|
|
1777
|
+
|
|
1778
|
+
**Response:**
|
|
1779
|
+
|
|
1780
|
+
```json
|
|
1781
|
+
{
|
|
1782
|
+
"content": [
|
|
1783
|
+
{
|
|
1784
|
+
"type": "text",
|
|
1785
|
+
"text": "Job: <uuid>\nStatus: started\nCollections: work, notes\nPhases: sync → embed"
|
|
1786
|
+
}
|
|
1787
|
+
],
|
|
1788
|
+
"structuredContent": {
|
|
1789
|
+
"jobId": "<uuid>",
|
|
1790
|
+
"status": "started",
|
|
1791
|
+
"collections": ["work", "notes"],
|
|
1792
|
+
"phases": ["sync", "embed"],
|
|
1793
|
+
"options": {
|
|
1794
|
+
"gitPull": false,
|
|
1795
|
+
"runUpdateCmd": false
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
```
|
|
1800
|
+
|
|
1801
|
+
**Notes:**
|
|
1802
|
+
|
|
1803
|
+
- Requires `--enable-write` flag
|
|
1804
|
+
- Runs sync phase first, then embed phase
|
|
1805
|
+
- `runUpdateCmd` is always false for MCP (security)
|
|
1806
|
+
- Fails fast if embedding model not cached
|
|
1807
|
+
- Poll job status with `gno_job_status`
|
|
1808
|
+
|
|
1809
|
+
---
|
|
1810
|
+
|
|
1811
|
+
### gno_remove_collection
|
|
1812
|
+
|
|
1813
|
+
Remove a collection from config (write-enabled). Indexed data is retained.
|
|
1814
|
+
|
|
1815
|
+
**Input Schema:**
|
|
1816
|
+
|
|
1817
|
+
```json
|
|
1818
|
+
{
|
|
1819
|
+
"type": "object",
|
|
1820
|
+
"properties": {
|
|
1821
|
+
"collection": {
|
|
1822
|
+
"type": "string",
|
|
1823
|
+
"description": "Collection name to remove"
|
|
1824
|
+
}
|
|
1825
|
+
},
|
|
1826
|
+
"required": ["collection"]
|
|
1827
|
+
}
|
|
1828
|
+
```
|
|
1829
|
+
|
|
1830
|
+
**Output Schema:** `gno://schemas/mcp-remove-result@1.0`
|
|
1831
|
+
|
|
1832
|
+
---
|
|
1833
|
+
|
|
1834
|
+
### gno_job_status
|
|
1835
|
+
|
|
1836
|
+
Get status of a background job.
|
|
1837
|
+
|
|
1838
|
+
**Input Schema:**
|
|
1839
|
+
|
|
1840
|
+
```json
|
|
1841
|
+
{
|
|
1842
|
+
"type": "object",
|
|
1843
|
+
"properties": {
|
|
1844
|
+
"jobId": {
|
|
1845
|
+
"type": "string",
|
|
1846
|
+
"description": "Job identifier"
|
|
1847
|
+
}
|
|
1848
|
+
},
|
|
1849
|
+
"required": ["jobId"]
|
|
1850
|
+
}
|
|
1851
|
+
```
|
|
1852
|
+
|
|
1853
|
+
**Output Schema:** `gno://schemas/mcp-job-status@1.0`
|
|
1854
|
+
|
|
1855
|
+
---
|
|
1856
|
+
|
|
1857
|
+
### gno_list_jobs
|
|
1858
|
+
|
|
1859
|
+
List active and recent jobs.
|
|
1860
|
+
|
|
1861
|
+
**Input Schema:**
|
|
1862
|
+
|
|
1863
|
+
```json
|
|
1864
|
+
{
|
|
1865
|
+
"type": "object",
|
|
1866
|
+
"properties": {
|
|
1867
|
+
"limit": {
|
|
1868
|
+
"type": "integer",
|
|
1869
|
+
"description": "Max recent jobs to return",
|
|
1870
|
+
"default": 10
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
```
|
|
1875
|
+
|
|
1876
|
+
**Output Schema:** `gno://schemas/mcp-job-list@1.0`
|
|
1877
|
+
|
|
1878
|
+
---
|
|
1879
|
+
|
|
1880
|
+
## Resources
|
|
1881
|
+
|
|
1882
|
+
### gno://tags
|
|
1883
|
+
|
|
1884
|
+
List all tags with document counts. Supports query parameters for filtering.
|
|
1885
|
+
|
|
1886
|
+
**URI Pattern:** `gno://tags` or `gno://tags?collection=x&prefix=work/`
|
|
1887
|
+
|
|
1888
|
+
**Query Parameters:**
|
|
1889
|
+
|
|
1890
|
+
| Parameter | Description |
|
|
1891
|
+
| ------------ | ------------------------------------- |
|
|
1892
|
+
| `collection` | Filter tags by collection name |
|
|
1893
|
+
| `prefix` | Filter tags by prefix (e.g., `work/`) |
|
|
1894
|
+
|
|
1895
|
+
**Response:**
|
|
1896
|
+
|
|
1897
|
+
MIME type: `application/json`
|
|
1898
|
+
|
|
1899
|
+
```json
|
|
1900
|
+
{
|
|
1901
|
+
"tags": [
|
|
1902
|
+
{ "tag": "work", "count": 10 },
|
|
1903
|
+
{ "tag": "personal", "count": 5 }
|
|
1904
|
+
],
|
|
1905
|
+
"meta": {
|
|
1906
|
+
"collection": null,
|
|
1907
|
+
"prefix": null,
|
|
1908
|
+
"totalTags": 2
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
```
|
|
1912
|
+
|
|
1913
|
+
---
|
|
1914
|
+
|
|
1915
|
+
### gno://{collection}/{path}
|
|
1916
|
+
|
|
1917
|
+
Read document content by URI.
|
|
1918
|
+
|
|
1919
|
+
**URI Pattern:** `gno://{collection}/{relativePath}[?index={name}]`
|
|
1920
|
+
|
|
1921
|
+
**Examples:**
|
|
1922
|
+
|
|
1923
|
+
- `gno://work/contracts/nda.docx`
|
|
1924
|
+
- `gno://notes/2025/01/meeting.md`
|
|
1925
|
+
- `gno://notes/2025/01/meeting.md?index=research`
|
|
1926
|
+
|
|
1927
|
+
**Response:**
|
|
1928
|
+
|
|
1929
|
+
MIME type: `text/markdown`
|
|
1930
|
+
|
|
1931
|
+
Content includes optional header comment:
|
|
1932
|
+
|
|
1933
|
+
```markdown
|
|
1934
|
+
<!-- gno://work/contracts/nda.docx
|
|
1935
|
+
docid: #a1b2c3d4
|
|
1936
|
+
source: /abs/path/to/nda.docx
|
|
1937
|
+
mime: application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
|
1938
|
+
-->
|
|
1939
|
+
|
|
1940
|
+
1: # Contract
|
|
1941
|
+
2:
|
|
1942
|
+
3: This Non-Disclosure Agreement...
|
|
1943
|
+
```
|
|
1944
|
+
|
|
1945
|
+
**Header Fields:**
|
|
1946
|
+
| Field | Description |
|
|
1947
|
+
|-------|-------------|
|
|
1948
|
+
| URI | Full gno:// URI |
|
|
1949
|
+
| docid | Document ID |
|
|
1950
|
+
| source | Absolute path to source file |
|
|
1951
|
+
| mime | Source file MIME type |
|
|
1952
|
+
| language | Document language hint (if available) |
|
|
1953
|
+
|
|
1954
|
+
**Behavior:**
|
|
1955
|
+
|
|
1956
|
+
- Returns Markdown mirror content (converted from source)
|
|
1957
|
+
- Line numbers included by default for agent friendliness
|
|
1958
|
+
- Header is display-only, not part of indexed content
|
|
1959
|
+
- An `index` query opens that named database; a missing index errors without
|
|
1960
|
+
creating an empty database
|
|
1961
|
+
|
|
1962
|
+
**Errors:**
|
|
1963
|
+
|
|
1964
|
+
- Document not found: standard MCP resource error
|
|
1965
|
+
- Collection not found: standard MCP resource error
|
|
1966
|
+
|
|
1967
|
+
---
|
|
1968
|
+
|
|
1969
|
+
## URI Encoding
|
|
1970
|
+
|
|
1971
|
+
Special characters in URIs are URL-encoded per RFC 3986:
|
|
1972
|
+
|
|
1973
|
+
| Character | Encoded |
|
|
1974
|
+
| --------- | ------- |
|
|
1975
|
+
| Space | `%20` |
|
|
1976
|
+
| `#` | `%23` |
|
|
1977
|
+
| `?` | `%3F` |
|
|
1978
|
+
| `%` | `%25` |
|
|
1979
|
+
|
|
1980
|
+
Path separators (`/`) are preserved.
|
|
1981
|
+
|
|
1982
|
+
**Example:**
|
|
1983
|
+
|
|
1984
|
+
- File: `My Documents/file name.pdf`
|
|
1985
|
+
- URI: `gno://work/My%20Documents/file%20name.pdf`
|
|
1986
|
+
|
|
1987
|
+
---
|
|
1988
|
+
|
|
1989
|
+
## Error Handling
|
|
1990
|
+
|
|
1991
|
+
Tool errors return:
|
|
1992
|
+
|
|
1993
|
+
```json
|
|
1994
|
+
{
|
|
1995
|
+
"isError": true,
|
|
1996
|
+
"content": [
|
|
1997
|
+
{
|
|
1998
|
+
"type": "text",
|
|
1999
|
+
"text": "Error: Document not found: #invalid"
|
|
2000
|
+
}
|
|
2001
|
+
]
|
|
2002
|
+
}
|
|
2003
|
+
```
|
|
2004
|
+
|
|
2005
|
+
Resource errors use standard MCP error responses.
|
|
2006
|
+
|
|
2007
|
+
### MCP Error Codes (Write Tools)
|
|
2008
|
+
|
|
2009
|
+
- `NOT_FOUND` — Resource not found
|
|
2010
|
+
- `DUPLICATE` — Resource already exists
|
|
2011
|
+
- `CONFLICT` — Conflict with existing resource
|
|
2012
|
+
- `HAS_REFERENCES` — Collection referenced by contexts
|
|
2013
|
+
- `INVALID_PATH` — Path violates safety rules
|
|
2014
|
+
- `PATH_NOT_FOUND` — Path does not exist
|
|
2015
|
+
- `JOB_CONFLICT` — Another job is already running
|
|
2016
|
+
- `LOCKED` — Another MCP process holds the write lock
|
|
2017
|
+
|
|
2018
|
+
---
|
|
2019
|
+
|
|
2020
|
+
## Versioning
|
|
2021
|
+
|
|
2022
|
+
### Tool Versioning
|
|
2023
|
+
|
|
2024
|
+
Tools are versioned via the server version. Breaking changes require major version bump.
|
|
2025
|
+
|
|
2026
|
+
**Compatibility Rules:**
|
|
2027
|
+
|
|
2028
|
+
- New optional input parameters: minor version
|
|
2029
|
+
- New output fields: minor version
|
|
2030
|
+
- Removing/renaming parameters: major version
|
|
2031
|
+
- Changing output structure: major version
|
|
2032
|
+
|
|
2033
|
+
### Schema Versioning
|
|
2034
|
+
|
|
2035
|
+
Output schemas include version in `$id`:
|
|
2036
|
+
|
|
2037
|
+
- `gno://schemas/search-result@1.0`
|
|
2038
|
+
- `gno://schemas/capture-receipt@1.0`
|
|
2039
|
+
|
|
2040
|
+
Clients should check schema version for compatibility.
|
|
2041
|
+
|
|
2042
|
+
---
|
|
2043
|
+
|
|
2044
|
+
## Session Behavior
|
|
2045
|
+
|
|
2046
|
+
- DB connection kept open for server lifetime
|
|
2047
|
+
- No persistent state between tool calls
|
|
2048
|
+
- Each tool call is independent
|
|
2049
|
+
- Server handles concurrent requests sequentially
|
|
2050
|
+
|
|
2051
|
+
---
|
|
2052
|
+
|
|
2053
|
+
## CLI Commands
|
|
2054
|
+
|
|
2055
|
+
GNO provides CLI commands to manage MCP server installation.
|
|
2056
|
+
|
|
2057
|
+
### gno mcp install
|
|
2058
|
+
|
|
2059
|
+
Install gno as an MCP server in client configurations.
|
|
2060
|
+
|
|
2061
|
+
**Synopsis:**
|
|
2062
|
+
|
|
2063
|
+
```bash
|
|
2064
|
+
gno mcp install [options]
|
|
2065
|
+
```
|
|
2066
|
+
|
|
2067
|
+
**Options:**
|
|
2068
|
+
|
|
2069
|
+
| Option | Description | Default |
|
|
2070
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------- | --------------------------------- |
|
|
2071
|
+
| `-t, --target <target>` | One of the 10 supported automatic clients | `claude-desktop` |
|
|
2072
|
+
| `-s, --scope <scope>` | `user` or `project`; project is supported by Claude Code, Codex, Cursor, OpenCode, and project-only LibreChat | Target default (otherwise `user`) |
|
|
2073
|
+
| `-f, --force` | Overwrite existing configuration | `false` |
|
|
2074
|
+
| `--dry-run` | Show what would be done without changes | `false` |
|
|
2075
|
+
| `--enable-write` | Install config with `--enable-write` args | `false` |
|
|
2076
|
+
| `--json` | JSON output | `false` |
|
|
2077
|
+
|
|
2078
|
+
**Config Locations:**
|
|
2079
|
+
|
|
2080
|
+
| Target | Scope(s) | Config path |
|
|
2081
|
+
| ---------------- | ------------- | --------------------------------------------------------------------- |
|
|
2082
|
+
| `claude-desktop` | user | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
2083
|
+
| `claude-code` | user, project | `~/.claude.json`, `./.mcp.json` |
|
|
2084
|
+
| `codex` | user, project | `~/.codex/config.toml`, `./.codex/config.toml` |
|
|
2085
|
+
| `cursor` | user, project | `~/.cursor/mcp.json`, `./.cursor/mcp.json` |
|
|
2086
|
+
| `zed` | user | `~/.config/zed/settings.json`; Windows: `%APPDATA%\Zed\settings.json` |
|
|
2087
|
+
| `windsurf` | user | `~/.codeium/windsurf/mcp_config.json` |
|
|
2088
|
+
| `opencode` | user, project | `~/.config/opencode/opencode.json`, `./opencode.json` |
|
|
2089
|
+
| `amp` | user | `~/.config/amp/settings.json` |
|
|
2090
|
+
| `lmstudio` | user | `~/.lmstudio/mcp.json` |
|
|
2091
|
+
| `librechat` | project | `./librechat.yaml` |
|
|
2092
|
+
|
|
2093
|
+
**Example:**
|
|
2094
|
+
|
|
2095
|
+
```bash
|
|
2096
|
+
# Install for Claude Desktop (default)
|
|
2097
|
+
gno mcp install
|
|
2098
|
+
|
|
2099
|
+
# Install for Claude Code (user scope)
|
|
2100
|
+
gno mcp install -t claude-code
|
|
2101
|
+
|
|
2102
|
+
# Install for Claude Code (project scope)
|
|
2103
|
+
gno mcp install -t claude-code -s project
|
|
2104
|
+
|
|
2105
|
+
# Install for project-only LibreChat
|
|
2106
|
+
gno mcp install -t librechat -s project
|
|
2107
|
+
|
|
2108
|
+
# Preview changes
|
|
2109
|
+
gno mcp install --dry-run
|
|
2110
|
+
|
|
2111
|
+
# Install with write tools enabled
|
|
2112
|
+
gno mcp install --enable-write
|
|
2113
|
+
```
|
|
2114
|
+
|
|
2115
|
+
**Installed entry contract:** The command is the absolute current Bun
|
|
2116
|
+
executable. Arguments are `run`, the absolute `src/index.ts` from the currently
|
|
2117
|
+
installed GNO package, `--index <active>`, `--config <absolute>`, then `mcp`.
|
|
2118
|
+
`--enable-write`, when requested, follows `mcp`. The config path is the active
|
|
2119
|
+
explicit, environment-selected, or default config resolved to an absolute path.
|
|
2120
|
+
Entries also pin absolute `GNO_DATA_DIR` and `GNO_CACHE_DIR` values under `env`
|
|
2121
|
+
(`environment` for OpenCode). No other environment keys are accepted by status
|
|
2122
|
+
or activation verification, and all values must be absolute paths without
|
|
2123
|
+
control characters. Codex uses native `[mcp_servers.gno]` and nested
|
|
2124
|
+
`[mcp_servers.gno.env]` TOML tables; install, update, and uninstall preserve
|
|
2125
|
+
unrelated TOML and comments. The index, config, data, and cache identity are
|
|
2126
|
+
always pinned because GUI clients do not reliably inherit the installing
|
|
2127
|
+
shell's `PATH` or environment. Invalid or empty index names fail before the
|
|
2128
|
+
target client config is written.
|
|
2129
|
+
JSON/JSONC targets preserve comments, trailing commas, and unrelated layout;
|
|
2130
|
+
OpenCode and Amp reuse supported existing `.jsonc` alternates rather than
|
|
2131
|
+
creating duplicate `.json` configs. `--dry-run --json` returns normalized
|
|
2132
|
+
command, argument, and workspace values rather than a target-specific persisted
|
|
2133
|
+
wrapper. Previewing an existing entry requires `--force --dry-run --json`.
|
|
2134
|
+
|
|
2135
|
+
Standard JSON/YAML entries use this shape (with target-specific outer keys):
|
|
2136
|
+
|
|
2137
|
+
```json
|
|
2138
|
+
{
|
|
2139
|
+
"command": "/absolute/path/to/bun",
|
|
2140
|
+
"args": [
|
|
2141
|
+
"run",
|
|
2142
|
+
"/absolute/path/to/@gmickel/gno/src/index.ts",
|
|
2143
|
+
"--index",
|
|
2144
|
+
"default",
|
|
2145
|
+
"--config",
|
|
2146
|
+
"/absolute/path/to/index.yml",
|
|
2147
|
+
"mcp"
|
|
2148
|
+
],
|
|
2149
|
+
"env": {
|
|
2150
|
+
"GNO_DATA_DIR": "/absolute/path/to/data",
|
|
2151
|
+
"GNO_CACHE_DIR": "/absolute/path/to/cache"
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
```
|
|
2155
|
+
|
|
2156
|
+
OpenCode stores the same executable and arguments in its `command` array and
|
|
2157
|
+
uses `environment`, not `env`. Codex stores the equivalent native TOML:
|
|
2158
|
+
|
|
2159
|
+
```toml
|
|
2160
|
+
[mcp_servers.gno]
|
|
2161
|
+
command = "/absolute/path/to/bun"
|
|
2162
|
+
args = ["run", "/absolute/path/to/@gmickel/gno/src/index.ts", "--index", "default", "--config", "/absolute/path/to/index.yml", "mcp"]
|
|
2163
|
+
|
|
2164
|
+
[mcp_servers.gno.env]
|
|
2165
|
+
GNO_DATA_DIR = "/absolute/path/to/data"
|
|
2166
|
+
GNO_CACHE_DIR = "/absolute/path/to/cache"
|
|
2167
|
+
```
|
|
2168
|
+
|
|
2169
|
+
### gno mcp uninstall
|
|
2170
|
+
|
|
2171
|
+
Remove gno MCP server from client configurations.
|
|
2172
|
+
|
|
2173
|
+
**Synopsis:**
|
|
2174
|
+
|
|
2175
|
+
```bash
|
|
2176
|
+
gno mcp uninstall [options]
|
|
2177
|
+
```
|
|
2178
|
+
|
|
2179
|
+
**Options:**
|
|
2180
|
+
|
|
2181
|
+
| Option | Description | Default |
|
|
2182
|
+
| ----------------------- | ------------------------------------ | ---------------- |
|
|
2183
|
+
| `-t, --target <target>` | Target client | `claude-desktop` |
|
|
2184
|
+
| `-s, --scope <scope>` | Scope; LibreChat defaults to project | Target default |
|
|
2185
|
+
| `--json` | JSON output | `false` |
|
|
2186
|
+
|
|
2187
|
+
### gno mcp status
|
|
2188
|
+
|
|
2189
|
+
Show MCP server installation status across all targets.
|
|
2190
|
+
|
|
2191
|
+
**Synopsis:**
|
|
2192
|
+
|
|
2193
|
+
```bash
|
|
2194
|
+
gno mcp status [options]
|
|
2195
|
+
```
|
|
2196
|
+
|
|
2197
|
+
**Options:**
|
|
2198
|
+
|
|
2199
|
+
| Option | Description | Default |
|
|
2200
|
+
| ----------------------- | --------------------------- | ------- |
|
|
2201
|
+
| `-t, --target <target>` | Filter by target (or `all`) | `all` |
|
|
2202
|
+
| `-s, --scope <scope>` | Filter by scope (or `all`) | `all` |
|
|
2203
|
+
| `--json` | JSON output | `false` |
|
|
2204
|
+
|
|
2205
|
+
**Example Output (abbreviated; unfiltered status enumerates 14 target/scope
|
|
2206
|
+
pairs):**
|
|
2207
|
+
|
|
2208
|
+
```text
|
|
2209
|
+
MCP Server Status
|
|
2210
|
+
──────────────────────────────────────────────────
|
|
2211
|
+
|
|
2212
|
+
✓ Claude Desktop: configured
|
|
2213
|
+
Command: /path/to/bun
|
|
2214
|
+
Args: run /path/to/@gmickel/gno/src/index.ts --index default --config /absolute/path/to/index.yml mcp
|
|
2215
|
+
Config: ~/Library/Application Support/Claude/claude_desktop_config.json
|
|
2216
|
+
|
|
2217
|
+
✗ Claude Code: not configured
|
|
2218
|
+
Config: ~/.claude.json
|
|
2219
|
+
|
|
2220
|
+
1/14 targets configured
|
|
2221
|
+
```
|
|
2222
|
+
|
|
2223
|
+
---
|
|
2224
|
+
|
|
2225
|
+
## See Also
|
|
2226
|
+
|
|
2227
|
+
- [CLI Specification](./cli.md)
|
|
2228
|
+
- [Output Schemas](./output-schemas/)
|
|
2229
|
+
- [MCP Protocol Specification](https://modelcontextprotocol.io/specification/)
|