@myvillage/cli 1.75.0 → 1.76.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myvillage/cli",
3
- "version": "1.75.0",
3
+ "version": "1.76.0",
4
4
  "description": "MyVillageOS CLI for community developers",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,9 +16,39 @@ import { tool } from 'ai';
16
16
  import { z } from 'zod';
17
17
  import { appendRows, datasetExists, readManifest, ingestAsset } from '../utils/dataset-workspace.js';
18
18
  import { DATASET_APPEND_DESCRIPTION, MODEL_PREDICT_DESCRIPTION } from './builtin-tools-registry.js';
19
+ import { readToolsYaml } from '../utils/local-agent.js';
19
20
 
20
21
  export { BUILTIN_TOOL_DEFS } from './builtin-tools-registry.js';
21
22
 
23
+ /**
24
+ * Gate built-ins by the SAME allowlist as the MyVillageOS platform server
25
+ * (`allowed_tools` on whichever tools.yaml server points at a myvillageproject.ai
26
+ * URL). This lets built-ins be scoped from one place — the myvillage tool card —
27
+ * rather than a separate mechanism. Semantics match `applyToolAllowlist`:
28
+ * - no allowlist on that server → all built-ins load (back-compatible)
29
+ * - allowlist present → a built-in loads only if explicitly listed
30
+ */
31
+ function applyBuiltinAllowlist(builtins, agentName) {
32
+ let allowed;
33
+ try {
34
+ const servers = readToolsYaml(agentName)?.servers ?? {};
35
+ const platform = Object.values(servers).find(
36
+ (s) =>
37
+ s && typeof s === 'object' && typeof s.url === 'string' &&
38
+ /(^|\.)myvillageproject\.ai/i.test(new URL(s.url).hostname),
39
+ );
40
+ allowed = platform?.allowed_tools;
41
+ } catch {
42
+ allowed = undefined;
43
+ }
44
+ if (!Array.isArray(allowed)) return builtins;
45
+ const filtered = {};
46
+ for (const [name, t] of Object.entries(builtins)) {
47
+ if (allowed.includes(name)) filtered[name] = t;
48
+ }
49
+ return filtered;
50
+ }
51
+
22
52
  /**
23
53
  * Build the native built-in tools for an agent.
24
54
  * @param {string} agentName
@@ -26,7 +56,7 @@ export { BUILTIN_TOOL_DEFS } from './builtin-tools-registry.js';
26
56
  * @returns {Record<string, object>} AI SDK tools keyed by tool name
27
57
  */
28
58
  export function getBuiltinTools(agentName, config) {
29
- return {
59
+ const all = {
30
60
  dataset_append: tool({
31
61
  description: DATASET_APPEND_DESCRIPTION,
32
62
  inputSchema: z.object({
@@ -122,4 +152,5 @@ export function getBuiltinTools(agentName, config) {
122
152
  },
123
153
  }),
124
154
  };
155
+ return applyBuiltinAllowlist(all, agentName);
125
156
  }
@@ -5,9 +5,15 @@
5
5
  import { readFileSync } from 'fs';
6
6
  import { join } from 'path';
7
7
  import { parse as parseYaml } from 'yaml';
8
+ import { BUILTIN_TOOL_DEFS } from './builtin-tools-registry.js';
8
9
 
9
10
  const activeClients = [];
10
11
 
12
+ // Built-in tools share the MyVillageOS server's `allowed_tools` list (they're
13
+ // scoped from the same card), so their names legitimately appear there even
14
+ // though they aren't exposed by any MCP server — don't flag them as "unknown".
15
+ const BUILTIN_TOOL_NAMES = new Set(BUILTIN_TOOL_DEFS.map((d) => d.name));
16
+
11
17
  // ── Public API ──────────────────────────────────────────
12
18
 
13
19
  export async function getMCPTools(agentDir, agentConfig) {
@@ -201,7 +207,7 @@ export function applyToolAllowlist(tools, allowed, serverName) {
201
207
  for (const [name, tool] of Object.entries(tools)) {
202
208
  if (allow.has(name)) filtered[name] = tool;
203
209
  }
204
- const unknown = allowed.filter((n) => !(n in tools));
210
+ const unknown = allowed.filter((n) => !(n in tools) && !BUILTIN_TOOL_NAMES.has(n));
205
211
  if (unknown.length > 0) {
206
212
  console.error(
207
213
  `[mcp-client] ${serverName}: allowed_tools lists ${unknown.length} tool(s) this server doesn't expose: ${unknown.join(', ')}`,