@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 +1 -1
- package/README.md +96 -249
- package/dist/agent-loop.js +73 -6
- package/dist/cli.js +78 -21
- package/dist/config.js +16 -16
- package/dist/llm.js +12 -48
- package/dist/local-memory-file.js +134 -0
- package/dist/local-memory.js +29 -9
- package/dist/resources.js +2 -2
- package/dist/tools/agents.js +4 -4
- package/dist/tools/base-mcp.js +4 -4
- package/dist/tools/chronicle.js +4 -4
- package/dist/tools/deep-research.js +10 -5
- package/dist/tools/defi.js +26 -5
- package/dist/tools/insight.js +23 -27
- package/dist/tools/memory.js +33 -29
- package/dist/tools/monitor.js +1 -1
- package/dist/tools/os.js +10 -5
- package/dist/tools/packets.js +3 -3
- package/dist/tools/research.js +2 -2
- package/dist/tools/rh-mcp.js +12 -0
- package/dist/tools/vault.js +23 -21
- package/dist/wallet.js +93 -16
- package/package.json +8 -20
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,159 +1,65 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDEyMDAgMzAwIj4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0iYmciIHgxPSIwIiB5MT0iMCIgeDI9IjAiIHkyPSIxIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojMGEwYTBhO3N0b3Atb3BhY2l0eToxIi8+CiAgICAgIDxzdG9wIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzFhMWEyNTtzdG9wLW9wYWNpdHk6MSIvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxyYWRpYWxHcmFkaWVudCBpZD0iZ2xvdyIgY3g9IjUwJSIgY3k9IjUwJSIgcj0iNTAlIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojMjU2M0VCO3N0b3Atb3BhY2l0eTowLjMiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMjU2M0VCO3N0b3Atb3BhY2l0eTowIi8+CiAgICA8L3JhZGlhbEdyYWRpZW50PgogIDwvZGVmcz4KICA8cmVjdCB3aWR0aD0iMTIwMCIgaGVpZ2h0PSIzMDAiIGZpbGw9InVybCgjYmcpIi8+CiAgPGNpcmNsZSBjeD0iNjAwIiBjeT0iMTUwIiByPSIyMDAiIGZpbGw9InVybCgjZ2xvdykiLz4KICA8dGV4dCB4PSI2MDAiIHk9IjEyMCIgZm9udC1mYW1pbHk9InN5c3RlbS11aSwgc2Fucy1zZXJpZiIgZm9udC1zaXplPSI1NiIgZm9udC13ZWlnaHQ9IjgwMCIgZmlsbD0iI2YwZjZmYyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgbGV0dGVyLXNwYWNpbmc9Ii0wLjAzZW0iPk5vZWxDbGF3PC90ZXh0PgogIDx0ZXh0IHg9IjYwMCIgeT0iMTY1IiBmb250LWZhbWlseT0ic3lzdGVtLXVpLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjIwIiBmb250LXdlaWdodD0iNDAwIiBmaWxsPSIjOTNjNWZkIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5UaGUgcnVudGltZSBsYXllciBmb3IgQWdlbnRpYyBBSTwvdGV4dD4KICA8dGV4dCB4PSI2MDAiIHk9IjE5NSIgZm9udC1mYW1pbHk9InN5c3RlbS11aSwgc2Fucy1zZXJpZiIgZm9udC1zaXplPSIxNCIgZm9udC13ZWlnaHQ9IjQwMCIgZmlsbD0iIzY0NzQ4YiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+MTIxIHRvb2xzIOKAlCBwZXJzaXN0ZW50IG1lbW9yeSDigJQgYWdlbnRzIOKAlCB3b3JrZmxvd3Mg4oCUIERlRmkgb24gQmFzZTwvdGV4dD4KPC9zdmc+" alt="Finch" width="100%">
|
|
3
|
+
# Finch
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
---
|
|
5
|
+
**The runtime layer for Agentic AI.**
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# The runtime layer for Agentic AI.
|
|
7
|
+
Persistent memory, autonomous agents, and workflows that survive every session.
|
|
13
8
|
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
17
|
+
## Why Finch
|
|
56
18
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
28
|
+
Always pin the version. Never use `@latest`.
|
|
29
|
+
|
|
112
30
|
```bash
|
|
113
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
84
|
+
## Quick start
|
|
185
85
|
|
|
186
|
-
**Turn it on:**
|
|
187
86
|
```bash
|
|
188
|
-
|
|
189
|
-
#
|
|
87
|
+
finch doctor # health check
|
|
88
|
+
finch setup # local vault / memory / providers
|
|
89
|
+
finch vault # inspect local vault
|
|
190
90
|
```
|
|
191
91
|
|
|
192
|
-
|
|
92
|
+
Try in your MCP client:
|
|
193
93
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
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
|
-
|
|
220
|
-
|
|
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
|
-
|
|
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
|
-
|
|
229
|
-
|
|
113
|
+
```json
|
|
114
|
+
"env": { "FINCH_TOOLS": "all" }
|
|
230
115
|
```
|
|
231
116
|
|
|
232
|
-
|
|
117
|
+
## Fully local
|
|
233
118
|
|
|
234
|
-
|
|
119
|
+
Finch is the runtime. **Your LLM is the brain. Your data stays yours.**
|
|
235
120
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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
|
-
|
|
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
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
-
|
|
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
|
-
|
|
151
|
+
Guided setup:
|
|
276
152
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
## Security Boundaries
|
|
153
|
+
```bash
|
|
154
|
+
npx -y -p @finchagentic/mcp@4.1.0 finch setup
|
|
155
|
+
```
|
|
282
156
|
|
|
283
|
-
|
|
157
|
+
## Security
|
|
284
158
|
|
|
285
159
|
| # | Boundary | Rule |
|
|
286
|
-
|
|
287
|
-
| 1 |
|
|
288
|
-
| 2 |
|
|
289
|
-
| 3 |
|
|
290
|
-
| 4 |
|
|
291
|
-
| 5 |
|
|
292
|
-
| 6 |
|
|
293
|
-
| 7 |
|
|
294
|
-
| 8 |
|
|
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
|
|
315
|
-
| Old version
|
|
316
|
-
| `
|
|
317
|
-
|
|
|
318
|
-
|
|
|
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
|
-
| **
|
|
328
|
-
| **
|
|
329
|
-
| **npm**
|
|
330
|
-
| **GitHub** | [github.com/
|
|
331
|
-
| **X**
|
|
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
|
-
|
|
336
|
-
|
|
337
|
-
### Star History
|
|
338
|
-
|
|
339
|
-
[](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
|
package/dist/agent-loop.js
CHANGED
|
@@ -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:
|
|
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
|
-
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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";
|