Echelon's operational MCP server. Tools for portfolio management, the internal finance ledger, Google Drive, Gmail, document filing, and operational SOPs — split across three workflow-shaped surfaces so an agent connects exactly one and its use case just works.
MCP endpoints: https://backoffice.api.nora.echelon.xyz/mcp/<surface>
Auth: OAuth 2.1 via the Nora auth server, with Google Workspace SSO
(@echelon.xyz accounts only)
| Connector name | Endpoint | Tools | Scope |
|---|---|---|---|
| Nora Fund | /mcp/fund |
35 = 21 portfolio reads + ledger writes (lookup, get_portfolio_summary, query_portfolio_view, record_investment, record_mark, void_transaction, …) + the 14 shared tools |
reads backoffice:read, mutations backoffice:write |
| Nora CFO | /mcp/cfo |
107 = 73 internal-finance-ledger tools (gl_get_cash_position, gl_get_income_statement, gl_categorize, gl_close_period, import_statement, import_card_statement, …) + the 20 Moneybags workbench tools (moneybags_sync, moneybags_claim_case, moneybags_search_*, moneybags_fetch_evidence, moneybags_submit, moneybags_brief, moneybags_open_questions, moneybags_queue, moneybags_month, moneybags_journal, moneybags_remember, moneybags_forget, moneybags_request, moneybags_close_request, moneybags_send_message, moneybags_record_reply) + the 14 shared tools |
reads backoffice:read, mutations backoffice:write; the workbench writes also admit backoffice.moneybags:write; moneybags_send_message and moneybags_record_reply need backoffice.moneybags.room:write |
| Nora Back Office | /mcp/dataroom |
41 = 27 filing-pipeline, layout, misfiling-review and cleanup tools (resolve_filing_target, file_attachment, file_document, label_email, send_email, get_folder_map, answer_layout_review_item, list_misfiling_suspects, accept_misfiling_suspect, compile_cleanup_plan, execute_cleanup_plan, reverse_cleanup_plan, …) + the 14 shared tools |
reads backoffice:read, mutations backoffice:write |
Each surface is a workflow destination: fund is the venture fund
(portfolio reads + ledger writes), cfo is the internal finance
ledger (cash, P&L, loans, forecasts, book close — with the cfo-ledger
reference docs: entity glossary, category hierarchy, loan model,
forecast & close — and the Moneybags workbench, whose procedure is the
moneybags skill), and dataroom is the shared-services side
(document filing pipeline, Drive/Gmail mutations). The workbench's writes
admit backoffice:write or backoffice.moneybags:write, a scope that never satisfies
backoffice:write: a token holding only backoffice.moneybags:write connected to cfo
gets 403 on every other mutation there. A shared
layer — skills/SOPs, reference data, feedback, and the Drive/Gmail
reads (14 tools) — is included on every mount, so one connection per
use case is self-sufficient; no companion "utilities" server is needed.
Adding a new surface is a deliberate decision reserved for a
genuinely new domain (e.g. legal), never a default.
Authorization is per-route: a read-only token connected to either surface still gets 403 on mutations.
Connect multiple surfaces when the agent's work spans domains. Catalog
listings are scoped per surface; when one surface honestly misses
(NO SOP FOUND), the client is expected to try its other mount — the
server never enumerates other surfaces. That hop is validated for
Claude (agents pick the right surface first and hop on a miss; see
tests/backoffice/trace/). Other MCP clients may treat a single-surface miss
as final — verify with the trace harness before relying on a new
client, or connect it to both mounts.
Add to .mcp.json in your project root (NOT settings.json):
{
"mcpServers": {
"backoffice-fund": {
"type": "http",
"url": "https://backoffice.api.nora.echelon.xyz/mcp/fund"
},
"backoffice-cfo": {
"type": "http",
"url": "https://backoffice.api.nora.echelon.xyz/mcp/cfo"
},
"backoffice-dataroom": {
"type": "http",
"url": "https://backoffice.api.nora.echelon.xyz/mcp/dataroom"
}
}
}
Then:
1. Restart Claude Code (or start a new session) — it reads
.mcp.json at startup only.
2. You'll be prompted to approve the server on first load.
3. On first tool call, a browser window opens for Google sign-in
on the Nora auth server (@echelon.xyz). Tokens refresh
automatically in the background.
If you already have a .mcp.json, merge the entries into the existing
mcpServers object.
https://backoffice.api.nora.echelon.xyz/mcp/cfo for internal
finance or https://backoffice.api.nora.echelon.xyz/mcp/fund for the
portfolio (each surface is a separate connection)Add to .cursor/mcp.json in your project root:
{
"mcpServers": {
"backoffice-fund": {
"url": "https://backoffice.api.nora.echelon.xyz/mcp/fund"
}
}
}
Restart Cursor. OAuth will prompt in a browser tab on first use.
Most MCP clients support URL-based servers. The endpoints are:
https://backoffice.api.nora.echelon.xyz/mcp/fund
https://backoffice.api.nora.echelon.xyz/mcp/cfo
https://backoffice.api.nora.echelon.xyz/mcp/dataroom
This server is an OAuth 2.1 resource server: RFC 9728 discovery at
https://backoffice.api.nora.echelon.xyz/.well-known/oauth-protected-resource
points at the Nora authorization server, which handles Google sign-in, dynamic client registration, and token issuance. Any MCP client that follows the standard 401 → resource-metadata → OAuth flow (claude.ai, Claude Code, Cursor, …) auto-detects everything; there is nothing to configure manually.
Not supported — these platforms don't support MCP natively (yet).
| Category | Surface | Tools | Description |
|---|---|---|---|
| Portfolio reads | fund | lookup, get_portfolio_summary, get_fund_performance, get_company_detail, get_gp_portfolio, get_active_positions, get_recent_activity, get_recent_marks, get_timeline, query_portfolio_view, read_source_document, portfolio_help |
Query the investment ledger |
| Ledger writes | fund | record_investment, record_carry, record_mark, record_exit, record_conversion, record_stock_split, record_holding_accounting, update_mark, update_transaction, update_lot, void_transaction |
Record and correct portfolio data (requires the backoffice:write scope) |
| Finance reads | cfo | get_entity_summary, get_income_statement, get_cash_position, get_account_activity, get_runway, get_loan_detail, get_debt_summary, get_intercompany_flows, get_unmatched_intercompany, get_pro_forma, get_forecast_vs_actual, get_forecast_run, get_entity_forecast, get_uncategorized, get_close_checklist, list_ledger_categories, reconcile |
Query the internal finance ledger: cash, P&L, loans, forecasts, book close, cross-derivation reconciliation |
| Finance writes | cfo | add_transaction, void_financial_transaction, categorize_transaction, bulk_categorize, add_category, add_loan, update_loan, record_loan_transaction, add_project, record_project_transaction, match_intercompany, generate_forecast, edit_forecast_entry, approve_forecast, close_period, reopen_period |
Maintain the finance ledger: categorization, loans/projects, forecasting, book close (require backoffice:write) |
| Drive reads | shared (every mount) | search_drive, list_folder, read_document, get_file_path, list_zip_contents |
Search and read files in the Echelon Master Folder |
| Gmail reads | shared (every mount) | search_inbox, get_email |
Read the documents@echelon.xyz inbox |
| Grants discovery | shared (every mount) | token_info |
Inspect the session's OAuth grants and which tools they gate — call before planning a workflow that ends in a mutation |
| Skills & SOPs | shared (every mount) | list_skill_categories, list_skills, get_skill |
Operational procedures — tiered discovery: categories → skills → SOP |
| Config | shared (every mount) | get_reference, list_reference |
Reference data (filing taxonomy, Drive structure, AP routing) |
| Feedback | shared (every mount) | submit_feedback |
Report issues or suggest improvements |
| Drive writes | dataroom | write_to_drive, rename_file, move_file, trash_file, create_folder |
Write files in the Echelon Master Folder (require backoffice:write) |
| Document filing | dataroom | file_attachment, file_document, extract_zip_attachment, resolve_filing_target |
Download email attachments and file to Drive |
| Gmail actions | dataroom | label_email, send_email |
Label/archive inbox mail; send internal email (require backoffice:write) |
| Wire instructions | dataroom | generate_wire_instructions |
Fill the bank's wire-instructions template for an entity's ledger account and file the PDF in its Banking folder (staff only; requires backoffice:write) |
list_skill_categories to see skill/SOP domainslookup to find entity codes before querying portfolio dataget_folder_map before searching Driveget_reference('filing-taxonomy') before filing documents"Server not found" after adding .mcp.json — restart Claude Code. The file is only read at session start.
OAuth window doesn't open — check that your browser default is set. The server redirects to the Nora auth server's Google consent screen.
Tools return 401 — your session was revoked or its refresh chain expired. Call any tool again to re-authenticate.
Tools return 403 "insufficient_scope" — your account's grant
ceiling doesn't include the required scope (ledger/Drive writes need
backoffice:write). Ask an admin to raise your ceiling in Lens →
Settings → Users → Edit ceiling, then sign out and back in — a refresh
cannot widen an existing session.