upbank-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@upbank-mcpshow my three most recent transactions"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
upbank-mcp
A Model Context Protocol server that exposes the Up Banking API to LLM clients, built with FastMCP and packaged for Docker.
It provides 19 tools and 2 resources covering the complete public surface of the Up API — accounts, transactions, categories, tags, attachments and webhooks — with responses reshaped for token efficiency, cursor pagination preserved end to end, and automatic retry on rate limits.
Contents
Related MCP server: Up Bank MCP Server
Requirements
Up account | A personal access token from https://api.up.com.au/getting_started. Tokens look like |
Docker | Docker Engine 20.10+ with Compose v2 ( |
Python | 3.11+ — only if running outside Docker. |
The Up API is available to Up customers in Australia. A token grants access to the issuing customer's own data only.
Quick start
git clone git@github.com:uiux-me/upbank-mcp.git
cd upbank-mcp
cp .env.example .env # paste your token into UP_API_TOKEN
docker compose up --buildThe server listens on http://127.0.0.1:8000/mcp. Verify it:
docker compose exec upbank-mcp python -c "
import asyncio, upbank_mcp
from fastmcp import Client
async def main():
async with Client(upbank_mcp.mcp) as c:
print((await c.call_tool('ping')).data)
asyncio.run(main())"A healthy response is your customer id and a status emoji:
{'ok': True, 'id': 'eb59f467-…', 'status_emoji': '⚡️'}Configuration
All configuration is by environment variable. Compose reads .env from the project
directory automatically.
Variable | Default | Description |
| (required) | Personal access token. The only variable the server reads for credentials. Compose refuses to start without it; run directly, the server starts and fails on the first tool call. |
|
| API base URL. Override only for testing against a mock. |
|
|
|
|
| Bind address for the HTTP transport, inside the container. |
|
| Listen port for the HTTP transport, inside the container. |
|
| Compose only. Host port published on |
Running the server
HTTP, via Compose
Best for a long-running server shared by several clients on your machine.
docker compose up --build # foreground
docker compose up -d --build # detached
docker compose logs -f # follow logs
docker compose down # stop and removeThe port is published on 127.0.0.1 only. See Security.
stdio, via Docker
Best for MCP clients that spawn the server as a subprocess. Build the image once:
docker build -t upbank-mcp:latest .The image defaults to MCP_TRANSPORT=stdio, so no transport override is needed.
Without Docker
pip install -e .
export UP_API_TOKEN=up:yeah:...
upbank-mcpSet MCP_TRANSPORT=http to serve over HTTP instead of stdio.
Connecting an MCP client
Claude Code
claude mcp add upbank \
-e UP_API_TOKEN=up:yeah:... \
-- docker run -i --rm -e UP_API_TOKEN upbank-mcp:latestClaude Desktop, or any client using mcpServers config
{
"mcpServers": {
"upbank": {
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "UP_API_TOKEN", "upbank-mcp:latest"],
"env": { "UP_API_TOKEN": "up:yeah:..." }
}
}
}-i is required — the server communicates over stdin/stdout. --rm cleans up the
container when the client disconnects.
Over HTTP
Point the client at http://127.0.0.1:8000/mcp while the Compose stack is running.
Tool reference
Required parameters are bold. Every list tool accepts cursor; see
Pagination.
Utility
Tool | Parameters | Returns |
| — |
|
Accounts
Tool | Parameters | Returns |
|
| Page of accounts with balances. |
|
| One account. |
Transactions
Tool | Parameters | Returns |
|
| Page of transactions, newest first. Omit |
|
| One transaction, including hold, round-up and cashback detail. |
since and until bound createdAt inclusively. category accepts a parent id,
which matches all of its children.
Categories
Tool | Parameters | Returns |
|
| The category tree, or one parent's children. Not paginated. |
|
| One category with its parent and child ids. |
|
| Sets the category, or clears it when |
Categories are fixed by Up and cannot be created. Ids are slugs such as
restaurants-and-cafes. Only transactions with is_categorizable: true can be
changed, and only leaf categories are accepted — passing a parent such as
good-life returns HTTP 403.
Tags
Tool | Parameters | Returns |
|
| Page of tags. A tag's id is its label. |
|
| Adds tags, creating any that do not exist. |
|
| Removes tags from the transaction. |
A transaction holds at most 6 tags. Tags with no remaining transactions disappear
from list_tags.
Attachments
Tool | Parameters | Returns |
|
| Page of attachments. |
|
| One attachment. |
file_url is a signed URL that expires at file_url_expires_at. Fetch it promptly
or re-request the attachment.
Webhooks
Tool | Parameters | Returns |
|
| Page of webhooks. |
|
| One webhook. |
|
| The new webhook, including |
|
|
|
|
| Sends a test |
|
| Recent delivery attempts with response codes and bodies. |
secret_key is returned only at creation and never again. Store it to verify
the X-Up-Authenticity-Signature header (SHA-256 HMAC) on incoming deliveries.
Resources
URI | Contents |
| Every account and its current balance, as a single JSON snapshot. |
| The full category tree, for resolving valid |
Both are read on demand and reflect state at read time.
Response conventions
Shape
Up returns JSON:API, which nests every field under
attributes/relationships and repeats self-links on each resource. This server
flattens each resource into a compact dict and omits optional fields when absent,
which materially reduces token cost without losing information a caller needs.
{
"id": "45b83097-c97d-40da-9790-254056f03d40",
"status": "SETTLED",
"description": "Google One",
"amount": { "value": "-2.49", "currency": "AUD", "base_units": -249 },
"created_at": "2026-08-20T06:53:17+10:00",
"settled_at": "2026-08-20T06:53:17+10:00",
"account_id": "90c0fffc-bed6-4214-9450-6a76cd39957b",
"category_id": "games-and-software",
"parent_category_id": "good-life",
"tags": [],
"is_categorizable": true
}Fields such as foreign_amount, hold_info, round_up, cashback,
card_purchase_method, note and message appear only when the transaction has
them.
Money
Every amount is an object:
{ "value": "-2.49", "currency": "AUD", "base_units": -249 }value is a decimal string, base_units is the integer minor unit (cents for AUD).
Debits are negative. Prefer base_units for arithmetic to avoid float error.
Pagination
List tools return:
{ "items": [ ... ], "next_cursor": "https://api.up.com.au/...", "prev_cursor": null }To page, pass a returned cursor back as the cursor argument of the same tool.
Cursors are Up's own opaque URLs and already encode the filters and page size, so
all other arguments are ignored when cursor is set. A null cursor means no further
page in that direction.
Cursors are validated against the configured API host before being followed, so a cursor cannot redirect the client to another server.
Dates
since and until accept either YYYY-MM-DD or a full RFC-3339 timestamp. Bare
dates and naive datetimes are anchored to Australia/Sydney, matching how Up
presents times in the app; the correct offset is applied for the date in question,
so daylight saving is handled. Unparseable input is rejected before the request is
made, rather than surfacing as an opaque HTTP 400.
Error handling and rate limits
API errors are raised as
ToolErrorwith the HTTP status and Up's own error title and detail, for example:HTTP 403 — Forbidden: Top-level categories cannot be set directly on transactions.429 and 5xx responses are retried up to 3 times with exponential backoff, honouring the
Retry-Afterheader when present.Network failures are retried on the same schedule before surfacing.
4xx responses other than 429 are not retried — they indicate a bad request.
Project layout
src/upbank_mcp/
├── client.py Async HTTP client: auth, retry/backoff, date normalisation,
│ cursor host validation
├── shapes.py JSON:API → flat dict transforms, one per resource type
├── server.py FastMCP instance, tool and resource definitions, entrypoint
├── __init__.py Exports `mcp` and `main`
└── __main__.py Enables `python -m upbank_mcp`The separation is deliberate: client.py knows about HTTP and nothing about MCP,
shapes.py is pure data transformation, and server.py holds the tool contracts.
Each is independently testable.
Development
pip install -e .
export UP_API_TOKEN=up:yeah:...
upbank-mcp # stdio
MCP_TRANSPORT=http upbank-mcp # http on :8000Drive the server in-process with the FastMCP client:
import asyncio
from fastmcp import Client
import upbank_mcp
async def main():
async with Client(upbank_mcp.mcp) as client:
print(await client.list_tools())
result = await client.call_tool("list_accounts", {"account_type": "TRANSACTIONAL"})
print(result.data)
asyncio.run(main())Rebuild the image after changes:
docker compose up -d --buildSecurity
The token is powerful. Up personal access tokens cannot move money — the API has no payment or transfer endpoint — but they can read your complete transaction history and mutate categories, tags and webhooks. Treat one like a password.
The HTTP transport has no authentication of its own. Anything that can reach the port can read your banking data. Compose therefore publishes to
127.0.0.1only. Do not bind it to0.0.0.0or expose it through a tunnel or reverse proxy without putting authentication in front of it.The token is never baked into an image.
.envis listed in.dockerignore, and the token is supplied at runtime. It does not appear in any image layer, so the image is safe to push to a registry..envis gitignored, and.env.examplecarries a placeholder only.The container runs as a non-root user (uid 10001).
Rotate immediately at https://api.up.com.au/getting_started if a token is ever exposed. Tokens do not expire on their own.
Troubleshooting
Symptom | Cause and fix |
|
|
Compose exits with | Same cause, caught at container start rather than first call. |
| Another process holds port 8000. Set |
| Token is invalid or revoked. Reissue it. |
|
|
| Ids are per-customer. Confirm the id came from this token's own data. |
Repeated | Sustained rate limiting. Reduce |
Client shows no tools | The client must run the container with |
Reference
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseDqualityDmaintenanceA Model Context Protocol server that allows AI assistants to connect to and manage Israeli bank accounts, fetch transactions, and handle authentication for all major Israeli banks and credit card companies.232
- AlicenseNot gradedqualityDmaintenanceAn MCP wrapper for Up Bank's API that allows Claude and other MCP-enabled clients to manage accounts, transactions, categories, tags, and webhooks from Up Bank.3MIT
- AlicenseNot gradedqualityCmaintenanceA Model Context Protocol server that enables interaction with You Need A Budget (YNAB) via their API, allowing users to manage budgets, accounts, categories, and transactions through natural language.2MIT
- AlicenseNot gradedqualityCmaintenanceA Model Context Protocol server that allows AI assistants to interact with Lunch Money accounts, enabling management of transactions, categories, budgets, and other financial data through natural language commands.MIT
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
A Model Context Protocol server for Wix AI tools
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/uiux-me/upbank-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server