@finchagentic/mcp 4.0.0 → 4.1.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 noelclaw
3
+ Copyright (c) 2026 finch
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,159 +1,65 @@
1
1
  <div align="center">
2
2
 
3
- <!-- Hero Banner SVG (self-contained, no external image) -->
4
- <img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDEyMDAgMzAwIj4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0iYmciIHgxPSIwIiB5MT0iMCIgeDI9IjAiIHkyPSIxIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojMGEwYTBhO3N0b3Atb3BhY2l0eToxIi8+CiAgICAgIDxzdG9wIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzFhMWEyNTtzdG9wLW9wYWNpdHk6MSIvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxyYWRpYWxHcmFkaWVudCBpZD0iZ2xvdyIgY3g9IjUwJSIgY3k9IjUwJSIgcj0iNTAlIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojMjU2M0VCO3N0b3Atb3BhY2l0eTowLjMiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMjU2M0VCO3N0b3Atb3BhY2l0eTowIi8+CiAgICA8L3JhZGlhbEdyYWRpZW50PgogIDwvZGVmcz4KICA8cmVjdCB3aWR0aD0iMTIwMCIgaGVpZ2h0PSIzMDAiIGZpbGw9InVybCgjYmcpIi8+CiAgPGNpcmNsZSBjeD0iNjAwIiBjeT0iMTUwIiByPSIyMDAiIGZpbGw9InVybCgjZ2xvdykiLz4KICA8dGV4dCB4PSI2MDAiIHk9IjEyMCIgZm9udC1mYW1pbHk9InN5c3RlbS11aSwgc2Fucy1zZXJpZiIgZm9udC1zaXplPSI1NiIgZm9udC13ZWlnaHQ9IjgwMCIgZmlsbD0iI2YwZjZmYyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgbGV0dGVyLXNwYWNpbmc9Ii0wLjAzZW0iPk5vZWxDbGF3PC90ZXh0PgogIDx0ZXh0IHg9IjYwMCIgeT0iMTY1IiBmb250LWZhbWlseT0ic3lzdGVtLXVpLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjIwIiBmb250LXdlaWdodD0iNDAwIiBmaWxsPSIjOTNjNWZkIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5UaGUgcnVudGltZSBsYXllciBmb3IgQWdlbnRpYyBBSTwvdGV4dD4KICA8dGV4dCB4PSI2MDAiIHk9IjE5NSIgZm9udC1mYW1pbHk9InN5c3RlbS11aSwgc2Fucy1zZXJpZiIgZm9udC1zaXplPSIxNCIgZm9udC13ZWlnaHQ9IjQwMCIgZmlsbD0iIzY0NzQ4YiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+MTIxIHRvb2xzIOKAlCBwZXJzaXN0ZW50IG1lbW9yeSDigJQgYWdlbnRzIOKAlCB3b3JrZmxvd3Mg4oCUIERlRmkgb24gQmFzZTwvdGV4dD4KPC9zdmc+" alt="Finch" width="100%">
3
+ # Finch
5
4
 
6
- </div>
7
-
8
- ---
5
+ **The runtime layer for Agentic AI.**
9
6
 
10
- <div align="center">
11
-
12
- # The runtime layer for Agentic AI.
7
+ Persistent memory, autonomous agents, and workflows that survive every session.
13
8
 
