About
Fyi — Model Context Protocol server
README
Give AI assistants full access to your accounting practice's FYI platform — clients, jobs, tasks, documents, time and billing — through the Model Context Protocol.
CI Python 3.11+ License: MIT MCP
Ask Claude (or any MCP client) things like:
"Which jobs for Riverbank Trading are still In Progress, and who's the manager?" "Summarise this week's time entries by staff member." "Find the latest VAT letter we filed for client X and give me a download link." "Create a task for Emma to chase the missing bank statements, due Friday."
Highlights
- 52 tools — full coverage of the documented FYI External API: clients, groups, contacts, relationships, jobs, tasks, documents, cabinets, categories, tags, comments, time, rates, invoices, users, roles, notifications, custom fields.
- No OAuth — FYI uses static API keys: three env vars and you're connected.
- Two run modes: local stdio for one user, or hosted streamable HTTP where every connecting user sends their own FYI keys — one server, many practices, zero shared credentials.
- Safe by design: 42 read tools; the 10 write tools are clearly marked, and the hosted server physically cannot fall back to the host's keys.
- LLM-friendly responses: FYI's verbose payloads are trimmed to the fields that matter, so answers stay fast and cheap.
- Tiny footprint: Python, 3 dependencies (
mcp,httpx,python-dotenv).
Quick start (local)
Requires uv and FYI API keys (FYI portal → Automations → Apps → Custom Applications; one-time approval via [email protected] — details in docs/local_setup.md).
git clone https://github.com/saiganeshreddy7/fyi-mcp-server.git
cd fyi-mcp-server
uv sync
cp .env.example .env # add FYI_ACCESS_ID, FYI_ACCESS_SECRET, FYI_REGION (uk|au)
uv run python scripts/smoke_read.py # read-only live check: expect ALL PASS
Connect it to Claude Code:
claude mcp add fyi -s user -- uv run --directory "$(pwd)" main.py
Claude Desktop, Codex, Cursor and other clients: docs/host.md.
Hosted mode (one server, many users)
MCP_TRANSPORT=http MCP_HOST=0.0.0.0 uv run main.py # serves /mcp
In HTTP mode the server holds no keys. Each client sends its own on every request:
| Header | Required | Value |
|---|---|---|
x-fyi-access-id |
yes | Your FYI Access ID |
x-fyi-access-secret |
yes | Your FYI Access Secret |
x-fyi-api-user-email |
no | FYI user to act as |
x-fyi-region |
no | uk (default) | au | uk-preprod | au-preprod |
A request without keys gets a helpful error — never someone else's data.
Optionally pin the public hostname with MCP_ALLOWED_HOSTS=your-host.com
(anything else then gets a 421). Deploy to Render in ~10 minutes with
docs/deploy.md.
Tools
| Domain | Read | Write |
|---|---|---|
| Clients (FYI "entities") | list_clients · get_fyi_client · list_client_groups · get_client_group · list_contacts · list_entity_relationships · get_entity_relationship |
upsert_client · upsert_contact · upsert_group · upsert_entity_metadata |
| Jobs | list_jobs · get_job · list_job_states · get_job_state · list_job_types · get_job_type |
upsert_job |
| Tasks | list_tasks · get_task · list_task_statuses |
upsert_task |
| Documents | list_documents · get_document · get_document_by_external_id · get_document_download_url · list_cabinets · get_cabinet · list_categories · get_category · list_tags · list_comments |
create_document_record · upsert_cabinet · upload_document_file |
| Time | list_time_entries · get_time_entry · list_time_types · get_time_type |
upsert_time_entry |
| Billing | list_rates · get_rate · list_invoices* · get_invoice* |
— |
| Practice | list_users · list_user_roles · get_user_role · list_employees · get_employee · list_notifications · list_custom_fields · get_custom_field |
— |
* Invoices require the FYI Elite plan.
Every tool is documented with example calls and responses in docs/tools.md.
Documentation
| Guide | What it covers |
|---|---|
| docs/local_setup.md | Install, get FYI keys, run locally, troubleshoot |
| docs/deploy.md | Deploy to Render step by step |
| docs/host.md | Connect Claude Desktop / Claude Code / Codex / Cursor — local and hosted |
| docs/tools.md | Every tool with example calls and responses |
How credentials work
LOCAL (stdio) HOSTED (streamable HTTP)
┌──────────────┐ ┌────────────┐ x-fyi-* headers ┌────────────┐
│ Claude app │── launches ──┐ │ Any MCP │──── per request ──▶│ Server │
└──────────────┘ ▼ │ client │ │ (no keys!) │
┌────────────┐ └────────────┘ └─────┬──────┘
│ Server │ each user's own keys │
│ reads .env │ ▼
└─────┬──────┘ FYI API (uk/au)
▼
FYI API (uk/au)
The two paths never mix: in HTTP mode the env fallback is disabled outright, so a tenant can only ever act with keys they supplied themselves.
FYI API notes (hard-won)
- Every FYI call is
POST {base}/{resource}with an RPC envelope:{"metadata": {"action": {"value": "list|get|upsert"}, "data": {...}}}. - Clients live at
/entity— there is no/clientendpoint. - Multi-value filters are comma-separated ID strings (
"1,2,3"); the time entryjobsfilter wants single-quoted UUIDs ("'uuid1','uuid2'"). - Upserts update when
id/source_idmatches, otherwise create. - Documents: record in FYI, file in S3 — download is get →
version_id→downloadUrl; upload is upsert →uploadForm→ presigned S3 POST. - Custom fields put the type in the URL path (
/custom-fields/{applies_to}). - FYI's docs point Job Type / User Role list requests at
/rateby mistake — the real endpoints (/job-type,/user-role) were verified live. Job Templates has no working endpoint and is the one documented resource not implemented. listresponses cap the reportedtotalat 10,000.- No official rate limits — "fair and sensible use".
Testing philosophy
- All 42 read tools are verified against a live UK production FYI account.
- Write tools follow FYI's documented formats and are code-reviewed, but are never run automatically — nothing in the repo or CI mutates an FYI account. Test writes against an FYI preprod/staging account.
- CI is fully offline: compile + "server builds and all 52 tools register".
Contributing
Issues and PRs are very welcome — see CONTRIBUTING.md for setup, the add-a-tool recipe, and testing rules, and SECURITY.md for reporting vulnerabilities privately. Good first contributions: new FYI endpoints as they appear, better response trimming, more client connection guides.
License & disclaimer
MIT. This is an unofficial, community-built integration — not affiliated with, endorsed by, or supported by FYI. It talks to live accounting data: keep your keys secret, prefer read-only usage until you trust your setup, and test write operations in a staging account first.
Installing Fyi
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/saiganeshreddy7/fyi-mcp-serverFAQ
Is Fyi MCP free?
Yes, Fyi MCP is free — one-click install via Unyly at no cost.
Does Fyi need an API key?
No, Fyi runs without API keys or environment variables.
Is Fyi hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Fyi in Claude Desktop, Claude Code or Cursor?
Open Fyi on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectAmap Maps Mcp Server
MCP server for using the AMap Maps API
by duxiaohuiSupabase
Database, auth and storage
by SupabaseEverything
Reference / test server with prompts, resources, and tools.
Git
Tools to read, search, and manipulate Git repositories.
Sequential Thinking
Dynamic and reflective problem-solving through thought sequences.
Time
Time and timezone conversion capabilities.
Compare Fyi with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
