ctxpkg 0.0.1

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 (61) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +282 -0
  3. package/bin/cli.js +8 -0
  4. package/bin/daemon.js +7 -0
  5. package/package.json +70 -0
  6. package/src/agent/AGENTS.md +249 -0
  7. package/src/agent/agent.prompts.ts +66 -0
  8. package/src/agent/agent.test-runner.schemas.ts +158 -0
  9. package/src/agent/agent.test-runner.ts +436 -0
  10. package/src/agent/agent.ts +371 -0
  11. package/src/agent/agent.types.ts +94 -0
  12. package/src/backend/AGENTS.md +112 -0
  13. package/src/backend/backend.protocol.ts +95 -0
  14. package/src/backend/backend.schemas.ts +123 -0
  15. package/src/backend/backend.services.ts +151 -0
  16. package/src/backend/backend.ts +111 -0
  17. package/src/backend/backend.types.ts +34 -0
  18. package/src/cli/AGENTS.md +213 -0
  19. package/src/cli/cli.agent.ts +197 -0
  20. package/src/cli/cli.chat.ts +369 -0
  21. package/src/cli/cli.client.ts +55 -0
  22. package/src/cli/cli.collections.ts +491 -0
  23. package/src/cli/cli.config.ts +252 -0
  24. package/src/cli/cli.daemon.ts +160 -0
  25. package/src/cli/cli.documents.ts +413 -0
  26. package/src/cli/cli.mcp.ts +177 -0
  27. package/src/cli/cli.ts +28 -0
  28. package/src/cli/cli.utils.ts +122 -0
  29. package/src/client/AGENTS.md +135 -0
  30. package/src/client/client.adapters.ts +279 -0
  31. package/src/client/client.ts +86 -0
  32. package/src/client/client.types.ts +17 -0
  33. package/src/collections/AGENTS.md +185 -0
  34. package/src/collections/collections.schemas.ts +195 -0
  35. package/src/collections/collections.ts +1160 -0
  36. package/src/config/config.ts +118 -0
  37. package/src/daemon/AGENTS.md +168 -0
  38. package/src/daemon/daemon.config.ts +23 -0
  39. package/src/daemon/daemon.manager.ts +215 -0
  40. package/src/daemon/daemon.schemas.ts +22 -0
  41. package/src/daemon/daemon.ts +205 -0
  42. package/src/database/AGENTS.md +211 -0
  43. package/src/database/database.ts +64 -0
  44. package/src/database/migrations/migrations.001-init.ts +56 -0
  45. package/src/database/migrations/migrations.002-fts5.ts +32 -0
  46. package/src/database/migrations/migrations.ts +20 -0
  47. package/src/database/migrations/migrations.types.ts +9 -0
  48. package/src/documents/AGENTS.md +301 -0
  49. package/src/documents/documents.schemas.ts +190 -0
  50. package/src/documents/documents.ts +734 -0
  51. package/src/embedder/embedder.ts +53 -0
  52. package/src/exports.ts +0 -0
  53. package/src/mcp/AGENTS.md +264 -0
  54. package/src/mcp/mcp.ts +105 -0
  55. package/src/tools/AGENTS.md +228 -0
  56. package/src/tools/agent/agent.ts +45 -0
  57. package/src/tools/documents/documents.ts +401 -0
  58. package/src/tools/tools.langchain.ts +37 -0
  59. package/src/tools/tools.mcp.ts +46 -0
  60. package/src/tools/tools.types.ts +35 -0
  61. package/src/utils/utils.services.ts +46 -0
