Three MCP servers that plug into apfel (Apple's on-device LLM CLI) and give it the one thing the 3B model can't do on its own: read the live web. Token-budget optimized, aggressively truncated, one brew install.
Most MCP bundles give you a search and a fetch tool and expect the model to chain them. In apfel's 4096-token context window, every extra tool call costs schema and conversation tokens you can't afford. apfel-mcp ships a compound search_and_fetch that does the whole round in a single call.
| apfel-mcp | separate search + fetch | |
|---|---|---|
| Tool-call round-trips per answer | 1 | 2-3 |
| Schema tokens per turn (2 schemas vs 1) | ~200 | ~450 |
| Tool-result hard cap (fits the context) | 5000 chars | unbounded |
| Readability article extraction | ✓ | ✗ |
| SSRF blocklist (private networks) | ✓ | ? |
| Tolerates model arg-key hallucinations | ✓ | ✗ |
| Works with apfel out of the box | ✓ | ? |
Numbers are from real measurements in apfel's 4096-token budget. Each MCP tool schema costs ~200-250 tokens in the prompt every turn; chaining two separate tools means the model pays that cost twice, plus the intermediate tool-call JSON in conversation history. The compound tool collapses the whole thing into one round-trip.
Every terminal below is a real apfel --chat session I ran before publishing. Tool calls, raw tool output, model answers - all copied verbatim. No cloud. No cherry-picked best-of-N. The compound tool handles it in one round-trip.
Three binaries on your PATH. Attach one (or all three) to apfel with --mcp and the 3B model picks up the tools automatically.
One tap, one install. Three console scripts land on your PATH: apfel-mcp-url-fetch, apfel-mcp-ddg-search, apfel-mcp-search-and-fetch.
Pass the binary path with apfel --mcp $(which apfel-mcp-search-and-fetch). apfel launches the MCP as a stdio subprocess and discovers its tools.
The on-device 3B model decides when to call the tool, reads the truncated result, and answers. One round-trip. No cloud. Your question stays on your Mac. Only the target URLs get fetched.
Each one ships as a standalone binary and a Python module. Attach one, two, or all three. Shared infrastructure for caching, arg-tolerance, SSRF guards, and token-budget truncation.
Fetch an http(s) URL, extract the main article body with Readability, drop navigation and ads with BeautifulSoup, convert to Markdown, return the cleaned result.
DuckDuckGo web search via a direct httpx + BeautifulSoup HTML scrape. No API key. Unofficial and experimental - see the README for the honest caveats.
Search DDG AND fetch the top N result pages in ONE tool call. Saves ~500 tokens of schema/state overhead vs chaining separate tools. Declared as search and web_search so the 3B model's hallucinated names still route.
apfel-mcp plugs into apfel. You need apfel working first.
Install apfel with brew install Arthur-Ficial/tap/apfel. Requires macOS 26 Tahoe, Apple Silicon, Apple Intelligence enabled.
Required by apfel for Apple Intelligence. apfel-mcp itself runs on any macOS with Python 3.10+.
The MCPs hit the open web when the model calls them. apfel itself still runs 100% on-device. Your prompts never leave your Mac.
Free. MIT-licensed. One brew install installs all three MCPs.
Installs three console-script binaries to /opt/homebrew/bin. One formula, all three MCPs.
brew install Arthur-Ficial/tap/apfel-mcp
Updates with brew upgrade apfel-mcp. Formula source lives in Arthur-Ficial/homebrew-tap.
which apfel-mcp-url-fetchapfel --mcp $(which apfel-mcp-search-and-fetch)--mcp flags to stack tools in one sessionpip install apfel-mcp
From source: git clone + pip install -e .. Requires Python 3.10+.
python -m apfel_mcp.url_fetch_server
Run directly without a console script. Useful for MCP Inspector.
npx @modelcontextprotocol/inspector \ apfel-mcp-search-and-fetch
Official interactive testing UI for MCP servers.
apfel-mcp exists because apfel's context budget is 4,096 tokens, most of which is already consumed by the system prompt, tool schemas, and conversation history. Every tool result has to earn its place. These MCPs are engineered from the ground up to return small, useful output - not to truncate afterward.
query, q, term, topic, or any reasonable string under any key that isn't clearly a count.search and web_search in tools/list so the model's hallucinated names still dispatch correctly.wt-wt but the result quality varies by topic.URL_FETCH_ALLOW_PRIVATE_NETWORKS=1 for local dev.apfel.franzai.com - The AI engine. github.com/Arthur-Ficial/apfel-mcp - The code. 136 tests. ruff clean. MIT.
apfel-mcp is designed as a home for token-budget-aware MCPs. If you have an idea for one that fits apfel's 4096-token window, open an issue or a PR. The shared common/ module gives you budget enforcement, JSON-RPC stdio, SSRF-safe fetch, arg tolerance, and a test harness to build on.
Claude Code, Codex, Cursor, Aider, any autonomous coding agent - if you can read CLAUDE.md, run pytest, and open a pull request, you can ship an apfel-mcp. The contribution rules below were written to be unambiguous enough for an agent to follow without human translation. Credit your tool in the commit trailer (Co-Authored-By: Claude Sonnet 4.6 <[email protected]>), include a passing test suite, and submit. Humans and agents review on the same bar: token budget first, tests second, honesty about limits third.
None of these exist yet. All welcome as issues or PRs. Each one should land with tests, a hard token cap, and honest documentation of its limits.
Read-only SQL query over a local SQLite file. Result row count capped, output truncated.
Query a local git repo: recent commits, file blame, branch info. Read-only, no writes.
Fetch a section of a man page or built-in help text. 3000-char hard cap.
Read a bounded slice of a local file with path allowlist, byte cap, and no writes.
Current date, timezone conversion, relative date parsing. Tiny, fast, always useful.
Allowlisted read-only shell commands (df, uname, uptime, ps) with output truncation.
common/. Reuse budget.truncate_to, mcp_protocol.run_server, arg_tolerance.extract_string. Don't reinvent.MIT-licensed. Use it, fork it, ship it. Bug reports, pull requests, and new MCP ideas all welcome.