@aigentyc/mcp 0.1.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.
Files changed (107) hide show
  1. package/AGENTS.md +197 -0
  2. package/LICENSE +21 -0
  3. package/README.md +112 -0
  4. package/context7.json +3 -0
  5. package/dist/cli.d.ts +3 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +289 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/client.d.ts +10 -0
  10. package/dist/client.d.ts.map +1 -0
  11. package/dist/client.js +70 -0
  12. package/dist/client.js.map +1 -0
  13. package/dist/config.d.ts +31 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +79 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/errors.d.ts +10 -0
  18. package/dist/errors.d.ts.map +1 -0
  19. package/dist/errors.js +28 -0
  20. package/dist/errors.js.map +1 -0
  21. package/dist/fs-safety.d.ts +29 -0
  22. package/dist/fs-safety.d.ts.map +1 -0
  23. package/dist/fs-safety.js +107 -0
  24. package/dist/fs-safety.js.map +1 -0
  25. package/dist/index.d.ts +5 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +4 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/llms-full.txt +659 -0
  30. package/dist/server.d.ts +2 -0
  31. package/dist/server.d.ts.map +1 -0
  32. package/dist/server.js +57 -0
  33. package/dist/server.js.map +1 -0
  34. package/dist/tools/analytics.d.ts +4 -0
  35. package/dist/tools/analytics.d.ts.map +1 -0
  36. package/dist/tools/analytics.js +82 -0
  37. package/dist/tools/analytics.js.map +1 -0
  38. package/dist/tools/backups.d.ts +4 -0
  39. package/dist/tools/backups.d.ts.map +1 -0
  40. package/dist/tools/backups.js +99 -0
  41. package/dist/tools/backups.js.map +1 -0
  42. package/dist/tools/config.d.ts +4 -0
  43. package/dist/tools/config.d.ts.map +1 -0
  44. package/dist/tools/config.js +84 -0
  45. package/dist/tools/config.js.map +1 -0
  46. package/dist/tools/corrections.d.ts +4 -0
  47. package/dist/tools/corrections.d.ts.map +1 -0
  48. package/dist/tools/corrections.js +69 -0
  49. package/dist/tools/corrections.js.map +1 -0
  50. package/dist/tools/data_stores.d.ts +4 -0
  51. package/dist/tools/data_stores.d.ts.map +1 -0
  52. package/dist/tools/data_stores.js +244 -0
  53. package/dist/tools/data_stores.js.map +1 -0
  54. package/dist/tools/documents.d.ts +4 -0
  55. package/dist/tools/documents.d.ts.map +1 -0
  56. package/dist/tools/documents.js +162 -0
  57. package/dist/tools/documents.js.map +1 -0
  58. package/dist/tools/extract.d.ts +4 -0
  59. package/dist/tools/extract.d.ts.map +1 -0
  60. package/dist/tools/extract.js +61 -0
  61. package/dist/tools/extract.js.map +1 -0
  62. package/dist/tools/files.d.ts +4 -0
  63. package/dist/tools/files.d.ts.map +1 -0
  64. package/dist/tools/files.js +198 -0
  65. package/dist/tools/files.js.map +1 -0
  66. package/dist/tools/golden_answers.d.ts +4 -0
  67. package/dist/tools/golden_answers.d.ts.map +1 -0
  68. package/dist/tools/golden_answers.js +117 -0
  69. package/dist/tools/golden_answers.js.map +1 -0
  70. package/dist/tools/helpers.d.ts +5 -0
  71. package/dist/tools/helpers.d.ts.map +1 -0
  72. package/dist/tools/helpers.js +10 -0
  73. package/dist/tools/helpers.js.map +1 -0
  74. package/dist/tools/index.d.ts +4 -0
  75. package/dist/tools/index.d.ts.map +1 -0
  76. package/dist/tools/index.js +35 -0
  77. package/dist/tools/index.js.map +1 -0
  78. package/dist/tools/jobs.d.ts +4 -0
  79. package/dist/tools/jobs.d.ts.map +1 -0
  80. package/dist/tools/jobs.js +78 -0
  81. package/dist/tools/jobs.js.map +1 -0
  82. package/dist/tools/link_sources.d.ts +4 -0
  83. package/dist/tools/link_sources.d.ts.map +1 -0
  84. package/dist/tools/link_sources.js +155 -0
  85. package/dist/tools/link_sources.js.map +1 -0
  86. package/dist/tools/misc.d.ts +8 -0
  87. package/dist/tools/misc.d.ts.map +1 -0
  88. package/dist/tools/misc.js +73 -0
  89. package/dist/tools/misc.js.map +1 -0
  90. package/dist/tools/page_questions.d.ts +4 -0
  91. package/dist/tools/page_questions.d.ts.map +1 -0
  92. package/dist/tools/page_questions.js +77 -0
  93. package/dist/tools/page_questions.js.map +1 -0
  94. package/dist/tools/personas.d.ts +4 -0
  95. package/dist/tools/personas.d.ts.map +1 -0
  96. package/dist/tools/personas.js +78 -0
  97. package/dist/tools/personas.js.map +1 -0
  98. package/dist/tools/tools_crud.d.ts +4 -0
  99. package/dist/tools/tools_crud.d.ts.map +1 -0
  100. package/dist/tools/tools_crud.js +207 -0
  101. package/dist/tools/tools_crud.js.map +1 -0
  102. package/dist/tools/types.d.ts +25 -0
  103. package/dist/tools/types.d.ts.map +1 -0
  104. package/dist/tools/types.js +15 -0
  105. package/dist/tools/types.js.map +1 -0
  106. package/llms.txt +150 -0
  107. package/package.json +53 -0
