MCP Server
Moneyline ships a [Model Context Protocol](https://modelcontextprotocol.io/) server that exposes 45 tools and 5 resources, so an agent can author and run workflows, not just read data.
The server proxies the Moneyline API. Anything an agent does through it is scoped to the API key it authenticates with, so it sees exactly what that tenant sees.
Tool paths are verified against the OpenAPI spec in CI, so they cannot silently
drift from the API. Run tools/list against a running server for the live,
authoritative catalog — the tables below are a guide, not the source of truth.
Install
Build from source:
cd apps/mcp && bun install && bun run build@moneyline/mcp-server is not on npm yet — it publishes from release.yml on
the first v* tag, and no tag has been cut. Until then, build from source and
point your client at apps/mcp/dist/index.js. The npx invocations below
start working once that release lands.
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"moneyline": {
"command": "npx",
"args": ["-y", "@moneyline/mcp-server"],
"env": {
"MONEYLINE_API_KEY": "ml_live_xxxxx",
"MONEYLINE_API_URL": "https://api.moneyline.co"
}
}
}
}Pointing at a local build instead:
{
"mcpServers": {
"moneyline": {
"command": "node",
"args": ["/path/to/moneyline/apps/mcp/dist/index.js"],
"env": {
"MONEYLINE_API_KEY": "ml_test_xxxxx",
"MONEYLINE_API_URL": "http://localhost:3000"
}
}
}
}Claude Code
claude mcp add moneyline \
--env MONEYLINE_API_KEY=ml_live_xxxxx \
--env MONEYLINE_API_URL=https://api.moneyline.co \
-- npx -y @moneyline/mcp-serverTransports
Selected by MCP_TRANSPORT.
| Mode | Use | Auth |
|---|---|---|
stdio (default) | Local — Claude Desktop, Claude Code, CLIs | MONEYLINE_API_KEY env, one key per process |
http | A hosted server serving many callers | Per-request Authorization: Bearer <key> |
Nothing needs to be hosted to use the server: stdio runs it as a subprocess of
your MCP client, and is the right choice for a single user on one machine.
Run the HTTP transport when you want one deployment to serve several people or a remote agent:
MCP_TRANSPORT=http MCP_PORT=3333 MONEYLINE_API_URL=https://api.moneyline.co \
npx -y @moneyline/mcp-serverIt is stateless — each POST /mcp is handled by a fresh server bound to the
caller's key from the Authorization header, so one deployment serves many
tenants and holds no cross-request state. GET /health is an unauthenticated
liveness probe. A request without a key gets 401.
Connecting with OAuth
An API key identifies a tenant and never expires, which is right for a server you control and wrong for someone connecting their own account to an agent they installed. For that, the Moneyline API is also an OAuth 2.1 authorization server, so a client can be authorized by a user instead of configured with a shared secret — and that grant can be revoked without rotating a key everything else depends on.
The hosted MCP server advertises where to go:
curl https://mcp.moneyline.co/.well-known/oauth-protected-resource{
"resource": "https://api.moneyline.co",
"authorization_servers": ["https://api.moneyline.co"],
"bearer_methods_supported": ["header"]
}A request without credentials also answers with the same pointer, so a client can begin the flow from the failure rather than needing to be told about it:
WWW-Authenticate: Bearer resource_metadata="https://mcp.moneyline.co/.well-known/oauth-protected-resource"From there the standard endpoints are discoverable at the authorization server:
curl https://api.moneyline.co/.well-known/oauth-authorization-serverDynamic client registration (RFC 7591) is supported, so a client can register
itself rather than the operator provisioning one by hand, and PKCE (S256) is
required. The user signs in on the dashboard and approves the request; the
token that comes back is bound to that user, carries an expiry, and is accepted
by the API anywhere an API key is.
Tokens are scoped to the user's organization. A user who belongs to no organization cannot complete the flow — create one first.
Environment variables
| Variable | Default | Description |
|---|---|---|
MONEYLINE_API_URL | http://localhost:3000 | API the server proxies to |
MONEYLINE_API_KEY | — | stdio only. ml_live_* or ml_test_* |
MCP_TRANSPORT | stdio | stdio or http |
MCP_PORT | 3333 | http only |
Leave MONEYLINE_API_KEY unset under http — the key comes from the request.
Tools
Workflows (14)
The workflow builder, exposed so an agent can do what the studio UI does.
| Tool | Description |
|---|---|
moneyline_list_node_types | Every node type the engine can run, with its config fields |
moneyline_list_workflow_templates | Prebuilt templates (MCA, bank statement analysis, SBA) |
moneyline_get_workflow_template | One template including its full node graph |
moneyline_clone_workflow_template | Copy a template into an editable workflow |
moneyline_create_workflow | Create a workflow from a trigger and a set of nodes |
moneyline_update_workflow | Update a workflow; nodes and edges are replaced wholesale |
moneyline_list_workflows | This tenant's workflows, with status and last run |
moneyline_get_workflow | One workflow including its full node graph |
moneyline_delete_workflow | Delete a workflow permanently |
moneyline_activate_workflow | Activate so the trigger fires |
moneyline_deactivate_workflow | Pause; existing runs are unaffected |
moneyline_run_workflow | Run now regardless of the trigger |
moneyline_list_workflow_runs | A workflow's runs, newest first |
moneyline_get_workflow_run | One run with its per-node step timeline |
Call moneyline_list_node_types before authoring. Activation refuses any node
type the engine cannot run, so an agent that guesses type strings writes a graph
it cannot activate — and the catalog is the difference between composing a
workflow and guessing at one.
Node positions and edges are optional. The API requires an x/y per node because the canvas needs one, but an agent composing a pipeline has no opinion about layout: omitted nodes are laid out in a readable column, and omitted edges wire the trigger through the nodes in the order given. The result still opens in the builder.
Submissions (8)
| Tool | Description |
|---|---|
moneyline_create_submission | Create a submission with external ID and metadata |
moneyline_get_submission | Retrieve a submission by ID |
moneyline_list_submissions | List submissions with pagination |
moneyline_update_submission | Update name/metadata |
moneyline_start_workflow | Kick off the processing pipeline |
moneyline_get_processing_status | Check processing progress and stage |
moneyline_find_duplicates | Find duplicate submissions by fuzzy match |
moneyline_delete_submission | Delete a submission and its data |
Documents (5)
| Tool | Description |
|---|---|
moneyline_upload_document | Upload a PDF/image to a submission |
moneyline_list_documents | List documents for a submission |
moneyline_get_parsed_results | Extracted fields from a parsed document |
moneyline_reclassify_document | Change document classification |
moneyline_split_document | Split a multi-document PDF |
Analytics (9)
| Tool | Description |
|---|---|
moneyline_get_scorecard | Full underwriting scorecard |
moneyline_get_cashflow | Cashflow analysis (inflows, outflows, net) |
moneyline_get_risk_score | Risk score with breakdown |
moneyline_get_balances | Account balance history and trends |
moneyline_get_anomalies | Anomaly detection results |
moneyline_get_forecasts | Revenue/cashflow forecasts |
moneyline_get_statistics | Statistical summary of financials |
moneyline_get_recurring | Recurring transaction detection |
moneyline_get_merchant_summary | Spending by merchant |
Policies (4)
| Tool | Description |
|---|---|
moneyline_evaluate_policy | Evaluate a submission against policy rules |
moneyline_create_rule | Create a policy rule |
moneyline_list_rules | List rules for a policy |
moneyline_get_policy_history | Policy evaluation history |
Transactions (3)
| Tool | Description |
|---|---|
moneyline_enrich_transactions | Enrich with categories, merchants, flags |
moneyline_create_transactions | Manually create transactions |
moneyline_get_transactions | List transactions with filtering |
Integrations (2)
| Tool | Description |
|---|---|
moneyline_import_plaid | Import bank data via Plaid link |
moneyline_import_bank_pdf | Import and process a bank statement PDF |
Resources
Read-only access over moneyline:// URIs.
| URI | Description |
|---|---|
moneyline://submissions/{id} | One submission |
moneyline://documents/{id} | One document |
moneyline://transactions | Transactions |
moneyline://analytics/{id}/scorecard | Scorecard for a submission |
moneyline://categories | Transaction category taxonomy |
Examples
Once configured, ask Claude:
"What workflow node types are available? Build me a pipeline that classifies an uploaded document, parses it, and raises a task if the risk score is over 700."
"Clone the MCA application template, activate it, and run it against submission sub_abc123."
"Show me the last five runs of my invoice workflow and tell me which node the failed ones stopped on."
"Create a submission for Acme Corp with external ID acme-001, upload this bank statement, and generate a scorecard."
Verifying a local setup
With the server built, a handshake and tools/list over stdio needs no API:
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| MONEYLINE_API_KEY=ml_test_xxxxx node dist/index.jsA tool that reaches the API needs MONEYLINE_API_URL pointing at a running one.
Develop
bun run dev # stdio, watch mode
bun run test # vitest
bun run build # -> dist/