AutoTally has one central design fact: everything that touches Tally is .NET, and everything agent-facing is TypeScript. The two halves meet at a single HTTP/JSON contract — the Bridge REST API.
TS (agent-facing): mcp-server / cli / relay ──HTTP/JSON──▶ Bridge REST API
.NET (Tally-facing): Bridge ─▶ Core ─▶ TallyConnector ──XML──▶ Tally (:9000)
The contract is the source of truth
openapi.yaml is shared by both stacks. When an endpoint or DTO changes, all three
change in lockstep: the OpenAPI spec, the .NET side, and the hand-maintained
TypeScript types that mirror it.
Why split it this way
- The .NET side calls the upstream
TallyConnectorlibrary in-process, so it can speak Tally's XML dialect without reimplementing it. - The TypeScript side owns everything an agent sees — the MCP tools, the CLI, and the relay — where the ecosystem is richest.
Layers
| Layer | Stack | Responsibility |
|---|---|---|
| MCP server | TypeScript | Exposes Tally operations as typed agent tools |
| CLI | TypeScript | Human + scripting access to the same contract |
| Bridge REST API | .NET | The one HTTP/JSON contract |
| Core | .NET | Maps DTOs to connector calls |
| TallyConnector | .NET | The Tally XML/HTTP protocol layer |
Read Write safety for the guardrails that live along the write path.