clementine-agent 1.0.56 → 1.0.58

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.
@@ -1103,21 +1103,43 @@ Delegate data-heavy work (SEO, analytics, bulk API calls for 3+ entities) to sub
1103
1103
  Never spawn a sub-agent with vague instructions like "handle this brief" — tell it exactly what to read, what to change, and where to write the result.
1104
1104
  `);
1105
1105
  }
1106
- // Inject Claude Desktop integration awareness. Derived from the probed
1107
- // SDK tool inventory — whatever the current user has connected at the
1108
- // claude.ai level shows up here automatically, no per-install hardcoding.
1106
+ // Inject MCP server awareness. Derived from the probed SDK tool inventory.
1107
+ // Covers three namespaces:
1108
+ // - claude_ai_* remote OAuth connectors (Drive, Gmail, M365, Slack, etc.)
1109
+ // - Desktop Extensions + per-query stdio servers (imessage, figma,
1110
+ // hostinger, supabase, dataforseo, browsermcp, apify, kernel, etc.)
1111
+ // - plugin_* → Claude Code plugin tools
1112
+ // Without this, the agent only "knows" about claude_ai_* connectors and
1113
+ // denies capabilities it actually has (e.g. "no iMessage integration")
1114
+ // even though mcp__imessage__* tools are in allowedTools.
1109
1115
  try {
1110
1116
  const inv = _mcpBridge?.loadToolInventory();
1111
- const labels = new Set();
1117
+ const byServer = new Map();
1112
1118
  if (inv?.tools) {
1113
1119
  for (const t of inv.tools) {
1114
- const m = t.match(/^mcp__claude_ai_([^_]+(?:_[^_]+)*)__/);
1115
- if (m)
1116
- labels.add(m[1].replace(/_/g, ' '));
1120
+ const m = t.match(/^mcp__([^_]+(?:_[^_]+)*)__/);
1121
+ if (!m)
1122
+ continue;
1123
+ const server = m[1];
1124
+ // Skip clementine's own server — it's already documented in the
1125
+ // self-service section. Keep everything else.
1126
+ if (server === TOOLS_SERVER)
1127
+ continue;
1128
+ byServer.set(server, (byServer.get(server) ?? 0) + 1);
1117
1129
  }
1118
1130
  }
1119
- if (labels.size > 0) {
1120
- parts.push(`**Claude Desktop integrations connected for this user:** ${[...labels].sort().join(', ')}. Call \`mcp__claude_ai_<Integration>__<tool>\` directly; the tool names and schemas are in your SDK inventory.`);
1131
+ if (byServer.size > 0) {
1132
+ const lines = [...byServer.entries()]
1133
+ .sort(([a], [b]) => a.localeCompare(b))
1134
+ .map(([server, n]) => {
1135
+ // Humanize: claude_ai_Google_Drive → "Google Drive (claude.ai)"
1136
+ if (server.startsWith('claude_ai_')) {
1137
+ return `- ${server.slice('claude_ai_'.length).replace(/_/g, ' ')} (${n} tools) — prefix \`mcp__${server}__\``;
1138
+ }
1139
+ return `- ${server} (${n} tools) — prefix \`mcp__${server}__\``;
1140
+ });
1141
+ parts.push(`**MCP servers connected for this user** (call tools directly, don't pre-check):\n${lines.join('\n')}\n\n` +
1142
+ `The exact tool names and schemas are in your SDK function inventory — just call the tool that matches the user's request.`);
1121
1143
  }
1122
1144
  }
1123
1145
  catch { /* non-fatal */ }
@@ -426,6 +426,13 @@ export async function probeAvailableTools(force = false) {
426
426
  }
427
427
  try {
428
428
  const { query } = await import('@anthropic-ai/claude-agent-sdk');
429
+ // Pass the same mcpServers the real query uses so the probe sees
430
+ // every tool a real query would see — Desktop Extensions (iMessage,
431
+ // figma), user-managed stdio servers (hostinger, supabase, etc.),
432
+ // anything wired through mcp-bridge. Without this, init.tools only
433
+ // reflects Claude Code's global config — Extensions are invisible
434
+ // and the SDK schema-rejects calls to their tools at runtime.
435
+ const externalMcpServers = getMcpServersForAgent();
429
436
  const stream = query({
430
437
  prompt: 'ok',
431
438
  options: {
@@ -433,6 +440,7 @@ export async function probeAvailableTools(force = false) {
433
440
  model: 'claude-haiku-4-5',
434
441
  permissionMode: 'bypassPermissions',
435
442
  allowDangerouslySkipPermissions: true,
443
+ mcpServers: externalMcpServers,
436
444
  },
437
445
  });
438
446
  let tools = [];
package/dist/index.js CHANGED
@@ -550,7 +550,11 @@ async function asyncMain() {
550
550
  // without per-user hardcoding. Cached 1h. On fresh probe, log a short
551
551
  // summary so the owner can verify which connectors were detected
552
552
  // without having to ask the assistant.
553
- probeAvailableTools().then(inv => {
553
+ // force=true on startup: the 1h cache from a prior daemon version may
554
+ // have been taken with a stale probe config (e.g. before we started
555
+ // passing mcpServers to the probe). Re-probe fresh so Extensions and
556
+ // per-query MCP servers are discovered and whitelisted immediately.
557
+ probeAvailableTools(true).then(inv => {
554
558
  const integrations = new Set();
555
559
  for (const t of inv.tools) {
556
560
  const m = t.match(/^mcp__claude_ai_([^_]+(?:_[^_]+)*)__/);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.0.56",
3
+ "version": "1.0.58",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",