@@ -0,0 +1,659 @@
1
+ # @aigentyc/mcp — full LLM context
2
+
3
+ This file is the deep reference for AI coding tools (Cursor, Claude Code, Windsurf, Claude Desktop). It is generated from this package's docs + registered MCP tools at build time. For a short overview, read `llms.txt`.
4
+
5
+ ---
6
+
7
+ ## README.md
8
+
9
+ # @aigentyc/mcp
10
+
11
+ Model Context Protocol server for [aiGentyc](https://aigentyc.com) — lets
12
+ Claude Code, Cursor, Windsurf, and any other MCP-compatible agent drive the
13
+ content/authoring side of your aiGentyc project (documents, crawling, data
14
+ stores, custom tools, config, backups, …) without clicking through the
15
+ dashboard.
16
+
17
+ Chat/search embedding is **not** part of this package — use the separate
18
+ `aigentyc-chat-sdk` (React) for user-facing chat.
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ npx @aigentyc/mcp login \
24
+ --api-key tyco_pk_XXXX \
25
+ --project-id proj_XXXX
26
+ ```
27
+
28
+ `login` verifies the key against `/api/auth/api-keys/verify` and writes
29
+ `~/.aigentyc/config.json` with `0600` perms.
30
+
31
+ **Dev-only flag**: pass `--allow-insecure` to permit plaintext HTTP against
32
+ non-loopback hosts (e.g. a staging box without TLS). Never use this against
33
+ production — all real traffic must be HTTPS.
34
+
35
+ Then wire it into your agent:
36
+
37
+ ### Claude Desktop / Claude Code
38
+
39
+ `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
40
+
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "aigentyc": {
45
+ "command": "npx",
46
+ "args": ["-y", "@aigentyc/mcp"]
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### Cursor
53
+
54
+ Settings → MCP → add server:
55
+
56
+ ```json
57
+ {
58
+ "aigentyc": {
59
+ "command": "npx",
60
+ "args": ["-y", "@aigentyc/mcp"]
61
+ }
62
+ }
63
+ ```
64
+
65
+ ## Commands
66
+
67
+ ```
68
+ aigentyc-mcp serve Run the stdio MCP server (default when invoked with no args)
69
+ aigentyc-mcp login Save + verify an API key profile
70
+ aigentyc-mcp logout Remove a profile
71
+ aigentyc-mcp doctor Verify config + dashboard reachability
72
+ ```
73
+
74
+ ## Tools (v0.1)
75
+
76
+ Vertical slice shipped in this release:
77
+
78
+ - `documents_list`, `documents_get`, `documents_delete`, `documents_create_from_text`
79
+ - `jobs_status`, `jobs_list`, `jobs_wait`
80
+
81
+ More domains (files, link sources, data stores, custom tools, config,
82
+ backups, analytics) land in subsequent releases.
83
+
84
+ ## Security
85
+
86
+ - API keys are project-scoped; a key for project A cannot read/write B.
87
+ - `~/.aigentyc/config.json` is written `0600`. The server refuses to start
88
+ with wider perms.
89
+ - The HTTP client refuses plaintext HTTP to non-loopback hosts.
90
+ - Destructive operations (e.g. `documents_delete`) require `confirm: true`.
91
+ - Per-API-key rate limits: 300 reads/min, 60 writes/min (429 over limit).
92
+ - Every API-key-authed request is logged server-side
93
+ (`api_key_audit_log` table) with `keyId`, `projectId`, `route`,
94
+ `method`, `status`, and `X-Request-Id` for tracing.
95
+ - `files_upload` refuses paths that escape `$CWD` or `$HOME`, rejects
96
+ non-regular files, and caps batches at 50MB/file, 500MB total.
97
+ - `extract_from_urls` prefilters RFC1918 / loopback / cloud-metadata URLs.
98
+
99
+ ## Publishing
100
+
101
+ ```
102
+ cd mcp-server
103
+ npm run build
104
+ npm run smoke # stdio JSON-RPC smoke test
105
+ npm pack --dry-run # inspect what would ship
106
+ npm publish --access public
107
+ ```
108
+
109
+ ## Deferred features
110
+
111
+ Tracked for v0.2+:
112
+
113
+ - **`backups_download_all` (ZIP) secret redaction** for API-key callers.
114
+ Current implementation redacts JSON downloads but not the archived ZIP.
115
+ Session callers are unaffected. Recommendation: use session for now.
116
+ - **`/api/extract/*` dual-auth + binary-file uploads** (PDF/DOC/DOCX).
117
+ The extract proxy currently has no auth guard — not exposed to MCP.
118
+ `files_upload` is therefore restricted to UTF-8 text formats only.
119
+ - **Analytics sessions/comments write paths** — MCP is read-only by design.
120
+ - **Custom rate-limit overrides per-key** — one limit for all keys today.
121
+
122
+ ---
123
+
124
+ ## AGENTS.md
125
+
126
+ # AGENTS.md — @aigentyc/mcp
127
+
128
+ Guide for AI coding assistants (Claude Code, Cursor, Windsurf, Claude Desktop, Codex) using or contributing to this MCP server. Humans: read `README.md` first.
129
+
130
+ **Live docs (always current):** see `context7.json` in this repo for the URL Context7 mirrors.
131
+
132
+ ---
133
+
134
+ ## What this package is
135
+
136
+ A Model Context Protocol (MCP) server that lets an LLM agent drive the **content & authoring** side of an Aigentyc project: documents, files, link-source crawling, custom tools, data stores, project config, backups, analytics. It is NOT a chat client — for embedding chat into your own app use the sister package `@aigentyc/chat-sdk`.
137
+
138
+ - Package name: `@aigentyc/mcp`
139
+ - Binary: `aigentyc-mcp` (Node 20+, ESM)
140
+ - Transport: stdio (default), wire into Claude Desktop / Cursor MCP config
141
+ - Auth: project-scoped API keys (`tyco_pk_...`) verified by Aigentyc auth-service
142
+ - Storage: `~/.aigentyc/config.json` (0600, refuses to start otherwise)
143
+
144
+ ---
145
+
146
+ ## Canonical install + usage (paste-ready)
147
+
148
+ ```bash
149
+ # 1. Save + verify an API key (one-time per profile)
150
+ npx @aigentyc/mcp login \
151
+ --api-key tyco_pk_XXXX \
152
+ --project-id proj_XXXX
153
+
154
+ # 2. Wire into Claude Desktop / Cursor (one-time)
155
+ # See README for the JSON snippet. Restart the client.
156
+
157
+ # 3. Sanity check
158
+ npx @aigentyc/mcp doctor
159
+ ```
160
+
161
+ For local dev against a self-hosted backend on a different port:
162
+
163
+ ```bash
164
+ npx @aigentyc/mcp login --api-key ... --project-id ... \
165
+ --base-url http://localhost:3000 \
166
+ --allow-insecure
167
+ ```
168
+
169
+ ---
170
+
171
+ ## Decision tree: which tool to use
172
+
173
+ ```
174
+ Need to add markdown / text content to the KB? → files_upload (paths)
175
+ Need to add raw text without a file? → documents_create_from_text
176
+ Need to crawl a public website into the KB? → link_sources_create + jobs_wait
177
+ Need to extract from a list of public URLs? → extract_from_urls + jobs_wait
178
+ Need to add a structured table (rows of data)? → data_stores_create + bulk_upsert
179
+ Need to scrape a website into a data store? → data_stores_scan_website + jobs_wait
180
+ Need to expose a custom action to chat? → tools_create (rest_api / custom_execute / hybrid)
181
+ Need to chain tools? → flows_create
182
+ Need to tweak system prompt or chat model? → config_update
183
+ Need to back up before a risky change? → backups_create + jobs_wait
184
+ Need to inspect what's already in the KB? → search_kb_search (read-only, non-streaming)
185
+ Need to see analytics? → analytics_overview / sessions / comments
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Important behaviors agents should know
191
+
192
+ ### 1. Tool inputs are validated by Zod
193
+
194
+ Required string fields enforce `min(1)` server-side via the chat-tools layer. Don't try to call a tool with `""` to "see what happens" — Zod will 400 and the LLM will be told to ask the user for real values.
195
+
196
+ ### 2. Async ops return jobIds
197
+
198
+ These tools are intentionally non-blocking:
199
+ `backups_create`, `backups_restore`, `extract_from_urls`, `data_stores_scan_website`, `page_questions_auto_generate`, `files_upload` (when `indexAsDocuments=true` and the batch is large).
200
+
201
+ Pattern:
202
+ ```
203
+ const { jobId } = await tool({ ... })
204
+ const result = await jobs_wait({ jobId })
205
+ ```
206
+
207
+ There's a per-project concurrency cap of 3 active jobs. If exceeded you get 429.
208
+
209
+ ### 3. Destructive ops require `confirm: true`
210
+
211
+ `documents_delete`, `files_delete`, `data_stores_delete`, `tools_delete`, `flows_delete`, `personas_delete`, `link_sources_delete`, `golden_answers_delete`, `backups_restore`, `data_stores_bulk_delete`. The agent should ALWAYS state what's about to be deleted and ask the user to approve before passing `confirm: true`.
212
+
213
+ ### 4. Secrets are server-rejected, not just client-warned
214
+
215
+ Calling `config_update({ patch: { openaiApiKey: "..." } })` returns 403 from the server, not a client warning. Same for `customHttpHeaders` and `neonConnectionString`. To rotate secrets, use the dashboard.
216
+
217
+ ### 5. Custom tool code can't reference `process.env`
218
+
219
+ `tools_create` / `tools_update` rejects `transformCode` / `executeCode` containing `process.env`. The right way to inject secrets is `apiConfig.headers` with template placeholders that the executor resolves.
220
+
221
+ ### 6. URL inputs are SSRF-prefiltered
222
+
223
+ `extract_from_urls`, `link_sources_create` reject RFC1918 / loopback / cloud-metadata hosts both client-side AND server-side. Don't try `192.168.x.x` or `169.254.169.254` — they 400.
224
+
225
+ ### 7. File uploads are FS-sandboxed
226
+
227
+ `files_upload` rejects paths outside `$CWD` and `$HOME`, refuses non-regular files, refuses symlinks that escape, caps 50MB/file and 500MB/batch. Text formats only (`.md .txt .json .csv .html .yaml .xml .rtf .log`). Binary formats (PDF/DOC/DOCX) need to go through the dashboard's file upload — out of scope for v0.1.
228
+
229
+ ---
230
+
231
+ ## Common pitfalls
232
+
233
+ - **"Tool created but agent doesn't see it"** → fully quit + relaunch the MCP client. The MCP server registers tools at startup.
234
+
235
+ - **"Created a doc but it's not under /knowledge-base/text"** → check `sourceType`. `documents_create_from_text` always uses `manual`. URLs sourced docs need `extract_from_urls` (which links them to a `link_source`).
236
+
237
+ - **"Tool fires with empty fields"** → the tool's `inputSchema` declared a string param without `required: true`. Update the tool schema.
238
+
239
+ - **"Persona writes return 404"** → upgrade your client; older agents may hit endpoints that didn't have writes.
240
+
241
+ - **"401 from a tool that worked yesterday"** → the API key was probably revoked. Re-run `aigentyc-mcp login`.
242
+
243
+ - **"Tool calls work for me but not from my CI"** → `~/.aigentyc/config.json` doesn't exist in the CI environment. Either run `login` in a build step or set `AIGENTYC_CONFIG=/path/to/config.json` env var pointing at a CI-safe location.
244
+
245
+ ---
246
+
247
+ ## Repository layout
248
+
249
+ ```
250
+ src/
251
+ ├── cli.ts # entry: serve | login | logout | doctor
252
+ ├── server.ts # stdio MCP bootstrap (uses @modelcontextprotocol/sdk)
253
+ ├── client.ts # HTTP client (Bearer + X-Request-Id + retries + error map)
254
+ ├── config.ts # ~/.aigentyc/config.json read/write (0600 enforced)
255
+ ├── errors.ts # AigentycError + httpStatusToCode
256
+ ├── fs-safety.ts # path resolve + glob + size cap (used by files_upload)
257
+ └── tools/ # one file per domain; each exports defineTool([])
258
+ ├── documents.ts
259
+ ├── files.ts
260
+ ├── extract.ts
261
+ ├── link_sources.ts
262
+ ├── page_questions.ts
263
+ ├── data_stores.ts
264
+ ├── tools_crud.ts # custom tools + flows
265
+ ├── golden_answers.ts
266
+ ├── corrections.ts
267
+ ├── personas.ts
268
+ ├── config.ts
269
+ ├── backups.ts
270
+ ├── analytics.ts
271
+ ├── misc.ts # branches, unified_links, audience, kb_search
272
+ ├── jobs.ts # status / list / wait
273
+ └── helpers.ts # pid() + projectIdArg
274
+ ```
275
+
276
+ ---
277
+
278
+ ## Adding a new tool
279
+
280
+ 1. Pick a domain file (or create a new one if it's a new domain).
281
+ 2. Use `defineTool({ name, title, description, inputSchema, handler })` from `./types.js`.
282
+ 3. The handler gets parsed args (Zod-validated by the SDK) and an injected `DashboardClient`. Call `client.get/post/patch/delete(path, body|query)`.
283
+ 4. Register it in `src/tools/index.ts` if a new domain.
284
+ 5. Run `npm run build && npm run smoke` — the smoke test asserts no duplicate names + tool count.
285
+
286
+ Conventions:
287
+ - Tool names: `domain_action` (snake_case). Example: `documents_create_from_text`.
288
+ - Title: short human label.
289
+ - Description: tells the LLM **when** to call the tool, not **how**. Cross-reference adjacent tools when ambiguity is likely (e.g. "for URL-sourced content use extract_from_urls instead").
290
+ - Always use `pid(client, args.projectId)` to default to the active profile's projectId.
291
+ - Destructive tools: include `confirm: z.boolean().default(false)` and short-circuit when `false`.
292
+ - For long-running ops: assume the backend returns `{ jobId, status }` and don't try to wait inline. The user can chain `jobs_wait`.
293
+
294
+ ---
295
+
296
+ ## Releasing a new version
297
+
298
+ ```bash
299
+ node scripts/release.mjs # patch bump (default)
300
+ node scripts/release.mjs minor # minor bump
301
+ node scripts/release.mjs major # major bump
302
+ node scripts/release.mjs 1.2.3 # explicit
303
+ node scripts/release.mjs --dry # rehearsal (no publish)
304
+ ```
305
+
306
+ The script:
307
+ 1. Bumps `package.json` version
308
+ 2. Rewrites `context7.json` URL to self-reference the new version on jsdelivr
309
+ 3. Runs `npm run build` (TypeScript + llms-full.txt)
310
+ 4. `npm publish --access public`
311
+ 5. Polls jsdelivr until the published tarball is mirrored
312
+ 6. Prints the Context7 URLs for re-registration if needed
313
+
314
+ Requires npm credentials with publish rights on `@aigentyc`.
315
+
316
+ ---
317
+
318
+ ## Where to ask for help
319
+
320
+ - Bugs / feature requests → file in this repo
321
+ - Questions about the **platform** (`app.aigentyc.com`) → main monorepo
322
+ - Questions about embedding a chat UI → `@aigentyc/chat-sdk`
323
+
324
+ ---
325
+
326
+ ## llms.txt (overview, recipes, troubleshooting)
327
+
328
+ # @aigentyc/mcp
329
+
330
+ > Model Context Protocol server for the Aigentyc platform. Lets Claude Code, Cursor, Windsurf, Claude Desktop, and any MCP-compatible agent drive the **content & authoring** side of an Aigentyc project — documents, files, crawling, custom tools, data stores, config, backups, analytics — without clicking through the dashboard. Chat/widget embedding is handled by a separate package, `@aigentyc/chat-sdk`.
331
+
332
+ ## Install
333
+
334
+ ```bash
335
+ npx @aigentyc/mcp login \
336
+ --api-key tyco_pk_XXXX \
337
+ --project-id proj_XXXX
338
+ ```
339
+
340
+ `login` verifies the key against `/api/auth/api-keys/verify` and writes `~/.aigentyc/config.json` with `0600` perms. The server refuses to start if perms are wider.
341
+
342
+ **Dev-only flag**: pass `--allow-insecure` to permit plaintext HTTP against non-loopback hosts. Never use this against production.
343
+
344
+ ## Wire into your agent
345
+
346
+ ### Claude Desktop / Claude Code
347
+
348
+ `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
349
+
350
+ ```json
351
+ {
352
+ "mcpServers": {
353
+ "aigentyc": {
354
+ "command": "npx",
355
+ "args": ["-y", "@aigentyc/mcp"]
356
+ }
357
+ }
358
+ }
359
+ ```
360
+
361
+ ### Cursor
362
+
363
+ Settings → MCP → add server:
364
+
365
+ ```json
366
+ {
367
+ "aigentyc": {
368
+ "command": "npx",
369
+ "args": ["-y", "@aigentyc/mcp"]
370
+ }
371
+ }
372
+ ```
373
+
374
+ Restart the client. The new tools appear under the `aigentyc` namespace.
375
+
376
+ ## Commands
377
+
378
+ ```
379
+ aigentyc-mcp serve Start the stdio MCP server (default)
380
+ aigentyc-mcp login Save + verify an API key profile
381
+ aigentyc-mcp logout Remove a profile
382
+ aigentyc-mcp doctor Verify config + transport + clock skew + reachability
383
+ ```
384
+
385
+ ## Tools (82 total, 19 domains)
386
+
387
+ - **documents** — list, get, delete, create_from_text, merge, versions
388
+ - **files** — list, get, upload (path-based), delete, reprocess, versions, bulk_audience
389
+ - **extract** — from_urls (jobified for api-key)
390
+ - **link_sources** — list, get, create, update, delete, list_items, update_item, delete_item
391
+ - **page_questions** — list, set_manual, auto_generate (jobified), delete_page
392
+ - **data_stores** — full CRUD + bulk_upsert + import + export + scan_website (jobified)
393
+ - **tools** (custom-tool CRUD) — list, get, create, update, delete, execute_dry_run
394
+ - **flows** — list, get, create, update, delete
395
+ - **golden_answers** — list, create, update, delete + ai_improve + ai_generate_variations
396
+ - **corrections** — list, create, update_status
397
+ - **personas** — list, upsert, delete
398
+ - **config** — get (secrets redacted for api-key), update (secret writes rejected)
399
+ - **backups** — list, create (jobified), restore (jobified), download, import, delete
400
+ - **analytics** — overview, sessions, session_timeline, comments
401
+ - **branches** — list
402
+ - **search** — kb_search (read-only authoring aid)
403
+ - **jobs** — status, list, wait
404
+
405
+ ## Async job pattern
406
+
407
+ Long-running ops (backup create/restore, extract, data-store scan, page-questions auto-generate) return `{ jobId, status: "queued" }`. Poll with `jobs_wait`:
408
+
409
+ ```
410
+ extract_from_urls({ urls: [...] })
411
+ → { jobId: "abc-123", status: "queued" }
412
+ jobs_wait({ jobId: "abc-123" })
413
+ → blocks until terminal; returns { status: "completed", result: {...} }
414
+ ```
415
+
416
+ Concurrency cap: 3 active jobs per project.
417
+
418
+ ## Security
419
+
420
+ - **Project-scoped keys**: a key for project A cannot read/write project B (403).
421
+ - **Per-key rate limits**: 300 reads/min, 60 writes/min. 429 with `Retry-After` over the limit.
422
+ - **Secrets**: `config.get` redacts `openaiApiKey` + `customHttpHeaders` to `***` for api-key callers. `config.update` rejects writes to those fields with 403. Backup downloads (single + ZIP) deep-redact secrets.
423
+ - **Custom tool code**: `tools.create` rejects `transformCode` / `executeCode` containing `process.env`. Use `apiConfig.headers` with template placeholders for secrets.
424
+ - **Destructive ops** (`*.delete`, `backups.restore`): require `confirm: true`.
425
+ - **Path uploads**: `files.upload` refuses paths outside `$CWD` / `$HOME`, refuses non-regular files, caps 50MB/file, 500MB/batch.
426
+ - **URL inputs**: `extract.from_urls` + `link_sources.create` reject RFC1918 / loopback / cloud-metadata hosts.
427
+ - **Audit log**: every api-key request is logged server-side (`api_key_audit_log` table) with `keyId`, `projectId`, `route`, `method`, `status`, `latencyMs`, `requestId`. Reads sampled at 10%; writes 100%.
428
+
429
+ ## Recipes
430
+
431
+ ### Add a markdown KB from local files
432
+
433
+ ```
434
+ files_upload({ paths: ["docs/intro.md", "docs/api.md"], indexAsDocuments: true })
435
+ ```
436
+
437
+ The MCP reads each file (text formats only — `.md`, `.txt`, `.json`, `.csv`, `.html`, …), uploads metadata to `uploaded_files`, then chunks + embeds + indexes via `documents/create`.
438
+
439
+ ### Crawl a website + dedupe before adding more docs
440
+
441
+ ```
442
+ 1. link_sources_create({ sourceUrl: "https://example.com", sourceType: "website" })
443
+ 2. jobs_wait({ jobId: ... }) — wait for crawl to finish
444
+ 3. search_kb_search({ query: "billing FAQ" }) // confirm it indexed
445
+ ```
446
+
447
+ ### Build a custom tool end-to-end
448
+
449
+ ```
450
+ 1. tools_create({
451
+ name: "submitForm",
452
+ toolType: "rest_api",
453
+ apiConfig: { method: "POST", url: "...", body: "name={{name}}" },
454
+ inputSchema: [{ name: "name", type: "string", required: true }],
455
+ })
456
+ 2. tools_execute_dry_run({ toolId, input: { name: "Test" } })
457
+ // verify output before exposing to chat
458
+ ```
459
+
460
+ ### Update system prompt
461
+
462
+ ```
463
+ config_update({ patch: { systemPrompt: "You are the support agent for ACME..." } })
464
+ ```
465
+
466
+ (Cannot update `openaiApiKey` over api-key — use the dashboard for secrets.)
467
+
468
+ ## Troubleshooting
469
+
470
+ - **404 on login** — auth-service may be on a different origin in dev. `login` falls back to dashboard ping. Use `--base-url http://localhost:3000` for local Docker.
471
+ - **Tool calls hang** — confirm `aigentyc-mcp doctor` passes. Most failures are wrong base-url, expired key, or clock skew (>60s breaks auth).
472
+ - **Tool created but UI doesn't show it** — fully restart Claude Desktop / Cursor. Server-side caches invalidate on every write; client-side router caches don't.
473
+ - **Empty fields on tool call** — required string fields with `min(1)` get rejected by Zod, prompting the LLM to gather real values from the user. If a tool fires with empty inputs, the field wasn't marked required at creation.
474
+
475
+ ## Versioning
476
+
477
+ Server (`@aigentyc/mcp` on npm) and platform (`app.aigentyc.com`) version independently. The platform maintains backward compatibility with older MCP releases — endpoints aren't broken without deprecation.
478
+
479
+ ---
480
+
481
+ ## Tool surface (live snapshot)
482
+
483
+ All MCP tools registered at server startup, grouped by domain prefix. Use these names verbatim when invoking via an MCP client.
484
+
485
+
486
+ _Total tools: **82**_
487
+
488
+
489
+ ### `analytics`
490
+
491
+ | tool | description |
492
+ | ---- | ----------- |
493
+ | `analytics_audience_overview` | Aggregate metrics for audience segments (document counts, coverage). |
494
+ | `analytics_overview` | Aggregate KPIs (sessions, messages, cost, latency, feedback) for a time window. Defaults to the last 30 days. |
495
+ | `analytics_sessions` | Paginated list of chat sessions with summary data, optional text search and date window. |
496
+ | `analytics_session_timeline` | Full Q&A timeline (messages + search events) for a single session. |
497
+ | `analytics_comments` | Project-wide list of admin-authored feedback comments on chat messages, ordered newest first. |
498
+
499
+ ### `backups`
500
+
501
+ | tool | description |
502
+ | ---- | ----------- |
503
+ | `backups_list` | List available project backups (Qdrant snapshots + MySQL exports). |
504
+ | `backups_create` | Snapshot the project's Qdrant collections + MySQL data. Synchronous; may take tens of seconds on large projects. |
505
+ | `backups_restore` | Restore the project's Qdrant + MySQL state from a backup. HIGHLY DESTRUCTIVE: overwrites current data. |
506
+ | `backups_download` | Download a backup by index. type='mysql' returns JSON (secrets redacted for API-key callers); type='qdrant' returns an opaque Qdrant snapshot reference. |
507
+ | `backups_import` | Upload a previously-exported backup JSON blob. |
508
+ | `backups_delete` | Delete a backup by index. Destructive. |
509
+
510
+ ### `branches`
511
+
512
+ | tool | description |
513
+ | ---- | ----------- |
514
+ | `branches_list` | List named branches of the knowledge base (draft vs published workspaces). |
515
+
516
+ ### `config`
517
+
518
+ | tool | description |
519
+ | ---- | ----------- |
520
+ | `config_get` | Fetch the full project configuration. When called via API key, secret fields (openaiApiKey, customHttpHeaders) are redacted to '***'. |
521
+ | `config_update` | Patch project config. Send only the fields you want to change. Secret fields (openaiApiKey, customHttpHeaders, neonConnectionString) cannot be updated via API key and will be rejected with 403. |
522
+
523
+ ### `corrections`
524
+
525
+ | tool | description |
526
+ | ---- | ----------- |
527
+ | `corrections_list` | List user feedback / suggested edits against the knowledge base. Corrections are NOT auto-applied — review + mark status. |
528
+ | `corrections_create` | Record a suggested correction for a past Q&A. Status starts as 'pending'. |
529
+ | `corrections_update_status` | Set a correction's status to 'applied' or 'dismissed'. |
530
+
531
+ ### `data`
532
+
533
+ | tool | description |
534
+ | ---- | ----------- |
535
+ | `data_stores_list` | List structured data tables (data stores) in the project. |
536
+ | `data_stores_create` | Create a new data store (structured table) with a schema. |
537
+ | `data_stores_get` | Fetch a data store's schema + metadata. |
538
+ | `data_stores_update` | Patch a data store's name, description, columns, or settings. |
539
+ | `data_stores_delete` | Delete a data store and all its rows. Destructive. |
540
+ | `data_stores_list_rows` | List rows in a data store with pagination + optional search. |
541
+ | `data_stores_create_row` | Insert one row into a data store. |
542
+ | `data_stores_update_row` | Update one row in a data store by id. |
543
+ | `data_stores_delete_row` | Delete one row by id. |
544
+ | `data_stores_bulk_upsert` | Insert many rows at once (max 10k). Does not dedupe by default. |
545
+ | `data_stores_bulk_delete` | Delete multiple rows by id in one call. Destructive. |
546
+ | `data_stores_import` | Bulk-import rows (≤10k) with optional column schema. `replaceExisting: true` wipes existing rows first. |
547
+ | `data_stores_export` | Export all rows of a data store as JSON. |
548
+ | `data_stores_scan_website` | Crawl a website and extract structured rows into the store. Returns a jobId; use jobs_wait to block until done. |
549
+
550
+ ### `documents`
551
+
552
+ | tool | description |
553
+ | ---- | ----------- |
554
+ | `documents_list` | List documents in a project with pagination, search, and filtering. Returns document summaries (name, chunk count, source). |
555
+ | `documents_get` | Get all chunks of a single document by name, including enrichment metadata. |
556
+ | `documents_delete` | Delete all chunks of a document (including non-current versions) from MySQL and Qdrant. Destructive. |
557
+ | `documents_create_from_text` | Create a new manual-text document in the knowledge base. Chunks, embeds, and indexes synchronously. Shows up under the dashboard's 'Text' tab. For URL-sourced content use extract_from_urls instead (it goes through the crawler and links to a link_source). For file uploads use files_upload. |
558
+ | `documents_merge` | Merge two consecutive chunks of the same document into one. Re-embeds the merged content and updates Qdrant. Provide the merged content verbatim. |
559
+ | `documents_versions` | action=list → return version history for a specific chunk (documentName + chunkIndex). action=create → create a new version of a chunk (documentId + newContent + changeReason). |
560
+
561
+ ### `extract`
562
+
563
+ | tool | description |
564
+ | ---- | ----------- |
565
+ | `extract_from_urls` | Batch-extract documents from a list of URLs into the project's knowledge base. Returns synchronously when fast; for large batches the backend may return a jobId (then use jobs_wait). |
566
+
567
+ ### `files`
568
+
569
+ | tool | description |
570
+ | ---- | ----------- |
571
+ | `files_list` | List files uploaded into the project's ingestion pipeline. |
572
+ | `files_get` | Get metadata + extraction status for a single uploaded file. |
573
+ | `files_versions` | List all versions of a file (same sourceUrl / family). |
574
+ | `files_delete` | Delete an uploaded file and (optionally) its derived documents. Destructive. |
575
+ | `files_reprocess` | Re-run embedding for all current document chunks derived from this file. Use after changing embedding model or chunk settings. |
576
+ | `files_upload` | Read text-based files (.md, .txt, .json, .csv, .html, …) from the user's local filesystem and ingest them into the project. Binary formats (pdf/doc/docx) are not supported in v0.1. Paths must be absolute or relative to CWD, cannot escape \$HOME, and are capped at 50MB/file and 500MB/batch. |
577
+ | `files_bulk_audience` | Assign an audience tag to multiple files at once. Audiences gate document visibility in search. |
578
+
579
+ ### `flows`
580
+
581
+ | tool | description |
582
+ | ---- | ----------- |
583
+ | `flows_list` | List multi-step tool flows (orchestrations) in the project. |
584
+ | `flows_get` | Fetch a single tool flow. |
585
+ | `flows_create` | Create a multi-step tool flow. |
586
+ | `flows_update` | Patch a flow's fields. |
587
+ | `flows_delete` | Delete a flow. Destructive. |
588
+
589
+ ### `golden`
590
+
591
+ | tool | description |
592
+ | ---- | ----------- |
593
+ | `golden_answers_list` | List high-priority Q&A pairs used for search ranking and fallback responses. |
594
+ | `golden_answers_create` | Create a golden Q&A pair. |
595
+ | `golden_answers_update` | Patch a golden answer by id. |
596
+ | `golden_answers_delete` | Delete a golden answer by id. Destructive. |
597
+ | `golden_answers_ai_improve` | Ask the AI to rewrite a response for a query in a chosen tone. Returns `improvedResponse` — you decide whether to save. |
598
+ | `golden_answers_ai_generate_variations` | Generate paraphrased variations of a question to improve retrieval. Returns `variations: [{question, context?}]`. |
599
+
600
+ ### `jobs`
601
+
602
+ | tool | description |
603
+ | ---- | ----------- |
604
+ | `jobs_status` | Fetch the current status of a long-running job created by another MCP tool. |
605
+ | `jobs_list` | List recent long-running jobs for the project. Useful for debugging. |
606
+ | `jobs_wait` | Poll a job until it reaches a terminal state (completed, failed, cancelled). Returns the final row. |
607
+
608
+ ### `kb`
609
+
610
+ | tool | description |
611
+ | ---- | ----------- |
612
+ | `kb_search` | Hybrid / vector search over the project KB. Non-streaming. Use BEFORE creating documents to check for overlap/duplicates. |
613
+
614
+ ### `link`
615
+
616
+ | tool | description |
617
+ | ---- | ----------- |
618
+ | `link_sources_list` | List website/pdf link sources configured for the project. Each source tracks discovered URLs + processing state. |
619
+ | `link_sources_get` | Fetch a single link source with its status + discovered item counts. |
620
+ | `link_sources_create` | Register a new website or PDF source and kick off discovery. Returns the source row. |
621
+ | `link_sources_update` | Update audience tags or crawl parameters on an existing source. |
622
+ | `link_sources_delete` | Delete a link source and its discovered items. Does not delete derived documents. Destructive. |
623
+ | `link_sources_list_items` | Paginated list of discovered URLs for a given link source. Filter by isProcessed / isSkipped. |
624
+ | `link_sources_update_item` | Mark a discovered item as processed/skipped. Used to override crawler decisions. |
625
+ | `link_sources_delete_item` | Remove one URL from a link source's discovered set. |
626
+
627
+ ### `page`
628
+
629
+ | tool | description |
630
+ | ---- | ----------- |
631
+ | `page_questions_list` | List per-page suggested questions pinned to specific URLs on the user's own site. |
632
+ | `page_questions_set_manual` | Set the suggested questions + welcome text shown for a specific page URL. Overwrites existing. |
633
+ | `page_questions_auto_generate` | Auto-generate Q&A for a page URL (runs AI over scanned document content) and persist as manual questions. Returns a jobId — poll with jobs_wait. |
634
+ | `page_questions_delete_page` | Remove the page questions entry for a specific URL. |
635
+
636
+ ### `personas`
637
+
638
+ | tool | description |
639
+ | ---- | ----------- |
640
+ | `personas_list` | List the chat personas configured for the project. Personas are used by the AudienceSelector and define tone/style/custom instructions for different audience segments. |
641
+ | `personas_upsert` | Upsert a chat persona identified by `key`. If a persona with that key exists it is patched, otherwise a new one is created. The persona defines tone, response length, language style, and custom instructions for the chat agent when this persona is active. |
642
+ | `personas_delete` | Delete a persona by key. Destructive. |
643
+
644
+ ### `tools`
645
+
646
+ | tool | description |
647
+ | ---- | ----------- |
648
+ | `tools_list` | List every custom tool in the project (rest_api, custom_execute, hybrid, data_store, web_search). |
649
+ | `tools_get` | Fetch one custom tool with its full config. |
650
+ | `tools_create` | Create a custom tool the chat agent can call. Tool code referencing `process.env` is rejected — put secrets in apiConfig.headers with template placeholders. |
651
+ | `tools_update` | Patch selected fields of an existing custom tool. |
652
+ | `tools_delete` | Delete a custom tool. Destructive. |
653
+ | `tools_execute_dry_run` | Invoke a custom tool in test mode with sample input. Safe for iteration; does not count against usage. |
654
+
655
+ ### `unified`
656
+
657
+ | tool | description |
658
+ | ---- | ----------- |
659
+ | `unified_links_list` | Get the aggregated catalog of every URL known to the project (files + link sources + manual). |
@@ -0,0 +1,2 @@
1
+ export declare function runStdioServer(): Promise<void>;
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAWA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAyDpD"}