@finchagentic/mcp 4.0.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 +21 -0
- package/README.md +345 -0
- package/dist/_http-cache.js +96 -0
- package/dist/agent-loop.js +231 -0
- package/dist/annotations.js +113 -0
- package/dist/cli.js +1195 -0
- package/dist/clink-input.js +15 -0
- package/dist/config.js +132 -0
- package/dist/convex.js +151 -0
- package/dist/dex-pair.js +54 -0
- package/dist/enrichment-router.js +315 -0
- package/dist/index.js +256 -0
- package/dist/llm.js +323 -0
- package/dist/local-memory.js +102 -0
- package/dist/local-vault.js +454 -0
- package/dist/output-schemas.js +551 -0
- package/dist/prompts.js +111 -0
- package/dist/public-url.js +107 -0
- package/dist/resources.js +116 -0
- package/dist/server.js +300 -0
- package/dist/signal-gate.js +57 -0
- package/dist/token-decimals.js +26 -0
- package/dist/token-gate.js +88 -0
- package/dist/tool-filter.js +44 -0
- package/dist/tools/_solidity-scan.js +313 -0
- package/dist/tools/agents.js +729 -0
- package/dist/tools/automation.js +314 -0
- package/dist/tools/base-mcp.js +478 -0
- package/dist/tools/base.js +269 -0
- package/dist/tools/chronicle.js +268 -0
- package/dist/tools/coder.js +94 -0
- package/dist/tools/deep-research.js +1416 -0
- package/dist/tools/defi.js +291 -0
- package/dist/tools/equity.js +364 -0
- package/dist/tools/events.js +182 -0
- package/dist/tools/framework.js +150 -0
- package/dist/tools/github.js +514 -0
- package/dist/tools/insider.js +264 -0
- package/dist/tools/insight.js +634 -0
- package/dist/tools/market.js +555 -0
- package/dist/tools/memory.js +1046 -0
- package/dist/tools/miroshark.js +343 -0
- package/dist/tools/monitor.js +319 -0
- package/dist/tools/os.js +226 -0
- package/dist/tools/packets.js +296 -0
- package/dist/tools/research-chain.js +226 -0
- package/dist/tools/research-compare.js +280 -0
- package/dist/tools/research.js +188 -0
- package/dist/tools/rh-bridge.js +148 -0
- package/dist/tools/rh-mcp.js +1411 -0
- package/dist/tools/rh-orders.js +471 -0
- package/dist/tools/scanner.js +534 -0
- package/dist/tools/vault.js +764 -0
- package/dist/tools/wallet.js +200 -0
- package/dist/types.js +2 -0
- package/dist/wallet.js +184 -0
- package/package.json +87 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 noelclaw
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
<div align="center">
|
|
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%">
|
|
5
|
+
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<div align="center">
|
|
11
|
+
|
|
12
|
+
# The runtime layer for Agentic AI.
|
|
13
|
+
|
|
14
|
+
**Your AI remembers, keeps working, and survives every session.**
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
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
|
+
---
|
|
54
|
+
|
|
55
|
+
## Three Pillars
|
|
56
|
+
|
|
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
|
+
---
|
|
108
|
+
|
|
109
|
+
## Install
|
|
110
|
+
|
|
111
|
+
### One-command auto-install (any MCP client)
|
|
112
|
+
```bash
|
|
113
|
+
npx -y -p @finchagentic/mcp@4.0.0 finch install
|
|
114
|
+
```
|
|
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
|
+
|
|
117
|
+
### Claude Code
|
|
118
|
+
```bash
|
|
119
|
+
claude mcp add finch -s user -- npx -y -p @finchagentic/mcp@4.0.0 finch-mcp
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Cursor / Windsurf / Claude Desktop
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"mcpServers": {
|
|
126
|
+
"finch": {
|
|
127
|
+
"command": "npx",
|
|
128
|
+
"args": ["-y", "-p", "@finchagentic/mcp@4.0.0", "finch-mcp"]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### VS Code
|
|
135
|
+
`mcp.json` uses the `servers` key (not `mcpServers`), and each entry needs `"type": "stdio"`:
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"servers": {
|
|
139
|
+
"finch": {
|
|
140
|
+
"type": "stdio",
|
|
141
|
+
"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"]
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
<details>
|
|
163
|
+
<summary>Config file paths</summary>
|
|
164
|
+
|
|
165
|
+
| Client | Path |
|
|
166
|
+
|--------|------|
|
|
167
|
+
| Claude Desktop (Mac) | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
168
|
+
| Claude Desktop (Windows) | `%APPDATA%\Claude\claude_desktop_config.json` |
|
|
169
|
+
| Cursor | `.cursor/mcp.json` |
|
|
170
|
+
| Windsurf | `~/.codeium/windsurf/mcp_config.json` |
|
|
171
|
+
| Zed | `.config/zed/settings.json` |
|
|
172
|
+
| VS Code | `.vscode/mcp.json` |
|
|
173
|
+
|
|
174
|
+
</details>
|
|
175
|
+
|
|
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
|
|
183
|
+
|
|
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.
|
|
185
|
+
|
|
186
|
+
**Turn it on:**
|
|
187
|
+
```bash
|
|
188
|
+
npx -y -p @finchagentic/mcp@4.0.0 finch setup
|
|
189
|
+
# → answer "y" to "Enable local vault" (and, optionally, local memory)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**What runs local:**
|
|
193
|
+
|
|
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
|
|
207
|
+
```
|
|
208
|
+
|
|
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
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
> what have you found so far on AI agent infrastructure?
|
|
217
|
+
→ Pulls from vault: 3 reports across 7 days · summarizes key themes
|
|
218
|
+
|
|
219
|
+
> give me a bull vs bear thesis on ETH, save it
|
|
220
|
+
→ Full analysis written + auto-saved to vault as v1
|
|
221
|
+
|
|
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
|
|
227
|
+
|
|
228
|
+
> spawn an agent to track Base DeFi weekly
|
|
229
|
+
→ 🤖 Agent 'base-tracker' created · runs every Monday 09:00 UTC
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## 121 Tools Across the Runtime
|
|
235
|
+
|
|
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 |
|
|
242
|
+
|
|
243
|
+
> Run `finch doctor` for a 5-second health check showing exactly what's wired and what isn't.
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Configuration
|
|
248
|
+
|
|
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
|
|
261
|
+
|
|
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 |
|
|
274
|
+
|
|
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.
|
|
276
|
+
|
|
277
|
+
</details>
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Security Boundaries
|
|
282
|
+
|
|
283
|
+
> These 8 boundaries are mandatory. Violating any is a critical security failure.
|
|
284
|
+
|
|
285
|
+
| # | 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
|
+
---
|
|
309
|
+
|
|
310
|
+
## Troubleshooting
|
|
311
|
+
|
|
312
|
+
| Problem | Fix |
|
|
313
|
+
|---------|-----|
|
|
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
|
+
---
|
|
322
|
+
|
|
323
|
+
## Links
|
|
324
|
+
|
|
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) |
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
<div align="center">
|
|
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>
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Shared cache + 429-backoff wrapper for external HTTP calls.
|
|
3
|
+
// Designed for read-heavy public APIs like CoinGecko (free tier: 30 req/min)
|
|
4
|
+
// and DexScreener - agent loops + parallel tool calls were tripping rate
|
|
5
|
+
// limits in production. Cache hit returns the prior body without a network
|
|
6
|
+
// round-trip; cache miss does a fetch with bounded retries on 429/503.
|
|
7
|
+
//
|
|
8
|
+
// The cache is in-process only - every MCP server process keeps its own
|
|
9
|
+
// LRU. That's intentional: tokens get fresh data on cold start, no shared
|
|
10
|
+
// state to invalidate across users.
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.cachedFetch = cachedFetch;
|
|
13
|
+
exports.clearHttpCache = clearHttpCache;
|
|
14
|
+
exports.httpCacheStats = httpCacheStats;
|
|
15
|
+
const DEFAULT_TTL_MS = 45000; // 45s - fresh enough for prices, generous enough to absorb a flurry
|
|
16
|
+
const DEFAULT_MAX_ENTRIES = 200;
|
|
17
|
+
const DEFAULT_RETRY_DELAYS_MS = [500, 1500, 4000];
|
|
18
|
+
const cache = new Map();
|
|
19
|
+
function cacheKey(url, init) {
|
|
20
|
+
// POST bodies are part of the key so two POSTs with different params don't collide.
|
|
21
|
+
if (!init || !init.body || init.method === "GET")
|
|
22
|
+
return `GET ${url}`;
|
|
23
|
+
return `${init.method ?? "POST"} ${url} ${typeof init.body === "string" ? init.body : ""}`;
|
|
24
|
+
}
|
|
25
|
+
function evictExpired() {
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
for (const [k, v] of cache) {
|
|
28
|
+
if (v.expiresAt < now)
|
|
29
|
+
cache.delete(k);
|
|
30
|
+
}
|
|
31
|
+
// LRU-ish eviction - Map preserves insertion order, so the first keys are oldest.
|
|
32
|
+
while (cache.size > DEFAULT_MAX_ENTRIES) {
|
|
33
|
+
const firstKey = cache.keys().next().value;
|
|
34
|
+
if (firstKey === undefined)
|
|
35
|
+
break;
|
|
36
|
+
cache.delete(firstKey);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function cachedFetch(url, init = {}, opts = {}) {
|
|
40
|
+
const ttl = opts.ttlMs ?? DEFAULT_TTL_MS;
|
|
41
|
+
const retryDelays = opts.retryDelaysMs ?? DEFAULT_RETRY_DELAYS_MS;
|
|
42
|
+
const timeout = opts.timeoutMs ?? 15000;
|
|
43
|
+
evictExpired();
|
|
44
|
+
const key = cacheKey(url, init);
|
|
45
|
+
if (!opts.bypassCache) {
|
|
46
|
+
const hit = cache.get(key);
|
|
47
|
+
if (hit && hit.expiresAt > Date.now()) {
|
|
48
|
+
// Refresh recency - re-insert moves it to the end of the Map.
|
|
49
|
+
cache.delete(key);
|
|
50
|
+
cache.set(key, hit);
|
|
51
|
+
return { ok: hit.status >= 200 && hit.status < 300, status: hit.status, text: hit.body, fromCache: true };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
let lastStatus = 0;
|
|
55
|
+
let lastText = "";
|
|
56
|
+
for (let attempt = 0; attempt <= retryDelays.length; attempt++) {
|
|
57
|
+
try {
|
|
58
|
+
const res = await fetch(url, { ...init, signal: AbortSignal.timeout(timeout) });
|
|
59
|
+
const text = await res.text();
|
|
60
|
+
lastStatus = res.status;
|
|
61
|
+
lastText = text;
|
|
62
|
+
// Cache successful responses + 404s (404 is "definitively not found" - no point retrying).
|
|
63
|
+
if (res.ok || res.status === 404) {
|
|
64
|
+
cache.set(key, { body: text, status: res.status, expiresAt: Date.now() + ttl });
|
|
65
|
+
return { ok: res.ok, status: res.status, text, fromCache: false };
|
|
66
|
+
}
|
|
67
|
+
// Retry on 429 (rate limit) and 5xx (transient server errors).
|
|
68
|
+
if (res.status === 429 || res.status >= 500) {
|
|
69
|
+
const delay = retryDelays[attempt];
|
|
70
|
+
if (delay === undefined)
|
|
71
|
+
break;
|
|
72
|
+
// Honor server's Retry-After if provided (CoinGecko sends this).
|
|
73
|
+
const retryAfter = res.headers.get("retry-after");
|
|
74
|
+
const waitMs = retryAfter ? Math.min(parseInt(retryAfter) * 1000, 30000) : delay;
|
|
75
|
+
await new Promise((r) => setTimeout(r, waitMs));
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
// Non-retryable client error (400/401/403) - surface to caller without retry.
|
|
79
|
+
return { ok: false, status: res.status, text, fromCache: false };
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
lastText = err instanceof Error ? err.message : String(err);
|
|
83
|
+
const delay = retryDelays[attempt];
|
|
84
|
+
if (delay === undefined)
|
|
85
|
+
break;
|
|
86
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return { ok: false, status: lastStatus, text: lastText, fromCache: false };
|
|
90
|
+
}
|
|
91
|
+
function clearHttpCache() {
|
|
92
|
+
cache.clear();
|
|
93
|
+
}
|
|
94
|
+
function httpCacheStats() {
|
|
95
|
+
return { size: cache.size, maxEntries: DEFAULT_MAX_ENTRIES };
|
|
96
|
+
}
|