@@ -0,0 +1,53 @@
1
+ import { type FeatureExtractionPipeline, pipeline } from '@huggingface/transformers';
2
+
3
+ // Instruction prefix for query embeddings (mxbai-embed format)
4
+ const QUERY_INSTRUCTION = 'Represent this sentence for searching relevant passages: ';
5
+
6
+ class EmbedderService {
7
+ #pipeline?: Promise<FeatureExtractionPipeline>;
8
+
9
+ #setup = async () => {
10
+ const extractor = await pipeline('feature-extraction', 'mixedbread-ai/mxbai-embed-large-v1', {
11
+ dtype: 'fp32',
12
+ });
13
+ return extractor;
14
+ };
15
+
16
+ public getExtractor = async () => {
17
+ if (!this.#pipeline) {
18
+ this.#pipeline = this.#setup();
19
+ }
20
+ return await this.#pipeline;
21
+ };
22
+
23
+ /**
24
+ * Create embeddings for documents (no instruction prefix).
25
+ * Use this when indexing document chunks.
26
+ */
27
+ public createDocumentEmbeddings = async (inputs: string[]): Promise<number[][]> => {
28
+ const extractor = await this.getExtractor();
29
+ const output = await extractor(inputs, { pooling: 'cls' });
30
+ return output.tolist();
31
+ };
32
+
33
+ /**
34
+ * Create embedding for a search query (with instruction prefix).
35
+ * Use this when searching for relevant documents.
36
+ */
37
+ public createQueryEmbedding = async (query: string): Promise<number[]> => {
38
+ const extractor = await this.getExtractor();
39
+ const instructedQuery = `${QUERY_INSTRUCTION}${query}`;
40
+ const output = await extractor([instructedQuery], { pooling: 'cls' });
41
+ return output.tolist()[0];
42
+ };
43
+
44
+ /**
45
+ * @deprecated Use createDocumentEmbeddings or createQueryEmbedding instead.
46
+ * Kept for backwards compatibility.
47
+ */
48
+ public createEmbeddings = async (inputs: string[]): Promise<number[][]> => {
49
+ return this.createDocumentEmbeddings(inputs);
50
+ };
51
+ }
52
+
53
+ export { EmbedderService };
package/src/exports.ts ADDED
File without changes
@@ -0,0 +1,264 @@
1
+ # MCP — Agent Guidelines
2
+
3
+ This document describes the MCP module architecture for AI agents working on this codebase.
4
+
5
+ ## Overview
6
+
7
+ The MCP module provides [Model Context Protocol](https://modelcontextprotocol.io/) server integration. It creates MCP servers that expose ctxpkg's document tools to AI editors like Cursor, Claude Desktop, and other MCP-compatible clients. The server communicates over stdio transport.
8
+
9
+ ## File Structure
10
+
11
+ | File | Purpose |
12
+ |------|---------|
13
+ | `mcp.ts` | MCP server creation and stdio runner |
14
+
15
+ ## Architecture
16
+
17
+ ```
18
+ ┌─────────────────────────────────────────────────────────────┐
19
+ │ AI Editor / Client │
20
+ │ (Cursor, Claude Desktop, etc.) │
21
+ └──────────────────────────┬──────────────────────────────────┘
22
+ │ stdio (JSON-RPC)
23
+
24
+ ┌─────────────────────────────────────────────────────────────┐
25
+ │ MCP Server │
26
+ │ ┌───────────────────────────────────────────────────────┐ │
27
+ │ │ StdioServerTransport │ │
28
+ │ └───────────────────────────────────────────────────────┘ │
29
+ │ │ │
30
+ │ ┌───────────────────────▼───────────────────────────────┐ │
31
+ │ │ McpServer │ │
32
+ │ │ (from @modelcontextprotocol/sdk) │ │
33
+ │ └───────────────────────────────────────────────────────┘ │
34
+ │ │ │
35
+ │ ┌───────────────────────▼───────────────────────────────┐ │
36
+ │ │ Document Tools │ │
37
+ │ │ • documents_list_collections │ │
38
+ │ │ • documents_search │ │
39
+ │ │ • documents_get_document │ │
40
+ │ │ • documents_list_documents │ │
41
+ │ │ • documents_get_outline │ │
42
+ │ │ • documents_get_section │ │
43
+ │ │ • documents_search_batch │ │
44
+ │ │ • documents_find_related │ │
45
+ │ └───────────────────────────────────────────────────────┘ │
46
+ │ │ │
47
+ │ ┌───────────────────────▼───────────────────────────────┐ │
48
+ │ │ BackendClient │ │
49
+ │ │ (connects to daemon/direct) │ │
50
+ │ └───────────────────────────────────────────────────────┘ │
51
+ └─────────────────────────────────────────────────────────────┘
52
+ ```
53
+
54
+ ## Usage
55
+
56
+ ### Starting the MCP Server
57
+
58
+ Via CLI:
59
+
60
+ ```bash
61
+ # Start with all collections
62
+ ctxpkg mcp documents
63
+
64
+ # Limit to specific collections
65
+ ctxpkg mcp documents -c my-docs langchain-docs
66
+
67
+ # Custom server name/version
68
+ ctxpkg mcp documents --name my-server --version 2.0.0
69
+ ```
70
+
71
+ ### Programmatic Usage
72
+
73
+ ```typescript
74
+ import { createDocumentsMcpServer, runMcpServer } from '#root/mcp/mcp.ts';
75
+ import { createClient } from '#root/client/client.ts';
76
+
77
+ const client = await createClient({ mode: 'daemon' });
78
+
79
+ const server = createDocumentsMcpServer({
80
+ client,
81
+ name: 'my-mcp-server',
82
+ version: '1.0.0',
83
+ aliasMap: new Map([['docs', 'pkg:file://./docs/manifest.json']]),
84
+ });
85
+
86
+ await runMcpServer(server);
87
+ ```
88
+
89
+ ## Editor Configuration
90
+
91
+ ### Cursor
92
+
93
+ Add to `.cursor/mcp.json`:
94
+
95
+ ```json
96
+ {
97
+ "mcpServers": {
98
+ "ctxpkg": {
99
+ "command": "ctxpkg",
100
+ "args": ["mcp", "documents"]
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ ### Claude Desktop
107
+
108
+ Add to Claude Desktop config:
109
+
110
+ ```json
111
+ {
112
+ "mcpServers": {
113
+ "ctxpkg": {
114
+ "command": "ctxpkg",
115
+ "args": ["mcp", "documents"]
116
+ }
117
+ }
118
+ }
119
+ ```
120
+
121
+ ## Server Modes
122
+
123
+ ### Documents Mode (default)
124
+
125
+ Exposes all document tools individually. The calling agent decides which tools to use.
126
+
127
+ ```bash
128
+ ctxpkg mcp documents
129
+ ```
130
+
131
+ ### Agent Mode
132
+
133
+ Exposes a single `ask_documents` tool. An internal LangChain agent handles searching and synthesizes a single answer. This reduces token/context costs for the calling agent.
134
+
135
+ ```bash
136
+ ctxpkg mcp agent
137
+ ```
138
+
139
+ Requires LLM configuration:
140
+ ```bash
141
+ ctxpkg config set llm.apiKey sk-...
142
+ ctxpkg config set llm.model gpt-4o
143
+ ```
144
+
145
+ ## Exposed Tools
146
+
147
+ ### Documents Mode
148
+
149
+ The MCP server exposes these tools to AI agents:
150
+
151
+ | Tool | Description |
152
+ |------|-------------|
153
+ | `documents_list_collections` | List available document collections with descriptions and versions |
154
+ | `documents_search` | Semantic search across documents using hybrid vector + keyword matching |
155
+ | `documents_get_document` | Get full document content |
156
+ | `documents_list_documents` | List all documents in a collection (table of contents) |
157
+ | `documents_get_outline` | Get document heading structure without fetching full content |
158
+ | `documents_get_section` | Get a specific section of a document by heading |
159
+ | `documents_search_batch` | Execute multiple search queries in a single call (max 10) |
160
+ | `documents_find_related` | Find content semantically related to a document or chunk |
161
+
162
+ See `src/tools/documents/` for tool implementation details.
163
+
164
+ ### Agent Mode
165
+
166
+ | Tool | Description |
167
+ |------|-------------|
168
+ | `ask_documents` | Ask a question with a use case; internal agent searches and synthesizes answer |
169
+
170
+ The `ask_documents` tool requires both a query and a use case to help the agent determine when sufficient information has been found.
171
+
172
+ See `src/tools/agent/` and `src/agent/` for implementation details.
173
+
174
+ ## Key Components
175
+
176
+ ### `createDocumentsMcpServer(options)`
177
+
178
+ Creates an MCP server instance with document tools:
179
+
180
+ ```typescript
181
+ type DocumentsMcpServerOptions = {
182
+ client: BackendClient; // Required: backend connection
183
+ name?: string; // Server name (default: 'ctxpkg-documents')
184
+ version?: string; // Server version (default: '1.0.0')
185
+ collections?: string[]; // Limit to specific collections
186
+ aliasMap?: Map<string, string>; // Project alias → collection ID
187
+ };
188
+ ```
189
+
190
+ ### `createAgentMcpServer(options)`
191
+
192
+ Creates an MCP server with agent mode (single `ask_documents` tool):
193
+
194
+ ```typescript
195
+ type AgentMcpServerOptions = {
196
+ client: BackendClient; // Required: backend connection
197
+ llmConfig: LLMConfig; // Required: LLM configuration
198
+ name?: string; // Server name (default: 'ctxpkg-agent')
199
+ version?: string; // Server version (default: '1.0.0')
200
+ aliasMap?: Map<string, string>; // Project alias → collection ID
201
+ maxIterations?: number; // Max agent iterations (default: 15)
202
+ };
203
+ ```
204
+
205
+ ### `runMcpServer(server)`
206
+
207
+ Connects the server to stdio transport and handles shutdown:
208
+
209
+ - Creates `StdioServerTransport`
210
+ - Connects server to transport
211
+ - Registers SIGINT/SIGTERM handlers for graceful shutdown
212
+
213
+ ## Adding New MCP Servers
214
+
215
+ To create an MCP server with different tools:
216
+
217
+ ```typescript
218
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
219
+ import { registerMcpTools } from '#root/tools/tools.mcp.ts';
220
+
221
+ const createMyMcpServer = (options: MyOptions) => {
222
+ const server = new McpServer({
223
+ name: options.name ?? 'my-server',
224
+ version: options.version ?? '1.0.0',
225
+ });
226
+
227
+ // Create tool definitions
228
+ const tools = createMyToolDefinitions(options);
229
+
230
+ // Register on MCP server
231
+ registerMcpTools(server, tools);
232
+
233
+ return server;
234
+ };
235
+ ```
236
+
237
+ Then add a CLI command in `cli.mcp.ts` to start it.
238
+
239
+ ## Key Patterns
240
+
241
+ ### Alias Resolution
242
+
243
+ Project aliases (from `context.json`) are resolved to collection IDs:
244
+
245
+ ```typescript
246
+ const aliasMap = new Map<string, string>();
247
+ for (const [alias, spec] of Object.entries(projectConfig.collections)) {
248
+ const collectionId = collectionsService.computeCollectionId(spec, cwd);
249
+ aliasMap.set(alias, collectionId);
250
+ }
251
+ ```
252
+
253
+ This allows users to search by friendly names like `"langchain"` instead of `"pkg:https://..."`.
254
+
255
+ ### Graceful Shutdown
256
+
257
+ The server handles shutdown signals to close cleanly:
258
+
259
+ ```typescript
260
+ process.on('SIGINT', async () => {
261
+ await server.close();
262
+ process.exit(0);
263
+ });
264
+ ```
package/src/mcp/mcp.ts ADDED
@@ -0,0 +1,105 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+
4
+ import { createDocumentAgent, type CreateDocumentAgentOptions } from '#root/agent/agent.ts';
5
+ import type { LLMConfig } from '#root/agent/agent.types.ts';
6
+ import type { BackendClient } from '#root/client/client.ts';
7
+ import { createAgentToolDefinitions } from '#root/tools/agent/agent.ts';
8
+ import { createDocumentToolDefinitions } from '#root/tools/documents/documents.ts';
9
+ import { registerMcpTools } from '#root/tools/tools.mcp.ts';
10
+
11
+ type McpServerOptions = {
12
+ /** Name of the MCP server */
13
+ name?: string;
14
+ /** Version of the MCP server */
15
+ version?: string;
16
+ };
17
+
18
+ type DocumentsMcpServerOptions = McpServerOptions & {
19
+ /** Backend client for accessing the documents service */
20
+ client: BackendClient;
21
+ /** Collections to limit searches to (optional, uses cwd and default collections if not specified) */
22
+ collections?: string[];
23
+ /** Optional map of project aliases to collection IDs */
24
+ aliasMap?: Map<string, string>;
25
+ };
26
+
27
+ type AgentMcpServerOptions = McpServerOptions & {
28
+ /** Backend client for accessing the documents service */
29
+ client: BackendClient;
30
+ /** LLM configuration for the agent */
31
+ llmConfig: LLMConfig;
32
+ /** Optional map of project aliases to collection IDs */
33
+ aliasMap?: Map<string, string>;
34
+ /** Maximum agent iterations */
35
+ maxIterations?: number;
36
+ };
37
+
38
+ /**
39
+ * Create an MCP server with document tools.
40
+ */
41
+ const createDocumentsMcpServer = (options: DocumentsMcpServerOptions) => {
42
+ const { client, aliasMap, name = 'ctxpkg-documents', version = '1.0.0' } = options;
43
+
44
+ const server = new McpServer({
45
+ name,
46
+ version,
47
+ });
48
+
49
+ // Create and register document tools
50
+ const documentTools = createDocumentToolDefinitions({ client, aliasMap });
51
+ registerMcpTools(server, documentTools);
52
+
53
+ return server;
54
+ };
55
+
56
+ /**
57
+ * Create an MCP server with agent mode (single ask_documents tool).
58
+ * The internal agent uses LLM to search and synthesize answers.
59
+ */
60
+ const createAgentMcpServer = (options: AgentMcpServerOptions) => {
61
+ const { client, aliasMap, llmConfig, maxIterations, name = 'ctxpkg-agent', version = '1.0.0' } = options;
62
+
63
+ const server = new McpServer({
64
+ name,
65
+ version,
66
+ });
67
+
68
+ // Create document agent
69
+ const agentOptions: CreateDocumentAgentOptions = {
70
+ client,
71
+ llmConfig,
72
+ aliasMap,
73
+ maxIterations,
74
+ };
75
+ const agent = createDocumentAgent(agentOptions);
76
+
77
+ // Create and register agent tools (just ask_documents)
78
+ const agentTools = createAgentToolDefinitions({ agent });
79
+ registerMcpTools(server, agentTools);
80
+
81
+ return server;
82
+ };
83
+
84
+ /**
85
+ * Run an MCP server over stdio transport.
86
+ * This is the main entry point for running as a standalone MCP server.
87
+ */
88
+ const runMcpServer = async (server: McpServer) => {
89
+ const transport = new StdioServerTransport();
90
+ await server.connect(transport);
91
+
92
+ // Handle graceful shutdown
93
+ process.on('SIGINT', async () => {
94
+ await server.close();
95
+ process.exit(0);
96
+ });
97
+
98
+ process.on('SIGTERM', async () => {
99
+ await server.close();
100
+ process.exit(0);
101
+ });
102
+ };
103
+
104
+ export { createAgentMcpServer, createDocumentsMcpServer, runMcpServer };
105
+ export type { AgentMcpServerOptions, DocumentsMcpServerOptions, McpServerOptions };
@@ -0,0 +1,228 @@
1
+ # Tools — Agent Guidelines
2
+
3
+ This document describes the tools module architecture for AI agents working on this codebase.
4
+
5
+ ## Overview
6
+
7
+ The tools module provides AI agent tools in a framework-agnostic format. Tools are defined once using a common format and can be adapted to different runtimes (MCP, LangChain). This allows the same tool logic to work across different AI frameworks.
8
+
9
+ ## File Structure
10
+
11
+ ```
12
+ src/tools/
13
+ ├── tools.types.ts # Common tool definition types
14
+ ├── tools.mcp.ts # MCP server adapter
15
+ ├── tools.langchain.ts # LangChain adapter
16
+ ├── documents/
17
+ │ └── documents.ts # Document tools
18
+ ├── files/
19
+ │ └── files.ts # File system tools (legacy)
20
+ └── git/
21
+ └── git.ts # Git tools (legacy)
22
+ ```
23
+
24
+ ## Architecture
25
+
26
+ ```
27
+ ┌─────────────────────────────────────────────────────────────┐
28
+ │ Tool Definitions │
29
+ │ (framework-agnostic format) │
30
+ │ │
31
+ │ defineTool({ │
32
+ │ name: 'tool_name', │
33
+ │ description: '...', │
34
+ │ schema: z.object({...}), │
35
+ │ handler: async (input) => {...} │
36
+ │ }) │
37
+ └─────────────────────────────────────────────────────────────┘
38
+
39
+ ┌───────────────┴───────────────┐
40
+ ▼ ▼
41
+ ┌─────────────────────┐ ┌─────────────────────┐
42
+ │ tools.mcp.ts │ │ tools.langchain.ts │
43
+ │ registerMcpTools() │ │ toLangchainTools() │
44
+ └─────────────────────┘ └─────────────────────┘
45
+ │ │
46
+ ▼ ▼
47
+ ┌─────────────────────┐ ┌─────────────────────┐
48
+ │ MCP Server │ │ LangChain Agent │
49
+ └─────────────────────┘ └─────────────────────┘
50
+ ```
51
+
52
+ ## Tool Definition Format
53
+
54
+ Tools use a common format with Zod schemas:
55
+
56
+ ```typescript
57
+ import { defineTool } from '#root/tools/tools.types.ts';
58
+ import * as z from 'zod';
59
+
60
+ const myTool = defineTool({
61
+ name: 'my_tool_name',
62
+ description: 'What the tool does and when to use it',
63
+ schema: z.object({
64
+ query: z.string().describe('Parameter description'),
65
+ limit: z.number().optional().default(10),
66
+ }),
67
+ handler: async ({ query, limit }) => {
68
+ // Tool logic here
69
+ return { result: 'data' };
70
+ },
71
+ });
72
+ ```
73
+
74
+ ### Key Fields
75
+
76
+ | Field | Purpose |
77
+ |-------|---------|
78
+ | `name` | Unique identifier (use snake_case with category prefix) |
79
+ | `description` | Help AI understand when/how to use the tool |
80
+ | `schema` | Zod schema for input validation with `.describe()` on fields |
81
+ | `handler` | Async function that executes the tool logic |
82
+
83
+ ## Using Tools
84
+
85
+ ### With MCP Server
86
+
87
+ ```typescript
88
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
89
+ import { registerMcpTools } from '#root/tools/tools.mcp.ts';
90
+ import { createDocumentToolDefinitions } from '#root/tools/documents/documents.ts';
91
+
92
+ const server = new McpServer({ name: 'my-server', version: '1.0.0' });
93
+ const tools = createDocumentToolDefinitions({ client });
94
+
95
+ registerMcpTools(server, tools);
96
+ ```
97
+
98
+ ### With LangChain
99
+
100
+ ```typescript
101
+ import { toLangchainTools } from '#root/tools/tools.langchain.ts';
102
+ import { createDocumentToolDefinitions } from '#root/tools/documents/documents.ts';
103
+
104
+ const definitions = createDocumentToolDefinitions({ client });
105
+ const langchainTools = toLangchainTools(definitions);
106
+
107
+ // Use with LangChain agent
108
+ const agent = createToolCallingAgent({ tools: Object.values(langchainTools), ... });
109
+ ```
110
+
111
+ ## Adding New Tools
112
+
113
+ ### 1. Create Tool Definitions
114
+
115
+ Create a new file in appropriate category folder:
116
+
117
+ ```typescript
118
+ // src/tools/myfeature/myfeature.ts
119
+ import * as z from 'zod';
120
+ import { defineTool, type ToolDefinitions } from '#root/tools/tools.types.ts';
121
+
122
+ type MyFeatureToolOptions = {
123
+ client: BackendClient;
124
+ };
125
+
126
+ const createMyFeatureToolDefinitions = (options: MyFeatureToolOptions): ToolDefinitions => {
127
+ const { client } = options;
128
+
129
+ const doSomething = defineTool({
130
+ name: 'myfeature_do_something',
131
+ description: 'Does something useful. Use this when...',
132
+ schema: z.object({
133
+ input: z.string().describe('The input to process'),
134
+ }),
135
+ handler: async ({ input }) => {
136
+ const result = await client.myFeature.process({ input });
137
+ return result;
138
+ },
139
+ });
140
+
141
+ return { doSomething };
142
+ };
143
+
144
+ export { createMyFeatureToolDefinitions };
145
+ ```
146
+
147
+ ### 2. Register on MCP Server
148
+
149
+ In `src/mcp/mcp.ts` or relevant MCP setup:
150
+
151
+ ```typescript
152
+ import { createMyFeatureToolDefinitions } from '#root/tools/myfeature/myfeature.ts';
153
+
154
+ const tools = createMyFeatureToolDefinitions({ client });
155
+ registerMcpTools(server, tools);
156
+ ```
157
+
158
+ ## Tool Categories
159
+
160
+ ### Document Tools (`documents/`)
161
+
162
+ Tools for searching and retrieving indexed documentation:
163
+
164
+ - `documents_list_collections` — List available collections with descriptions and versions
165
+ - `documents_search` — Semantic search across documents with hybrid vector + keyword matching
166
+ - `documents_get_document` — Get full document content
167
+ - `documents_list_documents` — List all documents in a collection (table of contents)
168
+ - `documents_get_outline` — Get document heading structure without fetching full content
169
+ - `documents_get_section` — Get a specific section of a document by heading
170
+ - `documents_search_batch` — Execute multiple search queries in a single call
171
+ - `documents_find_related` — Find content semantically related to a document or chunk
172
+
173
+ ### File Tools (`files/`) — Legacy
174
+
175
+ Direct file system access tools (LangChain format):
176
+
177
+ - `file_get_content` — Read file content
178
+ - `file_glob_files` — Find files by glob pattern
179
+ - `file_search_multiline` — Search file contents with regex
180
+ - `file_get_stats` — Get file metadata
181
+
182
+ ### Git Tools (`git/`) — Legacy
183
+
184
+ Git repository tools (LangChain format):
185
+
186
+ - `git_status` — Repository status
187
+ - `git_get_diff` — File diffs
188
+ - `git_get_log` — Commit history
189
+
190
+ ## Best Practices
191
+
192
+ ### Naming
193
+
194
+ - Use category prefix: `documents_`, `files_`, `git_`
195
+ - Use snake_case: `documents_list_collections`
196
+ - Be descriptive: `search` → `documents_search`
197
+
198
+ ### Descriptions
199
+
200
+ Write descriptions that help AI agents understand:
201
+ - What the tool does
202
+ - When to use it
203
+ - What input it expects
204
+ - What output it returns
205
+
206
+ ```typescript
207
+ description:
208
+ 'Search reference documents using semantic similarity. ' +
209
+ 'Returns the most relevant document chunks for the given query. ' +
210
+ 'Use this to find information in documentation, guides, or other indexed reference materials.',
211
+ ```
212
+
213
+ ### Schema Descriptions
214
+
215
+ Add `.describe()` to all schema fields:
216
+
217
+ ```typescript
218
+ schema: z.object({
219
+ query: z.string().describe('The search query - describe what information you are looking for'),
220
+ limit: z.number().optional().default(10).describe('Maximum number of results to return'),
221
+ }),
222
+ ```
223
+
224
+ ### Return Values
225
+
226
+ - Return structured data (objects/arrays) — adapters handle JSON serialization
227
+ - Return helpful error messages as strings
228
+ - Include relevant context in results
@@ -0,0 +1,45 @@
1
+ import * as z from 'zod';
2
+
3
+ import type { DocumentAgent } from '#root/agent/agent.ts';
4
+ import { defineTool, type ToolDefinitions } from '#root/tools/tools.types.ts';
5
+
6
+ type AgentToolOptions = {
7
+ /** Document agent instance */
8
+ agent: DocumentAgent;
9
+ };
10
+
11
+ /**
12
+ * Creates the ask_documents tool definition for agent mode MCP.
13
+ * This exposes a single tool that uses an internal agent to search and synthesize.
14
+ */
15
+ const createAgentToolDefinitions = (options: AgentToolOptions): ToolDefinitions => {
16
+ const { agent } = options;
17
+
18
+ const askDocuments = defineTool({
19
+ name: 'ask_documents',
20
+ description:
21
+ 'Ask a question about the indexed documentation. An internal agent will search, ' +
22
+ 'read relevant sections, and synthesize a comprehensive answer. Returns only the ' +
23
+ 'final answer, not intermediate search results. Requires both a query and a use case ' +
24
+ 'to help determine when sufficient information has been found.',
25
+ schema: z.object({
26
+ query: z.string().describe('The question to answer. Be specific about what information you need.'),
27
+ use_case: z
28
+ .string()
29
+ .describe(
30
+ 'Why you need this information and how it will be used. ' +
31
+ 'This helps determine when enough information has been found. ' +
32
+ 'Example: "I need to understand authentication flow to implement login in my app"',
33
+ ),
34
+ }),
35
+ handler: async ({ query, use_case }) => {
36
+ const response = await agent.ask(query, use_case);
37
+ return response;
38
+ },
39
+ });
40
+
41
+ return { askDocuments };
42
+ };
43
+
44
+ export { createAgentToolDefinitions };
45
+ export type { AgentToolOptions };