finary-mcp
# finary-mcp
A deliberately **read-only** [Model Context Protocol](https://modelcontextprotocol.io/) server for [Finary](https://finary.com/), built on top of the unofficial [`finary-uapi`](https://github.com/lasconic/finary_uapi) client.
> [!WARNING]
> This project is independent from Finary and is not endorsed, supported or maintained by Finary. It depends on private, undocumented endpoints via `finary-uapi`; either project can break without notice. It is not financial, tax, legal, or investment advice.
## Safety model
`finary-mcp` is intentionally a narrow, read-only adapter:
- It exposes only profile, organization, institution, portfolio and transaction queries.
- It has **no** login, account import, create, update, delete, transfer, trade or generic CLI tool.
- It constructs `finary-uapi` commands from a fixed allowlist, without a shell.
- Filter values are validated before execution.
- It returns no upstream stdout/stderr when a request fails, because an upstream login flow may print session material.
- Its state directory is explicit (`FINARY_MCP_STATE_DIR`); it does not look for tokens in arbitrary working directories.
This reduces accidental writes through MCP. It does not make a machine safe if another process can read your session files. Run the server only for an account and profile you trust.
### Important authentication caveat
“Read-only” refers to Finary portfolio data. `finary-uapi` refreshes its Clerk session before requests and can rewrite `jwt.json`; therefore the private state directory must remain writable by the local service account even though no MCP tool changes Finary data. The server never returns that file, cookies, or child-process diagnostics.
`finary-uapi` also brings `fuzzywuzzy` as a transitive GPL-2.0 dependency. Review the upstream dependency graph and licensing implications for your intended distribution or deployment.
## Prerequisites
- Python 3.10+.
- A local Finary session already created by `finary-uapi`.
- A private directory containing both `jwt.json` and `localCookiesMozilla.txt`, mode `0700` for the directory and `0600` for files.
The server does **not** support Google OAuth itself. Follow the authentication process supported by `finary-uapi` to create or renew the local session. Never send a password, TOTP code, JWT, cookie export, or session file to an agent, repository, issue tracker, or chat.
## Install
```bash
python -m venv .venv
. .venv/bin/activate
pip install finary-mcp
```
For development from a checkout:
```bash
pip install -e '.[dev]'
pytest -q
```
## Configure an MCP host
Set `FINARY_MCP_STATE_DIR` to the directory that holds your Finary session. If `finary-uapi` is installed in a separate virtual environment, set `FINARY_UAPI_PYTHON` to that environment's Python executable.
Example generic stdio configuration:
```json
{
"mcpServers": {
"finary": {
"command": "/path/to/finary-mcp/.venv/bin/finary-mcp",
"env": {
"FINARY_MCP_STATE_DIR": "/private/path/to/finary-state",
"FINARY_UAPI_PYTHON": "/path/to/finary-uapi/.venv/bin/python"
}
}
}
}
```
Use absolute paths. The state directory is private data and must never be committed. The supplied `.gitignore` excludes the known session files.
### Hermes Agent example
```yaml
mcp_servers:
finary:
command: /path/to/finary-mcp/.venv/bin/finary-mcp
env:
FINARY_MCP_STATE_DIR: /private/path/to/finary-state
FINARY_UAPI_PYTHON: /path/to/finary-uapi/.venv/bin/python
tools:
include:
- finary_me
- finary_organizations
- finary_institution_connections
- finary_portfolio
- finary_transactions
```
Add this through Hermes' MCP/configuration workflow rather than copying credentials into a public configuration file. Restart the Hermes process after adding a server so tool discovery runs again.
## Tools
| Tool | Read-only purpose |
| --- | --- |
| `finary_me` | Read the authenticated profile. |
| `finary_organizations` | List accessible Finary organizations. |
| `finary_institution_connections` | List financial-institution connections. |
| `finary_portfolio` | Read an allowed portfolio class: investments, securities, cryptos, fonds euro, SCPI, real estate or holding accounts. |
| `finary_transactions` | Read checking, investment or credit transactions with pagination and date/account filters. |
## Dependency: `finary-uapi`
This project is an adapter, not a reimplementation of Finary's API. It calls the `finary-uapi` CLI from the [lasconic/finary_uapi](https://github.com/lasconic/finary_uapi) project, whose package is currently declared in `pyproject.toml` as `finary-uapi>=0.2.3,<0.3`.
That dependency uses undocumented Finary endpoints and persists a local session. Review its source and license before using this server. When an upstream upgrade is needed, test it in a separate environment first and pin a compatible version here.
## Development
```bash
pytest -q
python -m build
```
Tests use no live Finary account and must not create session files. Before publishing, scan the staged files for `jwt.json`, `localCookiesMozilla.txt`, credentials, emails, cookies, and tokens.
## License
MIT. See [LICENSE](LICENSE).
TDQS
Scored across 5 tools
Each tool addresses a clearly distinct domain: user profile, organizations, institution connections, portfolio classes, and transactions. No overlap in purpose, and the descriptions make the boundaries obvious.
All tools use a consistent 'finary_' prefix followed by a descriptive noun (me, organizations, institution_connections, portfolio, transactions). The naming pattern is uniform and predictable.
Five tools is well-scoped for a read-only financial data API. Each tool covers a major data category without redundancy, and the count is neither sparse nor bloated.
The surface covers the core read operations for a personal finance platform: user, orgs, connections, portfolio, and transactions. Minor gaps exist, such as no detailed per-asset breakdown beyond portfolio class, but the essential workflows are supported.