Connect TallyPrime to DuckDB and AI via MCP
Project description
TallyBridge pulls your accounting data out of TallyPrime and into a local DuckDB file. Once synced, TallyPrime can be closed — all queries run against the local database. It also exposes an MCP server so AI assistants (Claude, Cursor) can query your data in plain English.
Highlights
- Offline-first — TallyPrime only needs to run during sync
- Incremental sync — AlterID-based, only fetches what changed
- 27 MCP tools — Query your accounts from Claude, Cursor, or any AI (includes setup diagnostics)
- GST compliance — GSTR-1, GSTR-3B, GSTR-9, ITC reconciliation
- Write-back — Create ledgers and vouchers from Python or AI
- BI integration — Pre-built views for Power BI, Metabase, Superset
- Data export — CSV, Excel, JSON with audit logging
- Setup wizard — Auto-detect TallyPrime and configure interactively
- TallyPrime 7.0 — Auto-detects and uses JSON/JSONEx when available
- Tally.ERP 9 compatible — XML fallback for all versions
Quick Start
1. Install
pip install tallybridge
2. Enable TallyPrime HTTP Server
- Open TallyPrime and load your company
- Press F1 → Help → Settings → Advanced Configuration (TallyPrime 7.0+) or F1 → Settings → Connectivity (older versions)
- Set TallyPrime acts as → Server, Port → 9000
- Save
Tip: Run
tallybridge setupto auto-detect TallyPrime and configure everything interactively.
Can't find the setting?
On some TallyPrime versions: press F12 → Product & Features → Advanced → check Enable ODBC/HTTP. The HTTP server port is configured under F1 → Settings → Connectivity.
See docs/tally-setup.md for full instructions.
3. Sync
tallybridge sync
This fetches all ledgers, groups, stock items, vouchers, and more into a local
tallybridge.duckdb file. You only need TallyPrime running during sync.
After that, close TallyPrime — queries work offline.
4. Query from Python
import tallybridge
q = tallybridge.connect()
digest = q.get_daily_digest()
print(f"Today's sales: {digest.total_sales:,.0f}")
5. Connect to AI (optional)
Add to your Claude Desktop config:
{
"mcpServers": {
"tallybridge": {
"command": "tallybridge-mcp"
}
}
}
See docs/mcp-setup.md for full details.
CLI Reference
# Setup & sync
tallybridge setup # Auto-detect TallyPrime and configure
tallybridge sync # Sync data from TallyPrime
tallybridge sync --full # Force full re-sync
tallybridge sync --watch # Continuous sync every N minutes
tallybridge status # Show sync status per entity
tallybridge doctor # Run diagnostic checks
# Configuration
tallybridge config show # Print current configuration
tallybridge config set KEY VALUE # Set a config value
# Data export
tallybridge export csv --table ledgers # Export table to CSV
tallybridge export csv --table vouchers --where "date >= '2025-01-01'"
tallybridge export excel # Export all tables to Excel
tallybridge export json --table stock_items
# Reports
tallybridge report generate --type daily_digest
tallybridge report generate --type gst_summary --from 2025-01-01 --to 2025-03-31
# MCP & API
tallybridge mcp # Start MCP server (stdio)
tallybridge mcp --http # Start MCP server with HTTP transport
tallybridge serve # Start HTTP API bridge for BI tools
tallybridge serve --port 8080 # Start on custom port
# Other
tallybridge --version # Show version
Python API
Business Summaries
import tallybridge
q = tallybridge.connect()
q.get_daily_digest() # Sales, purchases, balances
q.get_receivables() # Outstanding sales invoices
q.get_payables() # Outstanding purchase invoices
q.get_gst_summary(from_date, to_date) # GST collected, ITC, net liability
q.get_sales_summary(from_date, to_date, group_by="party")
Ledger & Account Queries
q.get_ledger_balance("Cash") # Closing balance
q.get_party_outstanding("Sharma Trading Co") # Full party position
q.get_balance_sheet(to_date="2025-03-31") # Balance sheet
q.get_profit_loss(from_date, to_date) # Profit & Loss
q.get_ledger_account("Cash", from_date, to_date) # Voucher-level GL
Inventory
q.get_stock_summary() # All stock items with quantities
q.get_low_stock_items(threshold=5) # Items below threshold
q.get_stock_aging() # How long stock has been sitting
q.get_stock_item_account("Widget A", from_date, to_date) # Stock movements
GST Reports
q.fetch_gstr1(from_date, to_date) # GSTR-1 outward supply report
q.fetch_gstr3b(from_date, to_date) # GSTR-3B summary return
q.fetch_gstr9(from_date, to_date) # GSTR-9 annual return
q.reconcile_itc(from_date, to_date) # GSTR-2A ITC reconciliation
Search
q.search(query="sharma", limit=10) # Search ledgers, parties, narrations
E-Invoice & E-Way Bill
q.get_einvoice_summary(from_date, to_date) # IRN coverage and missing invoices
q.get_eway_bill_summary(from_date, to_date) # Active, expired, expiring bills
Data Export
from tallybridge.export import DataExporter
from tallybridge.cache import TallyCache
cache = TallyCache("tallybridge.duckdb")
exporter = DataExporter(cache)
# CSV export with filters
exporter.export_csv("ledgers", path="ledgers.csv")
exporter.export_csv("vouchers", where="date >= '2025-01-01'", limit=1000)
# Excel (multi-sheet) — requires pip install tallybridge[excel]
exporter.export_excel(path="tally_data.xlsx")
# JSON
exporter.export_json("stock_items", path="stock.json")
# Memory-efficient chunked export for large datasets
exporter.export_csv_chunked("vouchers", path="vouchers.csv", chunk_size=50000)
Audit Log
# All write operations are automatically logged
q.get_audit_log(from_date="2025-01-01", operation="create")
q.get_audit_log(entity_type="voucher")
TallyBridge Unified Client
The TallyBridge class provides sync, query, validation, and write-back in one object:
import asyncio
import tallybridge
async def main():
async with tallybridge.TallyBridge() as tb:
# Sync data from TallyPrime
await tb.sync()
# Query (proxied to TallyQuery)
digest = tb.get_daily_digest()
balance = tb.get_ledger_balance("Cash")
# Pre-write validation
v = await tb.validate_voucher(
"Sales", "20250101",
[{"ledger_name": "Sales", "amount": "-5000"},
{"ledger_name": "Cash", "amount": "5000"}],
)
print(f"Valid: {v.valid}, Errors: {v.errors}")
# Create with automatic validation
await tb.create_ledger("New Customer", "Sundry Debtors")
await tb.create_voucher(
"Sales", "20250101",
[{"ledger_name": "Sales", "amount": "-5000"},
{"ledger_name": "Cash", "amount": "5000"}],
)
# Skip validation (e.g. for batch imports)
await tb.create_voucher("Sales", "20250101", entries, validate=False)
asyncio.run(main())
Import / Write-Back
Create ledgers and vouchers in TallyPrime from Python:
import asyncio
from tallybridge import TallyConnection, TallyBridgeConfig
# Set TALLYBRIDGE_ALLOW_WRITES=true in your environment
config = TallyBridgeConfig(allow_writes=True)
conn = TallyConnection(config)
# Create a ledger (XML — works on all versions)
xml = TallyConnection.build_ledger_xml("New Customer", "Sundry Debtors", "0")
result = asyncio.run(conn.import_masters(xml))
print(f"Created: {result.created}, Errors: {result.errors}")
# Create a voucher
xml = TallyConnection.build_voucher_xml(
"Sales", "20250101",
[{"ledger_name": "Sales", "amount": "-5000"},
{"ledger_name": "Cash", "amount": "5000"}],
narration="Cash sale",
)
result = asyncio.run(conn.import_vouchers(xml))
print(f"Created: {result.created}")
# Cancel a voucher
xml = TallyConnection.build_cancel_voucher_xml("guid-abc-123", "Sales")
result = asyncio.run(conn.import_vouchers(xml))
asyncio.run(conn.close())
Import Duplicates Control
When importing, control how TallyPrime handles duplicate records:
# Combine opening balances on duplicate (default)
result = asyncio.run(conn.import_masters(xml, import_dups="@@DUPCOMBINE"))
# Modify existing record instead
result = asyncio.run(conn.import_masters(xml, import_dups="@@DUPMODIFY"))
# Skip if already exists
result = asyncio.run(conn.import_masters(xml, import_dups="@@DUPIGNORE"))
Multi-Currency Vouchers
from tallybridge import TallyVoucher, TallyVoucherEntry
v = TallyVoucher(
voucher_type="Sales",
date="20250101",
currency="USD",
forex_amount="100.00",
exchange_rate="83.50",
base_currency_amount="8350.00",
entries=[
TallyVoucherEntry(
ledger_name="Sales",
amount="-8350.00",
currency="USD",
forex_amount="100.00",
exchange_rate="83.50",
),
],
)
Currency fields (currency, forex_amount, exchange_rate, base_currency_amount) are
None by default for INR-only vouchers.
For TallyPrime 7.0+, use JSON import:
conn._detected_version = TallyProduct.PRIME_7
msg = TallyConnection.build_ledger_json("New Supplier", "Sundry Creditors")
result = asyncio.run(conn.import_masters_json(msg))
Configuration
Set via environment variables or a .env file:
| Variable | Default | Description |
|---|---|---|
TALLYBRIDGE_TALLY_HOST |
localhost |
TallyPrime host |
TALLYBRIDGE_TALLY_PORT |
9000 |
TallyPrime HTTP port |
TALLYBRIDGE_TALLY_COMPANY |
(auto-detect) | Company name in TallyPrime |
TALLYBRIDGE_TALLY_ENCODING |
utf-8 |
Request encoding (utf-8 or utf-16) |
TALLYBRIDGE_TALLY_EXPORT_FORMAT |
auto |
Export format: auto, xml, or json |
TALLYBRIDGE_DB_PATH |
tallybridge.duckdb |
Local database file path |
TALLYBRIDGE_SYNC_FREQUENCY_MINUTES |
5 |
Sync interval in --watch mode |
TALLYBRIDGE_VOUCHER_BATCH_SIZE |
5000 |
Vouchers fetched per batch (100–5000) |
TALLYBRIDGE_STRICT_STATUS |
false |
Treat STATUS=0 as error |
TALLYBRIDGE_ALLOW_WRITES |
false |
Enable write-back to TallyPrime |
TALLYBRIDGE_MCP_API_KEY |
(none) | Bearer token for MCP HTTP transport |
TALLYBRIDGE_MCP_TRANSPORT |
stdio |
MCP transport mode: stdio or http |
TALLYBRIDGE_QUERY_CACHE_TTL |
300 |
Query result cache TTL in seconds |
TALLYBRIDGE_SLOW_QUERY_THRESHOLD |
1.0 |
Log queries slower than this (seconds) |
TALLYBRIDGE_EXPORT_CHUNK_SIZE |
5000 |
Rows per chunk for chunked export |
TALLYBRIDGE_CORS_ORIGINS |
* |
Comma-separated CORS origins for HTTP API |
TALLYBRIDGE_LOG_LEVEL |
INFO |
Logging level |
Example .env:
TALLYBRIDGE_TALLY_HOST=localhost
TALLYBRIDGE_TALLY_PORT=9000
TALLYBRIDGE_TALLY_COMPANY=My Company Pvt Ltd
BI Integration
TallyBridge creates 5 pre-built SQL views in DuckDB for BI tool connections:
| View | Description |
|---|---|
v_sales_summary |
Sales and credit note vouchers with amounts |
v_receivables |
Outstanding receivables with overdue days |
v_gst_summary |
GST ledger totals by date |
v_stock_summary |
Stock items with quantities and values |
v_party_position |
Party receivable/payable classification |
Connect from BI tools:
- Power BI — DuckDB ODBC driver
- Metabase — Native DuckDB driver
- Superset — DuckDB connector
- Excel — ODBC or
tallybridge export csv - Any HTTP client —
tallybridge serveREST API (requirespip install tallybridge[serve])
pip install tallybridge[serve]
tallybridge serve --port 8080
# GET http://localhost:8080/views/v_sales_summary
# POST http://localhost:8080/query {"sql": "SELECT * FROM mst_ledger"}
See docs/bi-integration.md for detailed connection guides.
MCP Tools (27 read-only + 3 write-back via Python API)
Read-Only Tools
| Tool | Description |
|---|---|
get_tally_digest |
Complete business summary |
get_ledger_balance |
Closing balance of any ledger |
get_receivables |
Outstanding sales invoices |
get_payables |
Outstanding purchase invoices |
get_party_outstanding |
Full position with one party |
get_sales_summary |
Sales by day/week/month/party |
get_gst_summary |
GST collected, ITC, net liability |
search_tally |
Search ledgers, parties, narrations |
get_sync_status |
Last sync time and record counts |
get_low_stock |
Items at or below quantity threshold |
get_stock_aging |
Stock aging by day buckets |
get_cost_center_summary |
Income/expense by cost centre |
get_balance_sheet |
Balance sheet grouped by assets/liabilities |
get_profit_loss |
P&L grouped by income/expense |
get_ledger_account |
Voucher-level general ledger |
get_stock_item_account |
Quantity movements for a stock item |
query_tally_data |
Run custom SQL on local cache |
get_sync_errors |
Recent sync errors |
get_gstr1 |
GSTR-1 outward supply data |
reconcile_itc |
ITC reconciliation (GSTR-2A) |
get_gstr9 |
GSTR-9 annual return data |
get_einvoice_status |
E-invoice IRN coverage |
get_eway_bill_status |
E-Way Bill status |
export_data |
Export cached data as CSV or JSON |
get_audit_log |
Audit log of write operations |
tally_check_connection |
Test TallyPrime connectivity and version |
tally_setup_guide |
Step-by-step setup instructions |
Write Tools (requires TALLYBRIDGE_ALLOW_WRITES=true)
Note: Write tools are available via the Python API (
TallyBridgeclient class) and are planned for MCP exposure in a future release.
| Tool | Description |
|---|---|
create_ledger |
Create a new ledger |
create_voucher |
Create a new voucher |
cancel_voucher |
Cancel a voucher by GUID |
Compatibility
| Product | Support |
|---|---|
| TallyPrime 7.0+ | Full support (JSON/JSONEx API, import, base64 encoding) |
| TallyPrime 4.0+ | Primary target (XML sync, Connected GST) |
| TallyPrime 1.x–3.x | Supported (XML only) |
| Tally.ERP 9 | Best-effort (LEDGERENTRIES.LIST fallback) |
TallyBridge auto-detects your Tally version on first sync. See docs/tally-setup.md for the full feature compatibility matrix.
How It Works
TallyPrime (port 9000) Your Machine
┌─────────────────┐ ┌──────────────────────┐
│ Accounting data │────→│ TallySyncEngine │
│ (XML/JSON HTTP) │ │ TallyXMLParser │
└─────────────────┘ │ TallyJSONParser │
│ │ │
│ ▼ │
│ tallybridge.duckdb │
│ (local, offline) │
│ │ │
│ ┌─────┼──────┐ │
│ │ │ │ │
│ Query MCP HTTP API │
│ (Python) (AI) (BI) │
└──────────────────────┘
- Sync — Pull data from TallyPrime via HTTP (XML or JSON/JSONEx on 7.0+)
- Cache — Store in local DuckDB with content hash drift detection
- Query — Read from local file — TallyPrime doesn't need to be running
- Import — Write back to TallyPrime when
TALLYBRIDGE_ALLOW_WRITES=true - MCP — Expose data to AI assistants via stdio or HTTP (27 tools, includes setup diagnostics)
- Export — CSV, Excel, JSON with audit logging
Development
git clone https://github.com/Vege-Direc/TallyBridge.git
cd tallybridge
uv sync --extra dev
uv run pytest
No TallyPrime installation needed — tests use a mock HTTP server.
Optional Dependencies
pip install tallybridge[serve] # FastAPI HTTP API bridge
pip install tallybridge[excel] # Excel export (openpyxl)
pip install tallybridge[cloud] # Supabase cloud sync (future)
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tallybridge-0.2.0.tar.gz.
File metadata
- Download URL: tallybridge-0.2.0.tar.gz
- Upload date:
- Size: 261.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5f95d240b5e1a852266f44296deea8a6f07cea24a520a8207b256ef9cbfab1e
|
|
| MD5 |
0c35903e86a9517bc18dc764b7f28223
|
|
| BLAKE2b-256 |
e76c87576c0953c5ec306b06276a024eec0a87eb7ad101a4047f52c07858e776
|
Provenance
The following attestation bundles were made for tallybridge-0.2.0.tar.gz:
Publisher:
publish.yml on Vege-Direc/TallyBridge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tallybridge-0.2.0.tar.gz -
Subject digest:
b5f95d240b5e1a852266f44296deea8a6f07cea24a520a8207b256ef9cbfab1e - Sigstore transparency entry: 1420248690
- Sigstore integration time:
-
Permalink:
Vege-Direc/TallyBridge@7ce6c02c0d7df462416bb874153918219009702e -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Vege-Direc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7ce6c02c0d7df462416bb874153918219009702e -
Trigger Event:
push
-
Statement type:
File details
Details for the file tallybridge-0.2.0-py3-none-any.whl.
File metadata
- Download URL: tallybridge-0.2.0-py3-none-any.whl
- Upload date:
- Size: 91.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f8e07dfa732afe050f5413c5b6e283c39c6b1fef678ecc8e8fd03d196064c84
|
|
| MD5 |
c626ef2abb65d70e7a26e1358500975c
|
|
| BLAKE2b-256 |
c45497b02fd027caa32d90fa828b4b0e560fba61733cde4a2685d7e6bed99a42
|
Provenance
The following attestation bundles were made for tallybridge-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on Vege-Direc/TallyBridge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tallybridge-0.2.0-py3-none-any.whl -
Subject digest:
7f8e07dfa732afe050f5413c5b6e283c39c6b1fef678ecc8e8fd03d196064c84 - Sigstore transparency entry: 1420248810
- Sigstore integration time:
-
Permalink:
Vege-Direc/TallyBridge@7ce6c02c0d7df462416bb874153918219009702e -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Vege-Direc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7ce6c02c0d7df462416bb874153918219009702e -
Trigger Event:
push
-
Statement type: