tally-mcp-server
Exposes TallyPrime accounting data to MCP-compatible clients via Tally's XML HTTP API. Enables listing companies, ledgers, groups, stock items, day book vouchers, and outstanding balances.
README
tally-mcp-server
An MCP (Model Context Protocol) server that exposes TallyPrime data to any MCP-compatible client (Claude Desktop, Claude Code, etc.) over Tally's classic XML HTTP API - the integration method supported by every Tally.ERP 9 / TallyPrime release.
Available tools
| Tool key | What it returns |
|---|---|
list_companies |
Companies known to the running Tally instance |
list_ledgers |
All ledger accounts, with opening/closing balances |
list_groups |
All accounting groups (chart-of-accounts categories) |
list_stock_items |
All inventory items, with closing qty/rate/value |
day_book |
Vouchers posted between two dates (fromDate, toDate) |
outstanding_balances |
Ledgers in a group with closing balance (receivables/payables) |
How it talks to Tally
TallyPrime can act as an HTTP server and accept an XML "envelope":
<ENVELOPE><HEADER>...</HEADER><BODY>...</BODY></ENVELOPE>. Two request
shapes are used here:
- Built-in reports (e.g.
list_companies) - just name the report, no TDL needed. - Custom collections (everything else) - an inline TDL
<COLLECTION>naming a native Tally object type (Ledger,Group,StockItem,Voucher) and the fields to fetch. This is the standard technique for "give me all X" pulls and is what most third-party Tally integrations use.
Docs: https://help.tallysolutions.com/developer-reference/introduction/integration-with-tallyprime/
1. Enable Tally as an HTTP server
In TallyPrime: F1 (Help) → Settings → Connectivity → Client/Server
configuration → set "TallyPrime acts as" to Server, and note the port
(default 9000).
2. Install
npm install
cp .env.example .env
# edit .env if your Tally isn't on localhost:9000
3. Run standalone (for testing)
npm start
The server speaks MCP over stdio, so running it directly won't print
anything to stdout - that's expected. Ctrl+C to stop.
4. Connect it to an MCP client
Example Claude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"tally": {
"command": "node",
"args": ["/absolute/path/to/tally-mcp-server/src/index.js"]
}
}
}
Project structure
src/
├── index.js # MCP server bootstrap - wires everything together
├── config.js # Reads TALLY_HOST / TALLY_PORT / etc. from .env
├── tally/
│ ├── client.js # Generic transport: builds/sends the XML envelope,
│ │ # parses the XML response into a plain object
│ └── endpoints/
│ ├── index.js # Registry - list every supported Tally API here
│ ├── companies.js # Built-in report example
│ ├── ledgers.js # Custom TDL collection example
│ ├── groups.js
│ ├── stockItems.js
│ ├── dayBook.js # Collection example with runtime params (dates)
│ └── outstanding.js # Collection example with a filter
└── tools/
└── index.js # Turns every registered endpoint into an MCP tool
The split matters:
tally/client.jsonly knows how to transport a request (build the XML envelope, POST it, parse the XML response, surface errors). It has zero Tally-report-specific knowledge.tally/endpoints/*.jseach describe one Tally API: what to request (request: { kind, ... }), any input parameters it needs, and how to turn Tally's parsed XML into a clean shape.tools/index.jsloops over the endpoint registry and callsserver.tool(...)for each one - so a new endpoint becomes a working MCP tool automatically, with no changes to the server or client code.
Adding a new Tally API
Say you want to add "List Cost Centres":
-
Create
src/tally/endpoints/costCentres.js, modeled ongroups.js:import { asArray } from "../client.js"; export default { key: "list_cost_centres", title: "List Cost Centres", description: "Returns cost centres from TallyPrime.", inputSchema: {}, request: { kind: "collection", collectionName: "MCP CostCentres", type: "CostCentre", fetch: ["NAME", "PARENT", "CATEGORY"], }, parseResponse(parsedXml) { const entries = asArray(parsedXml?.ENVELOPE?.COSTCENTRE); return entries.map((e) => ({ name: e["@_NAME"] ?? e.NAME, parent: e.PARENT, category: e.CATEGORY, })); }, }; -
Register it in
src/tally/endpoints/index.js(import + add to theendpointsarray). -
Restart the server.
list_cost_centresis now a callable MCP tool - nothing else needs to change.
If an endpoint needs runtime parameters (dates, a filter value, etc.),
add zod validators to inputSchema and read them in request.staticVariables(params)
and/or request.buildFilterValue(params) - see dayBook.js and
outstanding.js for examples.
Troubleshooting
- "Could not reach TallyPrime" - Tally isn't running, isn't configured
as a server, or
TALLY_HOST/TALLY_PORTin.envdon't match. - Empty results or
<LINEERROR>- the report/collectionidor TDL field names may need adjusting for your Tally release or company configuration. Turn on Tally's "Test Client" / check the Tally log screen while a request runs to see exactly what it received. - Unexpected shape in
list_companies-parseResponse()tries a few likely XML shapes and falls back to returning the raw parsed payload with awarningfield so you can see exactly what Tally sent back and adjust the parser. - Numbers coming back as strings/numbers inconsistently - Tally's XML
doesn't strongly type values;
fast-xml-parserdoes its best guess. If you need guaranteed types, cast explicitly insideparseResponse().
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.