Nora Back Office — Setup Guide

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)

Surfaces

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.


Claude Code (CLI / Desktop)

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.

Claude.ai (Web)

  1. Go to any conversation → click the plug icon → "Add integration"
  2. Paste the surface URL for your use case — pick ONE from the table above, e.g. 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)
  3. Authenticate with your @echelon.xyz Google account
  4. The server appears as a connected integration for all conversations

Cursor

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.

Windsurf / Cline / other MCP clients

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.

ChatGPT / Gemini

Not supported — these platforms don't support MCP natively (yet).


Available tool categories

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)

Quick start for agents

  1. Call list_skill_categories to see skill/SOP domains
  2. Call lookup to find entity codes before querying portfolio data
  3. Call get_folder_map before searching Drive
  4. Call get_reference('filing-taxonomy') before filing documents

Troubleshooting

"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.