Open-source Model Context Protocol bridge for the Agentfy cloud platform. Lets Claude Desktop, Cursor, Cline, Claude Code, and any other MCP-aware client drive remote iOS devices through your Agentfy dashboard.
A small (~200 LOC) Node.js CLI that:
- Speaks MCP over stdio (default, recommended) or SSE to the AI client
- Speaks plain HTTPS to your Agentfy dashboard, authenticated via a single API key
- Fetches the live tool catalogue from the dashboard at startup and registers each tool with the MCP SDK dynamically — no schemas are bundled in the bridge itself
- Forwards each tool call to the dashboard, returns the result, that's it
┌──────────────────────┐ stdio MCP ┌──────────────────────┐ HTTPS (X-API-Key) ┌──────────────────────┐
│ Claude Desktop / │ ◀────────────▶ │ agentfy-mcp-server │ ─────────────────────▶ │ app.agentfy.io │
│ Cursor / Cline / ... │ │ (this package) │ │ dashboard │
└──────────────────────┘ └──────────────────────┘ └─────────┬────────────┘
│ Redis tunnel
▼
┌──────────────────────┐
│ iOS device(s) │
└──────────────────────┘
The bridge is intentionally a thin protocol adapter. All tool definitions, parameter validation, and dispatch live in your Agentfy dashboard — this binary carries zero business logic.
Requires Node.js 20+.
npm install -g agentfy-mcp-server
# or run ad-hoc:
npx agentfy-mcp-server --api-key <api-key> --dashboard-url https://app.agentfy.io-
Mint an API key in your dashboard at Settings → API Keys. Toggle Expose over MCP. Optionally set a device allowlist to constrain which devices this key can touch.
-
Add the bridge to your AI client config. For Claude Desktop, edit
~/Library/Application Support/Claude/claude_desktop_config.json(macOS) or the equivalent on your platform:{ "mcpServers": { "agentfy": { "command": "npx", "args": [ "-y", "agentfy-mcp-server", "--api-key", "your-key-from-the-dashboard", "--dashboard-url", "https://app.agentfy.io" ] } } } -
Restart Claude Desktop. The Agentfy tools will appear in the tool picker. Try: "List my devices" or "Take a screenshot of device d-abc123."
For other clients (Cursor / Cline / Claude Code), follow the same shape — they all consume MCP over stdio.
agentfy-mcp-server --api-key <<api-key>> --dashboard-url <origin> [options]
Required:
--api-key <key> Dashboard API key. (Env: DASHBOARD_API_KEY)
--dashboard-url <url> Dashboard origin, no trailing slash.
(Env: DASHBOARD_URL)
Options:
--transport <mode> stdio (default) | sse
--port <n> SSE port (default: 3001)
--log-level <level> debug|info|warn|error
--version, -v Print version and exit
--help, -h Print this help
Both --api-key / --dashboard-url and the DASHBOARD_API_KEY / DASHBOARD_URL environment variables are accepted. CLI flags win when both are set.
- Read
--api-keyand--dashboard-urlfrom argv or env. GET /api/auth/mcp-meon the dashboard withX-API-Key. The dashboard validates the key, checks the Expose over MCP toggle is on, and returns the tenant + user binding plus the device allowlist.GET /api/mcp/tools. The dashboard returns one MCP-shaped entry per tool the key is allowed to call:Device-scoped tools have their{ "name": "screenshot", "description": "Capture a screenshot of the device.", "inputSchema": { "type": "object", "properties": { ... }, "required": [...] }, "scope": "device", "safety": "read", "cost_hint": "low" }device_idparameter narrowed to the API key's allowlist server-side.- Register each tool with the MCP SDK using its raw JSON Schema, attaching a generic dispatcher.
When the AI client invokes a tool, the bridge:
- POSTs to
/api/mcp/invoke/<tool_name>withbody = { args: { ... } }. - The dashboard re-validates
argsagainst the canonical zod schema, builds aToolContextscoped to this API key, and calls the registered handler. - Whatever the handler returns is wrapped in
{ success: true, data: ... }and returned. The bridge extractsdataand presents it to the MCP client as a single text content block.
- It doesn't store anything to disk
- It doesn't cache tool results
- It doesn't try to interpret tool semantics — even
device_idvalidation is server-side - It doesn't include any vendored copy of the dashboard's tool definitions
This means the dashboard can add, remove, or reshape tools at any time and existing bridge installs pick them up on the next restart of the AI client (which re-spawns the bridge over stdio).
- Your API key flows directly from the bridge process on your machine to your dashboard. The bridge does not phone home; there is no telemetry.
- Logs go to
stderr(so they don't pollute the stdio MCP stream). Set--log-level debugif you want to see every tool call. - The dashboard's audit log records every tool invocation tagged with the API key's
token_preview, so an operator can revoke a key and see exactly what it did.
The bridge talks to whatever URL you give it via --dashboard-url, so private / on-prem Agentfy dashboards work without changes. Just point it at your internal hostname and supply a key minted on that instance.
git clone https://github.com/Agentfy-io/agentfy-mcp.git
cd agentfy-mcp
npm install
npm run build
node dist/index.js --api-key <api-key> --dashboard-url https://app.agentfy.iov5 switches to runtime tool discovery — the bridge no longer ships any tool schemas itself. Practically:
- The CLI surface is unchanged. Existing client configs keep working.
- Your dashboard must be on a build that ships
GET /api/mcp/toolsandPOST /api/mcp/invoke/:name(added alongside this v5 release). - Tool list updates no longer require a bridge release. Add or change a tool on the dashboard side, restart your MCP client, the new tool appears.
Issues and pull requests welcome. Note the design constraints:
- Keep dependencies minimal. This is a binary that lands on user machines; every dep is attack surface. Today the only runtime dep is
@modelcontextprotocol/sdk. Adding more requires a strong justification. - No tool-specific code in the bridge. If you find yourself special-casing a tool name, it belongs on the dashboard side.
- stdio is the primary transport. SSE is supported but not the default; most MCP clients consume stdio.
MIT — see LICENSE.
- Agentfy.io — https://agentfy.io
- Model Context Protocol — https://modelcontextprotocol.io