@evomap/evolver-mcp 2.0.0-beta.2 → 2.0.0-beta.22

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/dist/stdio.js CHANGED
@@ -8,11 +8,17 @@ import { buildEvolverTools } from './tools.js';
8
8
  import { buildEvolverPrimer } from './primer.js';
9
9
  import { EvolverMcpServer, UnknownToolError } from './server.js';
10
10
  import { reachableProxyClientFromEnv } from './proxyClient.js';
11
- import { loadEnvFileFromEnv } from './envFile.js';
12
- const envFile = loadEnvFileFromEnv(process.env);
13
- if (envFile.error) {
14
- process.stderr.write(`[evolver-mcp] failed to load EVOLVER_ENV_FILE: ${envFile.error}\n`);
11
+ import { loadEnvFileFromEnvOrThrow } from './envFile.js';
12
+ import { bootstrap } from '@evomap/evolver-core';
13
+ try {
14
+ loadEnvFileFromEnvOrThrow(process.env);
15
15
  }
16
+ catch {
17
+ process.stderr.write('[evolver-mcp] fatal: failed to load EVOLVER_ENV_FILE\n');
18
+ process.exit(1);
19
+ }
20
+ // Emit deprecation warnings for any V1 env vars still present in the environment.
21
+ bootstrap.checkV1EnvCompat(process.env);
16
22
  const store = new assetstore.LocalJsonlProvider(events.assetsDir());
17
23
  const mailboxPath = process.env['EVOLVER_MCP_MAILBOX'] ?? join(events.evomapHome(), 'mailbox', 'mcp.db');
18
24
  mkdirSync(dirname(mailboxPath), { recursive: true });
package/dist/tools.js CHANGED
@@ -155,7 +155,7 @@ export function buildEvolverTools(deps) {
155
155
  // Self-onboarding (#mcp-onboarding): any MCP agent can learn the quiet reuse loop when it needs guidance.
156
156
  // Mirrors the initialize.instructions primer; always present, but no longer asks the agent to narrate routine work.
157
157
  name: 'evolver_guide',
158
- description: '按需说明 evolver 的静默复用机制(search→reuse→capture 循环)与各工具何时调用;不要向用户叙述例行预检、状态或空搜索。',
158
+ description: '按需说明 evolver 的静默复用机制(Recipe search→express, Gene/Capsule 为 fallback;search→reuse→capture 循环)与各工具何时调用;不要向用户叙述例行预检、状态或空搜索。',
159
159
  inputSchema: { type: 'object', properties: {} },
160
160
  handler: async () => ({ guide: buildEvolverPrimer({ proxy: !!deps.proxy }) }),
161
161
  },
@@ -165,13 +165,14 @@ export function buildEvolverTools(deps) {
165
165
  // later observe, from this agent's transcript, which primed genes were used. NOT a hub search (that is
166
166
  // evolver_asset_search): this is the curated, already-approved local memory, ready to reuse quietly.
167
167
  name: 'evolver_recall',
168
- description: '当本机已审核通过的可复用经验 gene 可能有帮助时调用;返回信任+审核双闸后的本地 gene,并记录一条 value.inject。若传入 sessionId(= 本会话 transcript 文件名去掉 .jsonl 后缀),后续 auto-recall 能从该 transcript 观测哪些注入 gene 真正被用,为经 MCP 接入的 AI 闭合自学习环;不传则仅记录归因、无法关联到会话。命中后静默复用,并在结果明确后用 evolver_asset_reuse_result 回报。',
168
+ description: 'Fallback:当本机已审核通过的可复用经验 gene 可能有帮助时调用(不是 Hub Recipe 搜索)。联网默认先 evolver_recipe_search / evolver_recipe_express。返回信任+审核双闸后的本地 gene,并记录一条 value.inject。若传入 sessionId(= 本会话 transcript 文件名去掉 .jsonl 后缀),后续 auto-recall 能从该 transcript 观测哪些注入 gene 真正被用,为经 MCP 接入的 AI 闭合自学习环;不传则仅记录归因、无法关联到会话。命中后静默复用,并在结果明确后用 evolver_asset_reuse_result 回报。',
169
169
  inputSchema: { type: 'object', properties: { limit: { type: 'number' }, sessionId: { type: 'string' } } },
170
170
  handler: async (a) => {
171
171
  const limit = optionalNonNegativeNumberArg(a, 'limit', 'evolver_recall limit must be a non-negative number') ?? 5;
172
172
  const sessionId = typeof a['sessionId'] === 'string' && a['sessionId'].trim() ? a['sessionId'].trim() : undefined;
173
173
  const review = assetstore.reviewLedgerForStore(deps.store);
174
- const genes = await assetstore.listApprovedGenes(deps.store, review, limit);
174
+ const provenance = assetstore.provenanceStoreForStore(deps.store);
175
+ const genes = await assetstore.listApprovedGenes(deps.store, review, limit, provenance);
175
176
  const primed = genes.map((g) => {
176
177
  const r = g;
177
178
  const id = typeof r['id'] === 'string' ? r['id'] : String(r['asset_id']);
@@ -198,6 +199,68 @@ export function buildEvolverTools(deps) {
198
199
  },
199
200
  },
200
201
  ...(deps.proxy ? [{
202
+ name: 'evolver_recipe_search',
203
+ description: '默认第一步:通过本机 evolver-proxy 搜索 Hub 已发布 Recipe(有序 Gene/Capsule DNA)。命中后调用 evolver_recipe_express。无匹配时再 fallback 到 evolver_asset_search。旧客户端默认收到 Recipe 数组;设置 includePagination=true 可读取 nextCursor/hasMore。',
204
+ inputSchema: {
205
+ type: 'object',
206
+ properties: {
207
+ q: { type: 'string' },
208
+ query: { type: 'string' },
209
+ text: { type: 'string' },
210
+ limit: { type: 'number' },
211
+ cursor: { type: 'string' },
212
+ sort: { type: 'string' },
213
+ includePagination: {
214
+ type: 'boolean',
215
+ description: 'Set true to return the recipe page envelope with nextCursor/hasMore. The default array shape remains backwards compatible.',
216
+ },
217
+ },
218
+ },
219
+ handler: async (a) => {
220
+ const q = [a['q'], a['query'], a['text']].find((value) => typeof value === 'string' && value.trim().length > 0);
221
+ const includePagination = a['includePagination'] === true;
222
+ const receipt = record(await deps.proxy.searchRecipes({
223
+ ...(q ? { q } : {}),
224
+ ...(typeof a['limit'] === 'number' ? { limit: a['limit'] } : {}),
225
+ ...(typeof a['cursor'] === 'string' ? { cursor: a['cursor'] } : {}),
226
+ ...(typeof a['sort'] === 'string' ? { sort: a['sort'] } : {}),
227
+ }));
228
+ if (includePagination && (Array.isArray(receipt['recipes'])
229
+ || Array.isArray(receipt['results'])
230
+ || Array.isArray(receipt['items'])))
231
+ return receipt;
232
+ if (Array.isArray(receipt['recipes']))
233
+ return receipt['recipes'];
234
+ if (Array.isArray(receipt['results']))
235
+ return receipt['results'];
236
+ if (Array.isArray(receipt['items']))
237
+ return receipt['items'];
238
+ return receipt;
239
+ },
240
+ }, {
241
+ name: 'evolver_recipe_express',
242
+ description: '表达/执行一条 Recipe:只转发 Hub POST /a2a/recipe/{id}/express。Hub 按步骤展开 Gene 再 Capsule,从而产生全网 gene/capsule 调用。不要在本地解析 recipe JSON。',
243
+ inputSchema: {
244
+ type: 'object',
245
+ required: ['recipeId'],
246
+ properties: {
247
+ recipeId: { type: 'string' },
248
+ inputPayload: { type: 'object' },
249
+ },
250
+ },
251
+ handler: async (a) => {
252
+ const recipeId = str(a['recipeId']).trim();
253
+ if (!recipeId)
254
+ throw new Error('evolver_recipe_express requires recipeId');
255
+ const inputPayload = a['inputPayload'];
256
+ return deps.proxy.expressRecipe({
257
+ recipeId,
258
+ ...(inputPayload && typeof inputPayload === 'object' && !Array.isArray(inputPayload)
259
+ ? { inputPayload: inputPayload }
260
+ : {}),
261
+ });
262
+ },
263
+ }, {
201
264
  name: 'evolver_proxy_status',
202
265
  description: '检查本机 evolver-proxy 与 PHub 的连接状态. 需要 EVOLVER_PROXY_URL/EVOLVER_IPC_TOKEN.',
203
266
  inputSchema: { type: 'object', properties: {} },
@@ -206,8 +269,8 @@ export function buildEvolverTools(deps) {
206
269
  {
207
270
  name: 'evolver_asset_search',
208
271
  description: deps.proxy
209
- ? '通过本机 evolver-proxy 搜索 PHub 经验资产(Gene/Capsule/EvolutionEvent); AntiGene 是本地负经验资产, 会直接查本地库供人工 review.'
210
- : '搜索本地经验资产库(Gene/Capsule/EvolutionEvent/AntiGene). 支持 kind/信号/类目/gene 反查/文本.',
272
+ ? 'Fallback:当 evolver_recipe_search 无匹配 Recipe 时,通过本机 evolver-proxy 直搜 PHub 经验资产(Gene/Capsule/EvolutionEvent)AntiGene 是本地负经验资产, 会直接查本地库供人工 review. 真正复用应优先 evolver_recipe_express。'
273
+ : '搜索本地经验资产库(Gene/Capsule/EvolutionEvent/AntiGene). 支持 kind/信号/类目/gene 反查/文本. 联网 Recipe 搜索需要 evolver-proxy。',
211
274
  inputSchema: { type: 'object', properties: { kind: { type: 'string', enum: searchableKinds }, signalsAny: { type: 'array', items: { type: 'string' } }, category: { type: 'string' }, gene: { type: 'string' }, text: { type: 'string' }, limit: { type: 'number' } } },
212
275
  handler: async (a) => {
213
276
  if (deps.proxy && a['kind'] === 'AntiGene') {
@@ -274,7 +337,7 @@ export function buildEvolverTools(deps) {
274
337
  },
275
338
  {
276
339
  name: 'evolver_distill_conversation',
277
- description: '从当前 agent 对话中蒸馏可复用 Gene/Capsule. 需要具体 summary、strategy/evidence、artifacts、validation; core quality gate 会拒绝弱信号.',
340
+ description: '从当前对话蒸馏可复用能力. persist=true 只在结果可发布(经宿主验证)或为失败/无轨迹草稿时才落 Gene/Capsule; 携带调用方自报 success 轨迹而未经宿主验证时仅返回草稿不落库. 需要具体 summary、strategy/evidence、artifacts、validation; 质量闸门会将弱信号保留为草稿而不会发布. provider 若不具备 putBundle 能力,成对持久化会 fail-closed 并返回 bundle_persistence_unsupported. Hub 默认优先发布成 Recipe, 不再优先上 Skill Store. publish=true 时默认 compose_recipe, 可用 publish_recipe=false 关掉.',
278
341
  inputSchema: {
279
342
  type: 'object',
280
343
  required: ['summary'],
@@ -292,7 +355,8 @@ export function buildEvolverTools(deps) {
292
355
  validation: { type: 'array', items: { type: 'string' } },
293
356
  persist: { type: 'boolean' },
294
357
  publish: { type: 'boolean' },
295
- min_score: { type: 'integer', minimum: 1, maximum: 10 },
358
+ publish_recipe: { type: 'boolean', description: 'When publish=true, also compose and publish a Recipe. Defaults to true.' },
359
+ min_score: { type: 'integer', minimum: 5, maximum: 10 },
296
360
  },
297
361
  },
298
362
  handler: async (a) => {
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "@evomap/evolver-mcp",
3
- "version": "2.0.0-beta.2",
3
+ "version": "2.0.0-beta.22",
4
4
  "private": false,
5
5
  "type": "module",
6
+ "engines": {
7
+ "node": "^22.13.0 || >=23.4.0"
8
+ },
6
9
  "description": "Evolver MCP server (agent 工具发现入口)",
7
10
  "bin": {
8
11
  "evolver-mcp": "./dist/stdio.js"
@@ -17,12 +20,20 @@
17
20
  "./stdio": {
18
21
  "types": "./dist/stdio.d.ts",
19
22
  "default": "./dist/stdio.js"
23
+ },
24
+ "./product-bridge": {
25
+ "types": "./dist/productBridgeShim.d.ts",
26
+ "default": "./dist/productBridgeShim.js"
20
27
  }
21
28
  },
22
29
  "dependencies": {
23
- "@evomap/evolver-core": "2.0.0-beta.2",
30
+ "@evomap/evolver-core": "2.0.0-beta.22",
24
31
  "smol-toml": "^1.6.1"
25
32
  },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/EvoMap/evolver.git"
36
+ },
26
37
  "publishConfig": {
27
38
  "access": "public",
28
39
  "tag": "v2-beta"