@mrrlin-dev/external-agents — Multi-LLM MCP ServerBLOCK
One MCP server routes LLM calls across 20+ providers, using round-robin dispatch and fallback to reduce rate-limit interruptions and cut costs up to 100x.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](#-2-minute-setup) [](#-2-minute-setup) [](#-2-minute-setup) [](https://www.npmjs.com/package/@mrrlin-dev/external-agents)
Give your coding agent a pool of 40+ cheaper models to hand work off to. Cut your bill 10-100×.
Changelog: CHANGELOG.md
The problem this solves
You run Claude Code or Codex all day. Most of what it does — reading files to answer one question, running a test suite, renaming a symbol across 30 files, summarizing a diff — does not need a frontier model. But it all bills at frontier prices, on one account, against one rate limit.
Meanwhile you probably already have a handful of separate, mostly-free quota buckets sitting idle: a Google AI Studio key, a Groq key, OpenRouter's :free models, whatever agentic CLIs you're logged into.
external-agents turns those into one pool your primary agent can dispatch into. It picks a healthy provider per call, round-robins across buckets, and when one returns 429 it moves to a different provider and honors that provider's real reset time.
It's also a clean substrate for LLM-Council-style panels: one pick_agents call gives you N picks from N distinct providers, so a jury of models isn't secretly the same model four times.
What this is optimizing for
Every design decision in here answers to five goals. They are the reason the proje
fd3a5703a743OBSERVED · 2026-10-12Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add external-agents -- npx -y @mrrlin-dev/[email protected]
Exposed tools (8)
5 read · 3 write · 0 destructive.
| Tool | Risk | Description |
|---|---|---|
dispatch | write | Run a specific agent by id with a prompt. transport ( |
get_state | read | Return the current external-agents state file (per-agent healthy/not_installed/needs_auth/quota_exhausted/errored_transient with metadata) |
get_stats | read | Aggregate dispatch telemetry from ~/.local/state/external-agents/dispatch-log.jsonl. Returns per-agent counts, tokens, outcomes; per-transport totals. |
list_agents | read | List configured agents merged with their current state |
pick_agents | read | Pick up to N distinct healthy candidates by round-robin (preference_order + last_used_at). |
ping | read | Ping the server |
probe_agent | write | Probe a specific agent by id; runs an install-check and updates the state file. Returns the new state. |
set_credential | write | Persist an API-key env variable so the next dispatch (and future sessions) see it. Writes to ~/.local/state/external-agents/keys.env (mode 0600). |
Trust audit
BLOCKgrade F · trust 59/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (2 observation(s))
- Network
- declared (5 observation(s))
- Shell
- declared (5 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (21)
yaml.load(fs.readFileSync(LOCAL_PATH, "utf-8"));
const parsed = yaml.load(fs.readFileSync(p, "utf-8"));
const bundled = yaml.load(raw);
const parsed = yaml.load(fs.readFileSync(LOCAL_PATH, "utf-8"));
# Requires prior `kiro-cli login`; state at ~/.aws/sso equivalent.
const token = "github_pat_11ABCDEFG0abcdefghijklmnopqrstuvwxyz1234567890AB";
const token = "github_pat_11ABCDEFG0abcdefghijklmnopqrstuvwxyz1234567890AB";
const overlay = yaml.load(
assert.equal(displayPath("/etc/passwd", "/Users/alice"), "/etc/passwd");fs.writeFileSync(outsidePath, "exfiltrated");
assert.ok(!result.includes("exfiltrated"));external-agents ui # opens http://127.0.0.1:4711
transports: { generate_new: { url: `http://127.0.0.1:${port}`, model: "fixture" } },transports: { generate_new: { url: `http://127.0.0.1:${port}`, model: "fixture" } },transports: { generate_new: { url: `http://127.0.0.1:${port}`, model: "fixture" } },url: "http://127.0.0.1:1/never-reached",
@modelcontextprotocol/sdk, js-yaml
<summary><b>Do you send my API keys anywhere?</b></summary>
docs/hero.png
mrrlin-dev-external-agents-0.56.0.tgz
curl -fsSL https://raw.githubusercontent.com/mrrlin-dev/external-agents/main/install.sh | bash
Gates applied: no_behavioural_pass.
fd3a5703a743full audit observations/trust-audit/mcp-server/mrrlin-dev__external-agents.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-12 | fd3a5703a743 | BLOCK | F | 59 | first audit |
Questions
What is the @mrrlin-dev/external-agents MCP server?
One MCP server routes LLM calls across 20+ providers, using round-robin dispatch and fallback to reduce rate-limit interruptions and cut costs up to 100x.
What tools does @mrrlin-dev/external-agents expose?
8 in total: 5 read-only, 3 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.
Is @mrrlin-dev/external-agents safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (59/100) and found 5 critical or high issues in the source. Each one is listed on this page with the file and line it is on.
What credentials does @mrrlin-dev/external-agents need?
It reads EA_TEST_KEY_2 and MY_ENTRY_API_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does @mrrlin-dev/external-agents run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as @mrrlin-dev/external-agents at 0.62.0.
How current is this page?
The grade is for one exact copy of the source (fd3a5703a743), read on 2026-10-12. The repository is watched and re-audited when it changes.