14
- **Your AI remembers, keeps working, and survives every session.**
9
+ [Docs](https://docs.finch.com) · [App](https://app.finchagentic.com) · [npm](https://www.npmjs.com/package/@finchagentic/mcp) · [GitHub](https://github.com/finchagentic/mcp) · [X](https://x.com/finchagentic)
15
10
 
16
11
  </div>
17
12
 
18
13
  ---
19
14
 
20
- > Most AI assistants disappear when the conversation ends. Finch gives them persistent state — memory that accumulates, agents that keep running, vaults that version knowledge, and workflows that continue after you close the chat.
21
-
22
- ## Table of Contents
23
-
24
- - [What's New](#whats-new)
25
- - [Three Pillars](#three-pillars)
26
- - [Install](#install)
27
- - [In Practice](#in-practice)
28
- - [Configuration](#configuration)
29
- - [Security](#security-boundaries)
30
- - [Comparison](#why-this-is-different)
31
- - [Troubleshooting](#troubleshooting)
32
- - [Links](#links)
33
-
34
- ---
35
-
36
- ## What's New
37
-
38
- | Feature | Description |
39
- |---------|-------------|
40
- | **🔒 Fully local** | Run the whole runtime on your own machine — **vault + memory on your own disk** (versioned, encrypted, no account), wallet keys local, your LLM does the thinking. Nothing phones home. `finch setup` to enable, `finch vault` to inspect. → [Run it fully local](#run-it-fully-local) |
41
- | **Local Memory** | Run memory tools on a free, self-hosted [supermemory](https://github.com/supermemoryai/supermemory) server on your own machine — zero cost, private, no Finch account needed. `finch setup` to enable. |
42
- | **OpenAI BYOK** | OpenAI joins Bankr/Anthropic/Grok as a direct LLM provider. `OPENAI_BASE_URL` also lets you point at any self-hosted OpenAI-compatible gateway (LiteLLM, vLLM, Ollama, OpenRouter, your own VPS). |
43
- | **`finch setup`** | New guided CLI wizard — pick an LLM provider and/or enable local memory in one flow. |
44
- | **Finch Terminal** | Tool calling from chat — spawn agents, save to vault, search memory, estimate + execute swaps, create automations. All from a single prompt. |
45
- | **`execute_swap`** | Execute token swaps on Base mainnet from Finch Terminal. Enforces estimate → preview → confirm → execute flow. Routes via 0x Permit2. |
46
- | **7 Agents** | Noel (AI OS), CoinGecko (market data), Sage (research), Forge (code), Quill (creative), Spectre (trading), Atlas (general) |
47
- | **Multi-Provider Chat** | Bankr → Anthropic → OpenAI → Grok → Finch proxy fallback |
48
- | **ConnectMcpModal** | Onboarding flow: auto-generate API key + copy install command from webapp |
49
- | **Security Hardened** | 8 security boundaries, wallet decrypt-failure protection, 4 other vulnerability fixes (auth, OTP, private key) |
50
- | **Knowledge Graph** | Vault entries link into a typed graph (`references`, `derived_from`, `supersedes`, `related`, `continues`) — auto-built from `[[wikilinks]]` + `#tags`, with backlinks. Data layer only for now; visual graph is planned. |
51
- | **Ecosystem** | CI/CD, CodeQL, Dependabot, Husky, Dockerfile, coverage reporting, semantic release, TypeDoc |
52
-
53
- ---
15
+ Most AI assistants disappear when the conversation ends. **Finch** gives them lasting state — memory that accumulates, agents that keep running, vaults that version knowledge, and workflows that continue after you close the chat.
54
16
 
55
- ## Three Pillars
17
+ ## Why Finch
56
18
 
57
- <table>
58
- <tr>
59
- <td width="33%" valign="top">
60
-
61
- ### Memory
62
- Semantic, versioned, deduplicated.
63
-
64
- Your AI remembers what you told it last week, last month, in a different session — and ranks recent context above stale notes via 90-day half-life decay. Run `finch setup` to switch to a free, self-hosted local backend instead of the Finch-hosted proxy.
65
-
66
- ```bash
67
- remember: I prefer conservative DeFi strategies, max 5% APY
68
- → ✓ saved to memory
69
- auto-loaded in future sessions
70
- ```
71
-
72
- </td>
73
- <td width="33%" valign="top">
74
-
75
- ### Agents
76
- Named, persistent, identity-bound.
77
-
78
- Spawn an agent with a goal, recall it weeks later, audit every state change. Each agent can hold its own Base wallet address.
79
-
80
- ```bash
81
- spawn an agent called market-researcher
82
- goal: track Base chain protocols weekly
83
- → 🤖 agent spawned
84
- recall anytime with agent_recall
85
- ```
86
-
87
- </td>
88
- <td width="33%" valign="top">
89
-
90
- ### Workflows
91
- Packets, automations, monitors, deep research.
92
-
93
- Anything that runs on a schedule or continues after the chat ends.
94
-
95
- ```bash
96
- set up a daily monitor for
97
- AI agent infrastructure news
98
- → ✓ monitor created
99
- runs daily 08:00 UTC
100
- findings auto-saved to vault
101
- ```
102
-
103
- </td>
104
- </tr>
105
- </table>
106
-
107
- ---
19
+ | | Without Finch | With Finch |
20
+ |--|---------------|------------|
21
+ | **Memory** | Resets every session | Full-text searchable + versioned vault, decays stale notes |
22
+ | **Agents** | One-shot tool calls | Named agents with state and audit history |
23
+ | **Workflows** | Manual chaining | Automations, monitors, packets, deep research |
24
+ | **Local** | Cloud-only | Vault + memory can run fully on your machine |
108
25
 
109
26
  ## Install
110
27
 
111
- ### One-command auto-install (any MCP client)
28
+ Always pin the version. Never use `@latest`.
29
+
112
30
  ```bash
113
- npx -y -p @finchagentic/mcp@4.0.0 finch install
31
+ # One-command installer (detects common MCP clients)
32
+ npx -y -p @finchagentic/mcp@4.1.0 finch install
114
33
  ```
115
- > Detects Claude Desktop, Cursor, Windsurf, VS Code, and Zed, and configures each automatically. **Claude Code** is configured with the dedicated `claude mcp add` command below (its config lives outside the desktop-app path this scan checks).
116
34
 
117
35
  ### Claude Code
36
+
118
37
  ```bash
119
- claude mcp add finch -s user -- npx -y -p @finchagentic/mcp@4.0.0 finch-mcp
38
+ claude mcp add finch -s user -- npx -y -p @finchagentic/mcp@4.1.0 finch-mcp
120
39
  ```
121
40
 
122
41
  ### Cursor / Windsurf / Claude Desktop
42
+
123
43
  ```json
124
44
  {
125
45
  "mcpServers": {
126
46
  "finch": {
127
47
  "command": "npx",
128
- "args": ["-y", "-p", "@finchagentic/mcp@4.0.0", "finch-mcp"]
48
+ "args": ["-y", "-p", "@finchagentic/mcp@4.1.0", "finch-mcp"]
129
49
  }
130
50
  }
131
51
  }
132
52
  ```
133
53
 
134
54
  ### VS Code
135
- `mcp.json` uses the `servers` key (not `mcpServers`), and each entry needs `"type": "stdio"`:
55
+
136
56
  ```json
137
57
  {
138
58
  "servers": {
139
59
  "finch": {
140
60
  "type": "stdio",
141
61
  "command": "npx",
142
- "args": ["-y", "-p", "@finchagentic/mcp@4.0.0", "finch-mcp"]
143
- }
144
- }
145
- }
146
- ```
147
-
148
- ### Zed
149
- In `settings.json` under `context_servers` (each entry needs `"source": "custom"`):
150
- ```json
151
- {
152
- "context_servers": {
153
- "finch": {
154
- "source": "custom",
155
- "command": "npx",
156
- "args": ["-y", "-p", "@finchagentic/mcp@4.0.0", "finch-mcp"]
62
+ "args": ["-y", "-p", "@finchagentic/mcp@4.1.0", "finch-mcp"]
157
63
  }
158
64
  }
159
65
  }
@@ -168,178 +74,119 @@ In `settings.json` under `context_servers` (each entry needs `"source": "custom"
168
74
  | Claude Desktop (Windows) | `%APPDATA%\Claude\claude_desktop_config.json` |
169
75
  | Cursor | `.cursor/mcp.json` |
170
76
  | Windsurf | `~/.codeium/windsurf/mcp_config.json` |
171
- | Zed | `.config/zed/settings.json` |
172
77
  | VS Code | `.vscode/mcp.json` |
78
+ | Zed | `.config/zed/settings.json` |
173
79
 
174
80
  </details>
175
81
 
176
- > No LLM API key required — not to start, and not for any tool. Tools load on first use.
177
-
178
- > **Always pin the version** (`@finchagentic/mcp@4.0.0`, never `@latest`) — this MCP has wallet, credential, and backend persistence capabilities. See [Security Boundaries](#security-boundaries).
179
-
180
- ---
181
-
182
- ## Run it fully local
82
+ No LLM API key is required to start 116 of 121 tools are plain reads/writes/on-chain calls that your MCP client's own model already drives; only 5 (`ask_finch`, `deep_research`, and scheduled agent learning) do their own multi-step reasoning server-side and need a key (see [Configuration](#configuration)). Tools load on first use.
183
83
 
184
- Finch is the runtime; **your LLM is the brain, and your data stays yours.** You can run the whole thing on your own machine — no Finch account, no cloud, nothing leaving your laptop.
84
+ ## Quick start
185
85
 
186
- **Turn it on:**
187
86
  ```bash
188
- npx -y -p @finchagentic/mcp@4.0.0 finch setup
189
- # → answer "y" to "Enable local vault" (and, optionally, local memory)
87
+ finch doctor # health check
88
+ finch setup # local vault / memory / providers
89
+ finch vault # inspect local vault
190
90
  ```
191
91
 
192
- **What runs local:**
92
+ Try in your MCP client:
193
93
 
194
- | Piece | Where it lives | Notes |
195
- |-------|----------------|-------|
196
- | **Vault** | `~/.finch/vault/` | Versioned artifacts + knowledge graph. Credentials AES-256-GCM encrypted. Plain files copy, `git`, or sync them anywhere. |
197
- | **Memory** | self-hosted [supermemory](https://github.com/supermemoryai/supermemory) | Semantic recall on your machine. Optional; without it, vault search falls back to local full-text. |
198
- | **Wallet** | `~/.finch/wallet.json` | Keys never leave your machine. |
199
- | **The brain** | your MCP client's model | Claude Code, Cursor, etc. **No BYOK LLM key needed** — the model is already yours. |
200
- | **Public-data tools** | direct API calls | Market, scanner, SEC, GitHub, Robinhood Chain reads — keyless from day one. |
201
-
202
- **Your data is a plain folder.** Back it up with `cp`, version it with `git`, sync it however you like — it never syncs anywhere on its own.
203
-
204
- ```bash
205
- finch vault # where it is, what's in it, how to back it up
206
- finch doctor # confirm "Local vault: on" and everything else
94
+ ```
95
+ remember: I prefer conservative DeFi strategies, max 5% risk
96
+ spawn an agent called research-bot to track AI agent news weekly
97
+ save this thesis to vault
207
98
  ```
208
99
 
209
- **What still needs an account** (inherently server-side, can't be local): scheduled/cron agents, cross-device sync, and the community marketplace. Everything else works with zero sign-in.
210
-
211
- ---
212
-
213
- ## In Practice
100
+ ## What you get
214
101
 
215
- ```
216
- > what have you found so far on AI agent infrastructure?
217
- → Pulls from vault: 3 reports across 7 days · summarizes key themes
102
+ **121 tools** across four pillars:
218
103
 
219
- > give me a bull vs bear thesis on ETH, save it
220
- → Full analysis written + auto-saved to vault as v1
104
+ | Pillar | What it does |
105
+ |--------|----------------|
106
+ | **Memory** | Full-text searchable memory + versioned vault + chronicle |
107
+ | **Agents** | Spawn, recall, update, schedule named agents |
108
+ | **Workflows** | Automations, monitors, packets, deep research |
109
+ | **Execution** | Base DeFi, Robinhood Chain, market data, web, GitHub |
221
110
 
222
- > swap 50 USDC to ETH
223
- → [estimate_swap] Quote: 0.027 ETH · slippage 0.5% · gas ~$0.03
224
- → Confirm swap? (yes/no)
225
- → [execute_swap confirmed=true]
226
- → ✅ Swap executed · tx 0xabc... · view on Basescan
111
+ Default palette is `core` (lighter context). Full set:
227
112
 
228
- > spawn an agent to track Base DeFi weekly
229
- 🤖 Agent 'base-tracker' created · runs every Monday 09:00 UTC
113
+ ```json
114
+ "env": { "FINCH_TOOLS": "all" }
230
115
  ```
231
116
 
232
- ---
117
+ ## Fully local
233
118
 
234
- ## 121 Tools Across the Runtime
119
+ Finch is the runtime. **Your LLM is the brain. Your data stays yours.**
235
120
 
236
- | Pillar | Categories | Count |
237
- |--------|-----------|:-----:|
238
- | Memory | Memory · Vault · Chronicle | 29 |
239
- | Agents | Agents · Hire | 12 |
240
- | Workflows | Automation · Monitors · Packets · Deep Research · Research Compare/Chain · OS | 19 |
241
- | Execution | Base DeFi (base_mcp_*) · Robinhood Chain (rh_*) · Stocks (SEC) · Market · Scanner · Web · GitHub · Code Audit · Wallet | 61 |
121
+ ```bash
122
+ npx -y -p @finchagentic/mcp@4.1.0 finch setup
123
+ # enable local vault (and optional local memory)
124
+ ```
242
125
 
243
- > Run `finch doctor` for a 5-second health check showing exactly what's wired and what isn't.
126
+ | Piece | Location |
127
+ |-------|----------|
128
+ | Vault | `~/.finch/vault/` |
129
+ | Wallet | `~/.finch/wallet.json` |
130
+ | Config | `~/.finch/config.json` |
131
+ | Brain | your MCP client’s model |
244
132
 
245
- ---
133
+ Scheduled/cloud features still need an account. Core memory, vault, and public-data tools work offline of Finch cloud.
246
134
 
247
135
  ## Configuration
248
136
 
249
- <details>
250
- <summary>Environment Variables (click to expand)</summary>
251
-
252
- **No LLM key is required for any tool.** Tools reach the network, read chains, hold state and execute
253
- transactions, then hand the result back to *your* client's model to reason over. None of them run inference of
254
- their own, so none of them can be broken by a missing key.
255
-
256
- A key makes Finch a *host* rather than a set of hands. That is only three things:
257
-
258
- - `finch run` the CLI agent loop, which has no client model to borrow
259
- - **scheduled / cron agents** they wake with no session attached
260
- - `deep_research mode:"report"` — opt-in server-written prose; the default `mode:"sources"` is keyless
137
+ | Variable | Purpose |
138
+ |----------|---------|
139
+ | `FINCH_SESSION_TOKEN` | Signed-in session (vault/memory/agents against your account) |
140
+ | `FINCH_API_KEY` | API key (`finch_sk_…`) |
141
+ | `FINCH_TOOLS` | `core` (default) · `all` · or palettes like `memory,defi` |
142
+ | `FINCH_PROVIDER` | Force `bankr` · `anthropic` · `openai` · `grok` |
143
+ | `FINCH_MODEL` | Model override for host-side loops |
144
+ | `BANKR_API_KEY` / `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `GROK_API_KEY` | Required for `ask_finch`, `deep_research`'s synthesis stages, and scheduled-agent learning extraction — these do their own multi-step reasoning server-side and there is no free hosted fallback (BYOK only, one key is enough) |
145
+ | `FIRECRAWL_API_KEY` | Better crawl quality (optional) |
146
+ | `GITHUB_TOKEN` | For `github_search_code` |
147
+ | `ALCHEMY_API_KEY` | Faster Base RPC (optional) |
261
148
 
262
- | Variable | Purpose | When you need it |
263
- |----------|---------|------------------|
264
- | `FINCH_SESSION_TOKEN` | Session token from [app.finchagentic.com](https://app.finchagentic.com) | Recommended — vault, memory and agent tools persist against your account |
265
- | `BANKR_API_KEY` | Use Bankr as your LLM gateway | Only to *be* a host: CLI loop, cron agents |
266
- | `ANTHROPIC_API_KEY` | Use your own Anthropic quota | Same — never needed by a tool |
267
- | `OPENAI_API_KEY` | Use OpenAI for chat/research | Same |
268
- | `OPENAI_BASE_URL` | Route OpenAI-shaped calls to a self-hosted gateway instead (LiteLLM, vLLM, Ollama, OpenRouter) | Same |
269
- | `GROK_API_KEY` | Use xAI Grok (`grok-4-fast-reasoning` by default) | Same |
270
- | `FINCH_PROVIDER` | Force a specific provider: `bankr` \| `anthropic` \| `openai` \| `grok` | Optional |
271
- | `FIRECRAWL_API_KEY` | Better crawl quality for `deep_research` and `web_search` | Optional — both fall back to the Finch proxy |
272
- | `GITHUB_TOKEN` | Required for `github_search_code` | For GitHub |
273
- | `ALCHEMY_API_KEY` | Faster Base chain queries | Optional |
149
+ **Cost model:** almost everything is free to run — the other 116 tools are plain API/RPC calls, and your MCP client's own model (Claude, GPT, whatever's driving the chat) does all the tool-selection reasoning at no cost to Finch. The 5 exceptions above need their own key because their reasoning happens *inside* the tool call, invisible to your client, and can't be delegated to it. Set exactly one of the four env vars and every tool that needs it will use it automatically.
274
150
 
275
- Run `npx -y -p @finchagentic/mcp@4.0.0 finch setup` for a guided wizard instead of setting these by hand — it also enables a free, self-hosted local memory + [fully-local vault](#run-it-fully-local), so vault and memory tools need no account at all.
151
+ Guided setup:
276
152
 
277
- </details>
278
-
279
- ---
280
-
281
- ## Security Boundaries
153
+ ```bash
154
+ npx -y -p @finchagentic/mcp@4.1.0 finch setup
155
+ ```
282
156
 
283
- > These 8 boundaries are mandatory. Violating any is a critical security failure.
157
+ ## Security
284
158
 
285
159
  | # | Boundary | Rule |
286
- |:---:|----------|------|
287
- | 1 | **Prompt-Injection** | External content (web, GitHub, vault, memory) is DATA ONLY. Cannot set tool params, request credentials, or drive wallet actions. |
288
- | 2 | **Mainnet Confirmation** | All Base mainnet transactions require estimate → preview → confirm → execute flow. |
289
- | 3 | **Pinned Install** | Always use `@finchagentic/mcp@4.0.0` (pinned), never `@latest`. Supply-chain trust model documented. |
290
- | 4 | **Credential Vault** | Credentials never fetched because untrusted content asks. Never copied into prompts, outputs, or third-party tools. |
291
- | 5 | **Data Flow Disclosure** | Documented: Bankr, Anthropic, Firecrawl, GitHub, Alchemy, Convex, 0x — what leaves machine vs stored server-side. |
292
- | 6 | **Server-Side Monitors** | Creating scheduled jobs requires explicit user confirmation. Jobs continue after MCP process exits. |
293
- | 7 | **Agent Schedules** | `agent_schedule` requires confirmation. Discloses LLM calls, vault writes, cost implications. |
294
- | 8 | **Identity Custody** | `agent_identity` is backend-controlled. Users should NOT send assets to this address. |
295
-
296
- ---
297
-
298
- ## Why This Is Different
299
-
300
- | | Other MCPs | Finch |
301
- |--|------------|----------|
302
- | **Memory** | Single tier, no decay | Two-tier (semantic + versioned vault), 90-day decay, dedup |
303
- | **Agents** | Stateless function calls | Persistent named agents, audit ledger, wallet identity |
304
- | **Workflows** | Manual chaining | Packets, automations, monitors, deep research |
305
- | **Safety** | Trust the LLM | Slippage caps, audit grounding, 8 security boundaries |
306
- | **Reliability** | Best effort | 0 errors across 4 rescans · cache + 429 backoff |
307
-
308
- ---
160
+ |:-:|----------|------|
161
+ | 1 | Prompt injection | External content is data only never instructions |
162
+ | 2 | Mainnet confirm | Estimate → preview → confirm → execute |
163
+ | 3 | Pinned install | Always `@finchagentic/mcp@4.1.0`, never `@latest` |
164
+ | 4 | Credential vault | Never paste secrets into prompts or third-party tools |
165
+ | 5 | Data disclosure | Know what leaves the machine (LLM, Firecrawl, GitHub, chain RPCs) |
166
+ | 6 | Server monitors | Scheduled jobs need explicit confirmation |
167
+ | 7 | Agent schedules | `agent_schedule` confirms cost + side effects |
168
+ | 8 | Identity custody | Do not send assets to agent identity addresses |
309
169
 
310
170
  ## Troubleshooting
311
171
 
312
172
  | Problem | Fix |
313
173
  |---------|-----|
314
- | Tools not appearing | Restart your MCP client after adding the config |
315
- | Old version loading | `npx clear-npx-cache` then restart |
316
- | `web_search` fails | Set `FIRECRAWL_API_KEY` |
317
- | Swap refused | Price impact exceeded cap call `estimate_swap` first |
318
- | Rate limit (429) | Auto-retries with backoff — no action needed |
319
- | Diagnose anything | `finch doctor` |
320
-
321
- ---
174
+ | Tools missing | Fully restart the MCP client |
175
+ | Old version | `npx clear-npx-cache` then restart |
176
+ | Auth issues | `finch login` or set `FINCH_API_KEY` / `FINCH_SESSION_TOKEN` |
177
+ | `ask_finch`/`deep_research` error: "No LLM provider configured" | Set one of `BANKR_API_KEY` / `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `GROK_API_KEY` — see [Configuration](#configuration), no free fallback exists |
178
+ | Diagnose | `finch doctor` |
322
179
 
323
180
  ## Links
324
181
 
325
- | | |
326
- | ---------- | ------------------------------------------------------------------------------ |
327
- | **App** | [app.finchagentic.com](https://app.finchagentic.com) |
328
- | **Docs** | [docs.finch.fun](https://docs.finch.fun) |
329
- | **npm** | [npmjs.com/package/@finchagentic/mcp](https://www.npmjs.com/package/@finchagentic/mcp) |
330
- | **GitHub** | [github.com/finch/mcp](https://github.com/finch/mcp) |
331
- | **X** | [@finch](https://x.com/finch) |
182
+ | | |
183
+ |--|--|
184
+ | **Docs** | [docs.finch.com](https://docs.finch.com) |
185
+ | **App** | [app.finchagentic.com](https://app.finchagentic.com) |
186
+ | **npm** | [@finchagentic/mcp](https://www.npmjs.com/package/@finchagentic/mcp) |
187
+ | **GitHub** | [github.com/finchagentic/mcp](https://github.com/finchagentic/mcp) |
188
+ | **X** | [@finchagentic](https://x.com/finchagentic) |
332
189
 
333
190
  ---
334
191
 
335
- <div align="center">
336
-
337
- ### Star History
338
-
339
- [![Star History Chart](https://api.star-history.com/svg?repos=finch/mcp&type=Date)](https://star-history.com/#finch/mcp&Date)
340
-
341
- ---
342
-
343
- **MIT License** · Built with by the Finch team
344
-
345
- </div>
192
+ MIT License · Finch
@@ -15,15 +15,32 @@ const SYSTEM_PROMPT = [
15
15
  "- For ALL Base chain operations, you MUST use the base_mcp_* family: base_mcp_swap (NOT swap_tokens), base_mcp_send (NOT send_token), base_mcp_balance (NOT get_portfolio), base_mcp_estimate, base_mcp_resolve, base_mcp_lend, base_mcp_status. This is non-negotiable - Base operations go through the Base MCP skill, period.",
16
16
  "- For Robinhood Chain tokenized stocks (chainId 4663, NVDA/AAPL/etc on Uniswap V4), you MUST use rh_mcp_*: rh_mcp_status, rh_mcp_list_stocks, rh_mcp_balance, rh_mcp_estimate, rh_mcp_swap. Never use base_mcp_* or 0x for RH stocks. rh_mcp_swap requires confirm:true. Explorer = robinhoodchain.blockscout.com. This is NOT Robinhood Agentic brokerage (agent.robinhood.com).",
17
17
  "- Do NOT claim an address belongs to the user (e.g. 'your own address') unless you have verified ownership. Resolving a basename returns whoever owns that name - usually NOT the caller.",
18
+ "- The Finch wallet is the SAME address on both Base and Robinhood Chain, but they are separate ledgers - a balance on one tells you nothing about the other. If the user asks a chain-unspecified question ('what's my balance', 'do I have any funds') call BOTH base_mcp_balance AND rh_mcp_balance before answering. Never report only one chain's result as 'your balance' or 'your wallet is empty' - say which chain(s) you checked, and give both figures.",
19
+ "- Swap/send requests are only chain-unambiguous when the token itself pins the chain (a RH catalog stock like NVDA/AAPL, or a token you already know only exists on one side). A bare request like 'swap 0.001 ETH to a stablecoin' with no chain named is NOT unambiguous just because you picked one - ETH and 'stablecoin' both exist on Base (USDC/USDT/DAI) and Robinhood Chain (USDG). Before estimating or executing an ambiguous swap, call both base_mcp_balance and rh_mcp_balance first: if only one chain actually holds enough of the source token, use that chain and say which one and why; if neither holds enough, say so plainly instead of quoting a swap the wallet can't cover; if both hold enough, ask the user which chain before proceeding.",
20
+ "- There is NO send/transfer tool for Robinhood Chain - base_mcp_send only moves assets on Base mainnet. If the user asks to send/transfer USDG or any RH catalog stock (NVDA, AAPL, etc.), do NOT call base_mcp_send with that token name hoping it resolves - it will either error or, worse, silently match an unrelated Base token with the same symbol. Tell the user directly that on-chain sends are not yet supported on Robinhood Chain.",
21
+ "- Never state a balance, price, quote, token address, or transaction result from memory or inference - every number in your answer must trace to a tool call you made THIS turn. If you are not sure which chain, token, or address a term refers to, ask or resolve it (rh_token_resolve / base_mcp_resolve) before answering - do not guess and present the guess as fact.",
18
22
  "",
19
23
  "For deep research: prefer deep_research (multi-stage, saves to vault). Use continueFrom when extending prior reports.",
20
24
  "For live web info: use web_search. For market questions: use get_market_data or market_thesis.",
21
25
  "Save substantive findings to vault; do not save thin or empty outputs.",
26
+ "",
27
+ "NEVER call ask_finch from this shell. It exists for MCP clients that have no reasoning model of their own - you already are one. Calling it mid-task means asking a second model to think for you, which produces nothing you couldn't write yourself from the data you already have, and repeating it when unsatisfied just burns turns. If a tool's result already answers the question, write the answer yourself.",
28
+ "Do not call the same tool with the same or near-identical arguments more than once in a single answer. If deep_research, a search, or an analysis tool already returned data, synthesize from that - do not re-run it hoping for a different result, and do not chain more tool calls than the question actually needs. Stop calling tools and answer as soon as you have enough to answer well.",
22
29
  ].join("\n");
23
30
  async function runAgent(userMessage, history, onToolCall) {
31
+ const provider = process.env.FINCH_PROVIDER?.toLowerCase().trim();
24
32
  const bankrKey = process.env.BANKR_API_KEY;
25
33
  const anthropicKey = process.env.ANTHROPIC_API_KEY;
26
34
  const openaiKey = process.env.OPENAI_API_KEY;
35
+ // Explicit override - lets FINCH_PROVIDER=openai win even when BANKR_API_KEY
36
+ // is also set (e.g. as a persistent shell env var), same as llm.ts's callLLM.
37
+ if (provider === "bankr" && bankrKey)
38
+ return runBankrLoop(bankrKey, userMessage, history, onToolCall);
39
+ if (provider === "anthropic" && anthropicKey)
40
+ return runAnthropicLoop(anthropicKey, userMessage, history, onToolCall);
41
+ if (provider === "openai" && openaiKey)
42
+ return runOpenAILoop(openaiKey, userMessage, history, onToolCall);
43
+ // Auto-priority
27
44
  if (bankrKey)
28
45
  return runBankrLoop(bankrKey, userMessage, history, onToolCall);
29
46
  if (anthropicKey)
@@ -65,7 +82,7 @@ async function runAnthropicLoop(apiKey, userMessage, history, onToolCall) {
65
82
  "x-api-key": apiKey,
66
83
  "anthropic-version": "2023-06-01",
67
84
  },
68
- body: JSON.stringify({ model, max_tokens: 2048, system: SYSTEM_PROMPT, tools, messages }),
85
+ body: JSON.stringify({ model, max_tokens: 4096, system: SYSTEM_PROMPT, tools, messages }),
69
86
  signal: AbortSignal.timeout(90000),
70
87
  });
71
88
  if (!res.ok) {
@@ -103,7 +120,41 @@ async function runAnthropicLoop(apiKey, userMessage, history, onToolCall) {
103
120
  }
104
121
  messages.push({ role: "user", content: toolResults });
105
122
  }
106
- return { text: "Reached max tool iterations.", toolCalls };
123
+ // Hit the turn cap without a final answer - rather than hand back nothing,
124
+ // force one more call with no tools available so the model has to
125
+ // synthesize a real answer from whatever it already gathered.
126
+ return finishWithoutTools(async (msgs) => {
127
+ const res = await fetch("https://api.anthropic.com/v1/messages", {
128
+ method: "POST",
129
+ headers: { "Content-Type": "application/json", "x-api-key": apiKey, "anthropic-version": "2023-06-01" },
130
+ body: JSON.stringify({ model, max_tokens: 4096, system: SYSTEM_PROMPT, messages: msgs }),
131
+ signal: AbortSignal.timeout(90000),
132
+ });
133
+ if (!res.ok)
134
+ return "";
135
+ const data = await res.json();
136
+ return (data.content ?? []).filter(b => b.type === "text").map(b => b.text).join("");
137
+ }, messages, toolCalls);
138
+ }
139
+ // Shared turn-cap fallback: rather than "Reached max tool iterations." with
140
+ // nothing useful, ask the model to synthesize a real answer from whatever
141
+ // conversation history (including every tool result so far) it already has,
142
+ // with no tools offered so it can't keep deferring.
143
+ async function finishWithoutTools(call, messages, toolCalls) {
144
+ try {
145
+ const closingMessages = [
146
+ ...messages,
147
+ { role: "user", content: "Stop calling tools. Summarize what you found above into a direct answer for the user right now." },
148
+ ];
149
+ const text = await call(closingMessages);
150
+ if (text.trim())
151
+ return { text, toolCalls };
152
+ }
153
+ catch { /* fall through to the honest failure message below */ }
154
+ return {
155
+ text: "I gathered some information but ran out of turns before finishing the analysis. Try a narrower question, or ask me to continue from what I found.",
156
+ toolCalls,
157
+ };
107
158
  }
108
159
  // ── Convex-proxied Anthropic loop (session token only - platform covers LLM) ──
109
160
  async function runConvexProxiedLoop(userMessage, history, onToolCall) {
@@ -118,7 +169,7 @@ async function runConvexProxiedLoop(userMessage, history, onToolCall) {
118
169
  // callConvex handles wallet/session auth automatically; 90s timeout matches the proxy endpoint
119
170
  const data = await (0, convex_js_1.callConvex)("/llm/complete", "POST", {
120
171
  model,
121
- max_tokens: 2048,
172
+ max_tokens: 4096,
122
173
  system: SYSTEM_PROMPT,
123
174
  tools,
124
175
  messages,
@@ -152,7 +203,12 @@ async function runConvexProxiedLoop(userMessage, history, onToolCall) {
152
203
  }
153
204
  messages.push({ role: "user", content: toolResults });
154
205
  }
155
- return { text: "Reached max tool iterations.", toolCalls };
206
+ return finishWithoutTools(async (msgs) => {
207
+ const data = await (0, convex_js_1.callConvex)("/llm/complete", "POST", {
208
+ model, max_tokens: 4096, system: SYSTEM_PROMPT, messages: msgs,
209
+ }, "llm_complete", 90000);
210
+ return (data.content ?? []).filter((b) => b.type === "text").map((b) => b.text).join("");
211
+ }, messages, toolCalls);
156
212
  }
157
213
  // ── Bankr (OpenAI-compatible) agent loop ─────────────────────────────────────
158
214
  function toBankrTool(tool) {
@@ -180,7 +236,7 @@ async function runOpenAICompatibleLoop(url, authHeaders, model, providerLabel, u
180
236
  const res = await fetch(url, {
181
237
  method: "POST",
182
238
  headers: { "Content-Type": "application/json", ...authHeaders },
183
- body: JSON.stringify({ model, messages, tools, max_tokens: 2048 }),
239
+ body: JSON.stringify({ model, messages, tools, max_tokens: 4096 }),
184
240
  signal: AbortSignal.timeout(90000),
185
241
  });
186
242
  if (!res.ok) {
@@ -213,7 +269,18 @@ async function runOpenAICompatibleLoop(url, authHeaders, model, providerLabel, u
213
269
  messages.push({ role: "tool", tool_call_id: call.id, content: resultText });
214
270
  }
215
271
  }
216
- return { text: "Reached max tool iterations.", toolCalls };
272
+ return finishWithoutTools(async (msgs) => {
273
+ const res = await fetch(url, {
274
+ method: "POST",
275
+ headers: { "Content-Type": "application/json", ...authHeaders },
276
+ body: JSON.stringify({ model, messages: msgs, max_tokens: 4096 }),
277
+ signal: AbortSignal.timeout(90000),
278
+ });
279
+ if (!res.ok)
280
+ return "";
281
+ const data = await res.json();
282
+ return data.choices?.[0]?.message?.content ?? "";
283
+ }, messages, toolCalls);
217
284
  }
218
285
  async function runBankrLoop(apiKey, userMessage, history, onToolCall) {
219
286
  const model = process.env.FINCH_MODEL ?? process.env.BANKR_MODEL ?? "claude-haiku-4-5-20251001";