@directive-run/knowledge 1.14.0 → 1.16.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 +50 -15
- package/ai/ai-adapters.md +7 -0
- package/ai/ai-agents-streaming.md +187 -149
- package/ai/ai-budget-resilience.md +305 -132
- package/ai/ai-communication.md +220 -197
- package/ai/ai-debug-observability.md +259 -173
- package/ai/ai-guardrails-memory.md +191 -153
- package/ai/ai-mcp-rag.md +204 -199
- package/ai/ai-multi-agent.md +254 -153
- package/ai/ai-orchestrator.md +353 -114
- package/ai/ai-security.md +287 -180
- package/ai/ai-tasks.md +8 -1
- package/ai/ai-testing-evals.md +363 -256
- package/core/anti-patterns.md +18 -2
- package/core/constraints.md +13 -2
- package/core/core-patterns.md +12 -0
- package/core/error-boundaries.md +8 -0
- package/core/history.md +7 -0
- package/core/multi-module.md +15 -3
- package/core/naming.md +128 -90
- package/core/plugins.md +7 -0
- package/core/react-adapter.md +256 -174
- package/core/resolvers.md +10 -0
- package/core/schema-types.md +8 -0
- package/core/system-api.md +10 -0
- package/core/testing.md +257 -143
- package/examples/checkers.ts +15 -16
- package/examples/contact-form.ts +2 -2
- package/examples/counter-react.ts +1 -1
- package/examples/counter-svelte.ts +1 -1
- package/examples/counter-vue.ts +1 -1
- package/examples/counter.ts +1 -1
- package/examples/data-triggers.ts +4 -4
- package/examples/feature-flags.ts +2 -2
- package/examples/form-wizard.ts +2 -2
- package/examples/newsletter.ts +2 -2
- package/examples/server.ts +2 -2
- package/examples/shopping-cart.ts +1 -1
- package/examples/topic-guard.ts +1 -1
- package/package.json +3 -3
- package/sitemap.md +17 -11
- package/examples/debounce-constraints.ts +0 -95
- package/examples/multi-module.ts +0 -58
package/ai/ai-mcp-rag.md
CHANGED
|
@@ -1,288 +1,293 @@
|
|
|
1
|
-
# AI MCP
|
|
1
|
+
# AI MCP + RAG
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Covers `@directive-run/ai/mcp` and `@directive-run/ai` — MCP adapter (`createMCPAdapter`), RAG enricher, embedder utilities.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Model Context Protocol (MCP) server integration and Retrieval-Augmented Generation (RAG) enrichment for Directive AI agents. Import from `@directive-run/ai/mcp` for the MCP adapter (the main barrel re-exports it with `@deprecated` notices for v2 removal), and from `@directive-run/ai` for the RAG enricher + embedder utilities.
|
|
6
|
+
|
|
7
|
+
## Decision tree
|
|
6
8
|
|
|
7
9
|
```
|
|
8
10
|
What do you need?
|
|
9
|
-
├── External tool servers (MCP)
|
|
10
|
-
│ ├── stdio transport
|
|
11
|
-
│ └── SSE transport
|
|
12
|
-
│
|
|
13
|
-
├── Knowledge retrieval (RAG) → createRAGEnricher({ embedder, storage })
|
|
14
|
-
│ ├── Need embeddings → createOpenAIEmbedder() or createAnthropicEmbedder()
|
|
15
|
-
│ ├── Need vector storage → createJSONFileStore() or custom VectorStore
|
|
16
|
-
│ └── Need chunk ingestion → enricher.ingest(documents)
|
|
11
|
+
├── External tool servers (MCP) → createMCPAdapter({ servers, ... })
|
|
12
|
+
│ ├── stdio transport → command-based MCP servers
|
|
13
|
+
│ └── SSE transport → HTTP-based MCP servers
|
|
17
14
|
│
|
|
18
|
-
|
|
19
|
-
├──
|
|
20
|
-
├──
|
|
21
|
-
|
|
15
|
+
├── Knowledge retrieval (RAG) → createRAGEnricher({ embedder, storage })
|
|
16
|
+
│ ├── User-supplied embeddings → EmbedderFn = (text) => Promise<number[]>
|
|
17
|
+
│ ├── Batched embedding calls → createBatchedEmbedder({ embed, batchSize, ... })
|
|
18
|
+
│ ├── Vector storage → createJSONFileStore(opts) or your own RAGStorage
|
|
19
|
+
│ └── Ingest documents → enricher.ingest(documents)
|
|
22
20
|
```
|
|
23
21
|
|
|
24
|
-
## MCP
|
|
22
|
+
## MCP server integration
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
The MCP adapter manages connections to one or more MCP servers, exposes their tools to your agents, and provides constraint-driven approval + risk-scoring for tool calls.
|
|
27
25
|
|
|
28
26
|
```typescript
|
|
29
|
-
import { createMCPAdapter } from "@directive-run/ai";
|
|
27
|
+
import { createMCPAdapter, type MCPTool } from "@directive-run/ai/mcp";
|
|
30
28
|
|
|
31
29
|
const mcp = createMCPAdapter({
|
|
32
30
|
servers: [
|
|
33
|
-
|
|
34
|
-
{
|
|
35
|
-
name: "tools",
|
|
36
|
-
transport: "stdio",
|
|
37
|
-
command: "npx mcp-server-tools",
|
|
38
|
-
},
|
|
39
|
-
// SSE transport – connects to an HTTP server
|
|
40
|
-
{
|
|
41
|
-
name: "data",
|
|
42
|
-
transport: "sse",
|
|
43
|
-
url: "http://localhost:3001/sse",
|
|
44
|
-
},
|
|
31
|
+
{ name: "tools", transport: "stdio", command: "npx", args: ["mcp-server-tools"] },
|
|
32
|
+
{ name: "data", transport: "sse", url: "http://localhost:3001/sse" },
|
|
45
33
|
],
|
|
46
|
-
|
|
47
|
-
// Per-tool constraints
|
|
48
34
|
toolConstraints: {
|
|
49
|
-
"tools/dangerous-tool": {
|
|
50
|
-
requireApproval:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
35
|
+
"tools/dangerous-tool": { requireApproval: true, maxAttempts: 3 },
|
|
36
|
+
"tools/read-only": { requireApproval: false },
|
|
37
|
+
},
|
|
38
|
+
autoConnect: false, // default false — opt-in to connecting on creation
|
|
39
|
+
autoReconnect: true, // default false — opt-in to reconnect on disconnect
|
|
40
|
+
approvalTimeoutMs: 5 * 60 * 1000, // default 300_000
|
|
41
|
+
allowDirectCalls: false, // default false — must be true to use callToolDirect()
|
|
42
|
+
clientFactory: (cfg) => new Client(cfg), // optional — supply a real MCP SDK client
|
|
43
|
+
events: {
|
|
44
|
+
onConnect: ({ server }) => console.log(`mcp:${server} up`),
|
|
45
|
+
onDisconnect: ({ server, reason }) => console.warn(`mcp:${server} down — ${reason}`),
|
|
46
|
+
onToolCall: ({ server, tool, args }) => log("mcp:tool", { server, tool }),
|
|
47
|
+
onApproval: (request) => showApprovalDialog(request),
|
|
56
48
|
},
|
|
57
|
-
|
|
58
|
-
// Connection options
|
|
59
|
-
connectionTimeout: 10000,
|
|
60
|
-
reconnect: true,
|
|
61
49
|
});
|
|
62
50
|
|
|
63
|
-
// Connect to all servers
|
|
64
51
|
await mcp.connect();
|
|
65
52
|
|
|
66
|
-
// Get available tools
|
|
67
|
-
const
|
|
53
|
+
// Get available tools — returns Map<serverName, MCPTool[]>, NOT a flat array
|
|
54
|
+
const toolsMap: Map<string, MCPTool[]> = mcp.getTools();
|
|
55
|
+
const flatTools = Array.from(toolsMap.values()).flat();
|
|
68
56
|
|
|
69
57
|
// Use tools with an agent
|
|
70
58
|
const agent = {
|
|
71
59
|
name: "researcher",
|
|
72
60
|
instructions: "Use available tools to research topics.",
|
|
73
61
|
model: "claude-sonnet-4-5",
|
|
74
|
-
tools:
|
|
62
|
+
tools: flatTools,
|
|
75
63
|
};
|
|
76
64
|
```
|
|
77
65
|
|
|
78
|
-
|
|
66
|
+
## MCP server lifecycle
|
|
67
|
+
|
|
68
|
+
The lifecycle verbs are `connect` / `connectServer(name)` for opening connections, and `disconnect()` / `disconnectServer(name)` for closing them. There is no `mcp.disconnect("name")` mixed form, no `mcp.disconnectAll()`, and no `mcp.getStatus()`.
|
|
79
69
|
|
|
80
70
|
```typescript
|
|
81
|
-
//
|
|
82
|
-
|
|
71
|
+
// Connect everything
|
|
72
|
+
await mcp.connect();
|
|
83
73
|
|
|
84
|
-
//
|
|
85
|
-
|
|
74
|
+
// Or one server at a time
|
|
75
|
+
await mcp.connectServer("tools");
|
|
76
|
+
|
|
77
|
+
// Status — typed per-server
|
|
78
|
+
const single: MCPServerState | undefined = mcp.getServerStatus("tools");
|
|
79
|
+
const all: Map<string, MCPServerState> = mcp.getAllServerStatuses();
|
|
80
|
+
|
|
81
|
+
// Disconnect one server
|
|
82
|
+
await mcp.disconnectServer("tools");
|
|
83
|
+
|
|
84
|
+
// Disconnect all
|
|
85
|
+
await mcp.disconnect();
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
## MCP
|
|
88
|
+
## Calling MCP tools with constraints
|
|
89
|
+
|
|
90
|
+
`callTool(server, tool, args, facts)` applies per-tool constraints (rate limits, approvals, argument-size caps). Use this in resolvers. `callToolDirect(server, tool, args)` bypasses the constraint pipeline — only available when `allowDirectCalls: true`.
|
|
89
91
|
|
|
90
92
|
```typescript
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
const result = await mcp.callTool(
|
|
94
|
+
"tools",
|
|
95
|
+
"search-docs",
|
|
96
|
+
{ query: "directive constraints" },
|
|
97
|
+
context.facts, // for constraint evaluation
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// For trusted internal calls only:
|
|
101
|
+
const direct = await mcp.callToolDirect("tools", "internal-ping", {});
|
|
102
|
+
```
|
|
93
103
|
|
|
94
|
-
|
|
95
|
-
const status = mcp.getStatus();
|
|
96
|
-
// { tools: "connected", data: "connected" }
|
|
104
|
+
## Approval workflow for sensitive tools
|
|
97
105
|
|
|
98
|
-
|
|
99
|
-
await mcp.disconnect("tools");
|
|
106
|
+
When `toolConstraints[…].requireApproval: true`, the adapter queues an `MCPApprovalRequest` instead of executing immediately. Surface it via `events.onApproval` and resolve via the instance methods.
|
|
100
107
|
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
```typescript
|
|
109
|
+
const pending = mcp.getPendingApprovals();
|
|
110
|
+
mcp.approve(request.id);
|
|
111
|
+
mcp.reject(request.id, "violates data policy");
|
|
103
112
|
|
|
104
|
-
//
|
|
105
|
-
|
|
113
|
+
// Read the rejection reason for a previously-resolved request
|
|
114
|
+
const reason = mcp.getRejectionReason(request.id);
|
|
106
115
|
```
|
|
107
116
|
|
|
108
|
-
##
|
|
117
|
+
## Resource sync
|
|
118
|
+
|
|
119
|
+
MCP also exposes resources (read-only content the agent can pull). `syncResources` materializes them into Directive facts so constraints can react to them.
|
|
109
120
|
|
|
110
121
|
```typescript
|
|
111
|
-
|
|
122
|
+
const resourcesMap = mcp.getResources(); // Map<serverName, MCPResource[]>
|
|
123
|
+
const oneResource = await mcp.readResource("data", "file://config.yaml");
|
|
124
|
+
await mcp.syncResources(system.facts);
|
|
125
|
+
```
|
|
112
126
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
127
|
+
## RAG enrichment
|
|
128
|
+
|
|
129
|
+
`createRAGEnricher` wires an embedder + a vector store into an agent's input pipeline, retrieving relevant context chunks before the agent runs.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import {
|
|
133
|
+
createRAGEnricher,
|
|
134
|
+
createJSONFileStore,
|
|
135
|
+
createBatchedEmbedder,
|
|
136
|
+
createTestEmbedder,
|
|
137
|
+
type EmbedderFn,
|
|
138
|
+
type RAGEnricher,
|
|
139
|
+
} from "@directive-run/ai";
|
|
140
|
+
|
|
141
|
+
// 1. Supply an embedder. EmbedderFn = (text: string) => Promise<number[]>
|
|
142
|
+
// There is no createOpenAIEmbedder / createAnthropicEmbedder factory —
|
|
143
|
+
// you bring your own and pass it through createBatchedEmbedder for production.
|
|
144
|
+
const rawEmbed: EmbedderFn = async (text) => {
|
|
145
|
+
const res = await myEmbedAPI.embed(text);
|
|
146
|
+
return res.embedding;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const { embed } = createBatchedEmbedder({
|
|
150
|
+
embed: rawEmbed,
|
|
151
|
+
batchSize: 16,
|
|
152
|
+
flushIntervalMs: 50,
|
|
117
153
|
});
|
|
118
154
|
|
|
119
|
-
|
|
155
|
+
// 2. Storage — a JSON file store for prototyping, or your own RAGStorage adapter
|
|
156
|
+
const storage = createJSONFileStore({ path: "./rag-store.json" });
|
|
120
157
|
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
},
|
|
127
|
-
},
|
|
158
|
+
const enricher: RAGEnricher = createRAGEnricher({
|
|
159
|
+
embedder: embed,
|
|
160
|
+
storage,
|
|
161
|
+
topK: 5,
|
|
162
|
+
minSimilarity: 0.7,
|
|
128
163
|
});
|
|
129
164
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
165
|
+
// 3. Ingest documents
|
|
166
|
+
await enricher.ingest([
|
|
167
|
+
{ id: "doc-1", text: "Directive is a constraint-driven runtime…", metadata: { source: "README.md" } },
|
|
168
|
+
{ id: "doc-2", text: "Auto-tracked derivations recompute on read…", metadata: { source: "concepts" } },
|
|
169
|
+
]);
|
|
170
|
+
|
|
171
|
+
// 4. Use the enricher in your runner pipeline
|
|
172
|
+
const enrichedRunner: AgentRunner = async (agent, input, opts) => {
|
|
173
|
+
const enriched = await enricher.enrich(input);
|
|
174
|
+
return baseRunner(agent, enriched, opts);
|
|
135
175
|
};
|
|
136
176
|
|
|
137
|
-
const
|
|
177
|
+
const orchestrator = createAgentOrchestrator({ runner: enrichedRunner });
|
|
138
178
|
```
|
|
139
179
|
|
|
140
|
-
|
|
180
|
+
For testing without API calls, use `createTestEmbedder(dimensions?)` — deterministic, no network.
|
|
141
181
|
|
|
142
|
-
##
|
|
182
|
+
## Anti-patterns
|
|
143
183
|
|
|
144
|
-
|
|
184
|
+
### `mcp.disconnect(name)` / `mcp.disconnectAll()`
|
|
145
185
|
|
|
146
186
|
```typescript
|
|
147
|
-
|
|
148
|
-
|
|
187
|
+
// WRONG — neither shape exists
|
|
188
|
+
await mcp.disconnect("tools");
|
|
189
|
+
await mcp.disconnectAll();
|
|
149
190
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}),
|
|
191
|
+
// CORRECT
|
|
192
|
+
await mcp.disconnectServer("tools");
|
|
193
|
+
await mcp.disconnect();
|
|
194
|
+
```
|
|
155
195
|
|
|
156
|
-
|
|
157
|
-
storage: createJSONFileStore({ filePath: "./chunks.json" }),
|
|
196
|
+
### `mcp.getStatus()`
|
|
158
197
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
198
|
+
```typescript
|
|
199
|
+
// WRONG — no flat-object status method
|
|
200
|
+
const status = mcp.getStatus(); // ?? { tools: "connected", data: "connected" }
|
|
162
201
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
},
|
|
167
|
-
});
|
|
202
|
+
// CORRECT — typed per-server
|
|
203
|
+
const all = mcp.getAllServerStatuses(); // Map<name, MCPServerState>
|
|
204
|
+
const one = mcp.getServerStatus("tools"); // MCPServerState | undefined
|
|
168
205
|
```
|
|
169
206
|
|
|
170
|
-
|
|
207
|
+
### Treating `mcp.getTools()` as a flat array
|
|
171
208
|
|
|
172
209
|
```typescript
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
content: "Directive uses proxy-based facts for auto-tracking.",
|
|
177
|
-
metadata: { source: "docs", topic: "facts" },
|
|
178
|
-
},
|
|
179
|
-
{
|
|
180
|
-
content: "Derivations are auto-tracked computed values.",
|
|
181
|
-
metadata: { source: "docs", topic: "derivations" },
|
|
182
|
-
},
|
|
183
|
-
]);
|
|
210
|
+
// WRONG — getTools() returns Map<serverName, MCPTool[]>
|
|
211
|
+
const flat: MCPTool[] = mcp.getTools();
|
|
212
|
+
agent.tools = flat;
|
|
184
213
|
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
chunkOverlap: 50,
|
|
189
|
-
metadata: { source: "architecture" },
|
|
190
|
-
});
|
|
214
|
+
// CORRECT — flatten if your agent expects a flat list
|
|
215
|
+
const flat = Array.from(mcp.getTools().values()).flat();
|
|
216
|
+
agent.tools = flat;
|
|
191
217
|
```
|
|
192
218
|
|
|
193
|
-
|
|
219
|
+
### Importing from `@directive-run/ai` only
|
|
194
220
|
|
|
195
221
|
```typescript
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
prefix: "Use this context to answer:\n",
|
|
199
|
-
});
|
|
200
|
-
// Result: "Use this context to answer:\n[0.92] Directive uses proxy-based..."
|
|
222
|
+
// WORKS, but fires v2-deprecation notices
|
|
223
|
+
import { createMCPAdapter } from "@directive-run/ai";
|
|
201
224
|
|
|
202
|
-
//
|
|
203
|
-
|
|
204
|
-
prefix: "Use this context:\n",
|
|
205
|
-
history: messages,
|
|
206
|
-
});
|
|
225
|
+
// PREFERRED — the subpath barrel is the v2-stable import
|
|
226
|
+
import { createMCPAdapter } from "@directive-run/ai/mcp";
|
|
207
227
|
```
|
|
208
228
|
|
|
209
|
-
|
|
229
|
+
### `MCPAdapterConfig` option names from a different library
|
|
210
230
|
|
|
211
231
|
```typescript
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
232
|
+
// WRONG — these options don't exist
|
|
233
|
+
createMCPAdapter({
|
|
234
|
+
servers,
|
|
235
|
+
connectionTimeout: 10_000,
|
|
236
|
+
reconnect: true,
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
// CORRECT — the real names
|
|
240
|
+
createMCPAdapter({
|
|
241
|
+
servers,
|
|
242
|
+
autoConnect: true,
|
|
243
|
+
autoReconnect: true,
|
|
244
|
+
approvalTimeoutMs: 300_000,
|
|
245
|
+
allowDirectCalls: false,
|
|
246
|
+
clientFactory: (cfg) => new Client(cfg),
|
|
247
|
+
})
|
|
227
248
|
```
|
|
228
249
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
Implement the `Embedder` interface for any provider:
|
|
250
|
+
### `createOpenAIEmbedder` / `createAnthropicEmbedder`
|
|
232
251
|
|
|
233
252
|
```typescript
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
const
|
|
237
|
-
embed: async (texts: string[]) => {
|
|
238
|
-
// Return float arrays, one per input text
|
|
239
|
-
const embeddings = await myEmbeddingAPI.embed(texts);
|
|
240
|
-
|
|
241
|
-
return embeddings.map((e) => e.vector);
|
|
242
|
-
},
|
|
243
|
-
|
|
244
|
-
dimensions: 1536, // Vector dimensions
|
|
245
|
-
};
|
|
253
|
+
// WRONG — no provider-specific embedder factories ship from @directive-run/ai
|
|
254
|
+
import { createOpenAIEmbedder } from "@directive-run/ai/openai";
|
|
255
|
+
const embedder = createOpenAIEmbedder({ apiKey });
|
|
246
256
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
topK: 5,
|
|
251
|
-
minSimilarity: 0.3,
|
|
252
|
-
});
|
|
257
|
+
// CORRECT — supply your own EmbedderFn, optionally batched
|
|
258
|
+
const rawEmbed: EmbedderFn = async (text) => (await openai.embeddings.create({ input: text, model: "text-embedding-3-small" })).data[0].embedding;
|
|
259
|
+
const { embed } = createBatchedEmbedder({ embed: rawEmbed, batchSize: 16 });
|
|
253
260
|
```
|
|
254
261
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
Implement the `VectorStore` interface for any backend:
|
|
262
|
+
### Treating `Embedder` as an object with `embed(texts[]): number[][]`
|
|
258
263
|
|
|
259
264
|
```typescript
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
const pgStore: VectorStore = {
|
|
263
|
-
add: async (chunks) => {
|
|
264
|
-
await db.query("INSERT INTO chunks ...", chunks);
|
|
265
|
-
},
|
|
266
|
-
search: async (vector, topK) => {
|
|
267
|
-
const results = await db.query(
|
|
268
|
-
"SELECT * FROM chunks ORDER BY embedding <=> $1 LIMIT $2",
|
|
269
|
-
[vector, topK],
|
|
270
|
-
);
|
|
265
|
+
// WRONG — there is no Embedder interface; the EmbedderFn signature takes ONE string
|
|
266
|
+
type Embedder = { embed(texts: string[]): Promise<number[][]>; dimensions: number };
|
|
271
267
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
clear: async () => {
|
|
275
|
-
await db.query("DELETE FROM chunks");
|
|
276
|
-
},
|
|
277
|
-
};
|
|
268
|
+
// CORRECT — single string in, single vector out
|
|
269
|
+
type EmbedderFn = (text: string) => Promise<number[]>;
|
|
278
270
|
```
|
|
279
271
|
|
|
280
|
-
## Quick
|
|
281
|
-
|
|
282
|
-
| API |
|
|
283
|
-
|
|
284
|
-
| `createMCPAdapter` | `@directive-run/ai` | Connect to MCP
|
|
285
|
-
| `
|
|
286
|
-
| `
|
|
287
|
-
| `
|
|
288
|
-
| `
|
|
272
|
+
## Quick reference
|
|
273
|
+
|
|
274
|
+
| API | Path | Returns | Purpose |
|
|
275
|
+
|---|---|---|---|
|
|
276
|
+
| `createMCPAdapter(config)` | `@directive-run/ai/mcp` | `MCPAdapter` | Connect to MCP servers, expose tools |
|
|
277
|
+
| `mcp.connect()` / `connectServer(name)` | instance method | `Promise<void>` | Open one or all connections |
|
|
278
|
+
| `mcp.disconnect()` / `disconnectServer(name)` | instance method | `Promise<void>` | Close one or all connections |
|
|
279
|
+
| `mcp.getTools()` | instance method | `Map<string, MCPTool[]>` | All tools, keyed by server |
|
|
280
|
+
| `mcp.getResources()` | instance method | `Map<string, MCPResource[]>` | All resources, keyed by server |
|
|
281
|
+
| `mcp.callTool(server, tool, args, facts)` | instance method | `Promise<MCPToolResult>` | Constraint-checked tool call |
|
|
282
|
+
| `mcp.callToolDirect(server, tool, args)` | instance method | `Promise<MCPToolResult>` | Bypass constraints (requires `allowDirectCalls: true`) |
|
|
283
|
+
| `mcp.getServerStatus(name)` / `getAllServerStatuses()` | instance method | `MCPServerState` | Per-server connection state |
|
|
284
|
+
| `mcp.approve(id)` / `reject(id, reason?)` | instance method | `void` | Resolve a pending approval |
|
|
285
|
+
| `createRAGEnricher(config)` | `@directive-run/ai` | `RAGEnricher` | Embedding-driven context retrieval |
|
|
286
|
+
| `createBatchedEmbedder(config)` | `@directive-run/ai` | `{ embed, flush, dispose }` | Wrap an EmbedderFn with batching |
|
|
287
|
+
| `createTestEmbedder(dim?)` | `@directive-run/ai` | `EmbedderFn` | Deterministic embedder for tests |
|
|
288
|
+
| `createJSONFileStore(options)` | `@directive-run/ai` | `RAGStorage` | File-backed vector store for prototyping |
|
|
289
|
+
|
|
290
|
+
## See also
|
|
291
|
+
|
|
292
|
+
- [`ai-orchestrator.md`](./ai-orchestrator.md) — where MCP-supplied tools and RAG-enriched runners flow into agent runs
|
|
293
|
+
- [`ai-security.md`](./ai-security.md) — `toolConstraints[…].requireApproval` and the per-tool approval workflow the MCP adapter exposes
|