Plaid

Lightweight, dependency-free, in-memory Plaid API fake for testing code that uses the official plaid Node client (and the language-agnostic Plaid REST API).

Default port: 4866

Quick start

import { PlaidServer } from "./services/plaid/src/server.js";

const server = new PlaidServer(4866);
await server.start();
// ... run your app/tests ...
await server.stop();

Point the official plaid client at it via the base URL:

import { Configuration, PlaidApi } from "plaid";

const client = new PlaidApi(new Configuration({
  basePath: "http://127.0.0.1:4866",
  baseOptions: { headers: { "PLAID-CLIENT-ID": "parlel", "PLAID-SECRET": "parlel" } },
}));

Auth is via client_id + secret in the JSON request body (any non-empty values are accepted, matching a local sandbox key).

Access via MCP / preview URL

Once registered in the parlel pool, the service is reachable at its preview URL (http://127.0.0.1:4866) and through the parlel MCP server as the plaid tool. Set PLAID_BASE_URL=http://127.0.0.1:4866 and any non-empty PLAID_CLIENT_ID / PLAID_SECRET. The MCP layer proxies the REST calls below verbatim.

Implemented operations

Error envelope

{
  "error_type": "INVALID_INPUT",
  "error_code": "INVALID_ACCESS_TOKEN",
  "error_message": "...",
  "display_message": null,
  "request_id": "..."
}

Surface coverage

This emulator faithfully replicates the API surface most application code and agents exercise. Anything below the supported lines is either an intentional design choice for a fast, zero-cost local emulator (✓ By design) or a candidate for a future release (⟳ Roadmap) — never a silent inaccuracy.

Legend: ✅ fully supported · ◐ accepted (stored, not strictly enforced) · ✓ by design · ⟳ on the roadmap.

FeatureStatus
Link token create / public-token exchange✅ Supported
Accounts / balances / transactions / auth / identity✅ Supported
Item retrieval✅ Supported
client_id + secret body auth✓ By design — Intentional for a local, zero-cost test emulator
Real bank data / live institutions✓ By design — Always succeeds deterministically — no real funds move
Webhooks / async updates✓ By design — Not emitted
Asset reports / income / investments⟳ Roadmap

Manifest

See services/plaid/manifest.json — name plaid, port 4866, protocol http, healthcheck /health, env PLAID_CLIENT_ID, PLAID_SECRET, PLAID_BASE_URL.

<!-- parlel:testenv:start -->

Configuration — test.env

Copy these into your test.env (used by the bridge sidecar flow). Tokens are Parlel's seeded test credentials — any non-empty value is accepted by the emulator, so you rarely need to change them. Swap in real credentials only when pointing at the live service in prod.env.

PLAID_CLIENT_ID=parlel
PLAID_SECRET=parlel
PLAID_BASE_URL=http://parlel-bridge:4866
<!-- parlel:testenv:end -->