Content
# 1c-odata-mcp — Connecting 1C:Enterprise to AI (Claude) via OData
[](https://www.npmjs.com/package/1c-odata-mcp)
[](https://github.com/evilbruce666/1c-odata-mcp/actions/workflows/ci.yml)
[](LICENSE)
[](https://nodejs.org)
<p align="center">
<img src="docs/assets/demo-debtors.svg" alt="Dialogue with Claude: on the question «who owes the most» comes a list of debtors and the result from 1C" width="720">
</p>
> 🇬🇧 **In short:** an MCP server that connects 1C:Enterprise to Claude over its standard OData interface. Ask your accounting database in plain language (debtors, sales, taxes, cash flow) and get the number back; opt-in, preview-gated write. Read-only by default. Run with `npx -y 1c-odata-mcp`. Works with any 1C where OData is published — cloud, SQL or local file base.
**MCP Server (Model Context Protocol) for 1C:Enterprise via standard OData interface.** Allows working with 1C data in natural language directly from AI assistant **Claude** (and any MCP client): ask about counterparties, documents, balances, receivables, sales and cash flow — and with explicit enablement, also create/change directories and documents, conduct, register payments.
If you were looking for **how to connect 1C to neural network / AI**, a ready-made **1C OData connector** or **1C integration with Claude** without programming on the 1C side — this is it.
- 🔌 Any **MCP client**: Claude Desktop and Claude Code, Cursor, VS Code (Continue/Cline), JetBrains — and **local models** (Ollama, LM Studio)
- 🔐 **Data stays with you** — the server is a local process, only accesses your database; with a local model, data does not leave the network
- 🏢 Multiple information bases and organizations (legal entities) simultaneously
- 🔒 **Read-only by default**; writing — through a double safeguard and preview
- 🚀 Launch with one command: `npx -y 1c-odata-mcp`
- ⚙️ Nothing is installed on the 1C side — a published **OData** is sufficient (no COM connection, no access to SQL)
> **📘 Installation, OData publication and connection to Claude — step-by-step in [docs/CONNECTING.md](docs/CONNECTING.md).** This section is about the project itself, capabilities and limitations.
---
## Suitable for any of your 1C options
The connector communicates with 1C **only through OData**. If it is enabled — everything works the same, **regardless of how your database is deployed**:
| Your 1C | What is needed to make it work | Complexity |
|---|---|---|
| **Cloud / hosting** (Scloud, 1cFresh, 1C rental) | OData includes provider — with a checkbox in the cabinet or by request | 🟢 low |
| **Server with SQL** (PostgreSQL / MS SQL) | publish the database on Apache/IIS + enable OData | 🟡 medium |
| **Local file database** (`.1CD`) | the same + give the web server rights to the database folder | 🟡 medium |
| **No web server / access to configurator** | OData is not available → another transport is needed | 🔴 |
The type of storage (file or SQL) itself does not change the complexity — it is only important that the OData web publication is raised. **Without enabled OData, the connector cannot work** (it does not use COM and does not directly access SQL).
➡️ Step-by-step instructions for each option — in **[docs/ODATA-SETUP.md](docs/ODATA-SETUP.md)**. Base address, account and connection to Claude — in **[docs/CONNECTING.md](docs/CONNECTING.md)**.
---
## Why is this needed
Raw 1C OData is hundreds of technical `EntitySet` with Cyrillic names (`Catalog_Контрагенты`, `Document_РеализацияТоваровУслуг`, `AccumulationRegister_ТоварыНаСкладах`) and GUID keys. It is impossible to work with this from a chat, and writing your own code for each report takes a long time.
The server hides all the technical details behind understandable tools. You ask in a natural language — AI chooses the right tool, accesses your database's OData and returns a ready-made answer. For a manager — a quick insight into the business, for an accountant — routine document creation under control.
---
## Capabilities
**Analytics and reading (by default):**
- «Show receivables» → balance of account 62 by counterparties
- «History by counterparty Romashka» → all documents and settlements
- «Balances in the warehouse» → quantity and amount by nomenclature
- «Sales for May», «cash flow for the quarter» → turnover for the period
- search for counterparties and documents, object cards, database map
**Actions (with enabled writing, always with preview and confirmation):**
- «Create counterparty LLC Romashka, TIN …, phone, email, settlement account, director»
- «Issue an invoice to the buyer for 3 items at 1000» → draft document
- «Create a receipt from the supplier and implement it to the buyer», «conduct the document» → 1C generates postings
- changing details, document lines, payments, service acts
The full list is in the [Tools](#tools) section.
---
## Example dialogue
```text
You: Who owes the most and how much?
Claude: (calls get_debtors) Top debtors today:
1. LLC «Romashka» — 1 240 500 ₽
2. IP Ivanov — 318 000 ₽
3. LLC «Berezka» — 94 050 ₽
Total on account 62: 1 800 000 ₽.
You: Create a new buyer LLC «Voskhod», TIN 7701234567, and issue an invoice for 10 items at 2500.
Claude: (dry-run) Will be created:
• Counterparty «LLC Voskhod» (TIN 7701234567)
• Invoice to the buyer for 25 000 ₽ (10 × 2500)
Confirm creation?
You: Yes
Claude: Ready: counterparty 00-000123, invoice № … (draft, not conducted).
```
---
## Quick start
> **First time hearing about MCP?** This is an open protocol (Model Context Protocol) by which an AI assistant connects to external tools. Here, the tool is your 1C: the assistant calls the necessary functions and returns the answer. Nothing needs to be programmed — three steps below.
1. **Publish OData** in 1C and add the necessary objects to «Composition» (details — [docs/CONNECTING.md](docs/CONNECTING.md); if OData is not enabled — [docs/ODATA-SETUP.md](docs/ODATA-SETUP.md)).
2. **Prescribe the server** in Claude Desktop (`claude_desktop_config.json`), substituting the address and account details:
```json
{
"mcpServers": {
"1c-odata": {
"command": "npx",
"args": ["-y", "1c-odata-mcp"],
"env": {
"ODATA_BASE_URL": "https://<server>/<base>/odata/standard.odata/",
"ODATA_USERNAME": "...",
"ODATA_PASSWORD": "..."
}
}
}
}
```
3. **Restart Claude Desktop** (completely) and ask: «check connection with 1C».
Full setup (OData address by platforms, authorization, launch from sources, Claude Code, error diagnostics) — in **[docs/CONNECTING.md](docs/CONNECTING.md)**.
---
## Tools
All tools have an optional parameter **`database`** (which 1C database — see `list_databases`); analytical tools also have **`organization`** (filter by legal entity — see `list_organizations`).
**Reading and analytics:**
| Tool | What does it do |
|---|---|
| `list_databases` / `list_organizations` | List of databases / organizations (for `database` / `organization` parameters) |
| `list_entities` / `describe_entity` | Database object map and fields of a specific object (from `$metadata`) |
| `find_counterparty` / `get_counterparty` | Counterparty search (by name/TIN) and its card |
| `search_documents` / `get_document` | Document search and document with tabular part |
| `get_debtors` / `get_inventory` | Receivables (account 62) / inventory balances (account 41/10/43) |
| `get_sales` / `get_cashflow` | Sales for the period / cash flow (bank + cash) |
| `get_customer_history` / `get_supplier_history` | Settlement history with the buyer / supplier |
| `health_check` | Connection and authorization check |
**Writing (✍️ requires enablement, works through dry-run → `confirm=true`):**
| Tool | What does it do |
|---|---|
| `create_counterparty` | Counterparty (+ phone/email/address/OGRN) |
| `create_bank_account` / `create_contact_person` | Settlement account (bank by BIC) / contact person (director) |
| `create_nomenclature` | Nomenclature |
| `create_contract` | Contract (type, currency, price type) |
| `create_invoice` | Invoice to the buyer (not conducted) |
| `create_purchase` / `create_shipment` | Receipt from the supplier / implementation to the buyer |
| `create_act` | Service implementation (act) |
| `create_payment` | Payment from the buyer (receipt to the settlement account) |
| `update_counterparty` / `update_nomenclature` / `update_entity` | Changing details (PATCH) |
| `update_document_lines` / `add_document_line` / `remove_document_line` | Editing document lines |
| `post_document` | Conduct / cancel conduct (1C generates postings) |
| `mark_for_deletion` | Mark for deletion / remove mark (soft deletion) |
All tools are tested on a live database **1C:Accounting of enterprise 3.0**.
---
## Security
**By default, the server is read-only.** Writing is enabled deliberately through **two independent safeguards**:
1. **Global switch** `READ_ONLY=false`.
2. **Per-base flag** `ODATA_DB_<NAME>_WRITABLE=true` — databases without it remain read-only even with the global switch off. This way, you can enable writing to one database (e.g., IP) and protect others (e.g., LLC).
Additionally, when writing:
- **Dry-run by default** — the tool first shows what it will create and only writes when `confirm=true`;
- **Soft deletion** — `mark_for_deletion` sets a mark (like in 1C); there is no hard `DELETE`;
- on the 1C side, only the necessary objects are included in the "OData Composition," and the 1C user must have write permissions.
**Data privacy.** The server is a local process on your machine: it accesses only your 1C database (via Basic authentication) and provides data to your MCP client. There are no third-party project servers in the chain. If you use a **local model** (Ollama, LM Studio), 1C data does not leave your network. Secrets are only from `.env` (or the `env` block of the config); the password and authorization header do not get into the logs.
How to enable writing — [docs/CONNECTING.md → Enabling writing](docs/CONNECTING.md#enabling-writing-optional).
---
## Multiple databases and multiple organizations
These are different cases:
- **Multiple separate databases** (different OData addresses) — one server serves all; the database name is passed as a parameter `database`. Configuration in `.env` — see [docs/CONNECTING.md](docs/CONNECTING.md#multiple-1c-databases). Example request: "compare revenue for buh and torg for May".
- **Multiple organizations (legal entities) in one database** — a separate connection is not needed, the `organization` filter works. Example: "balances for the organization Romashka".
---
## Limitations
It's worth knowing in advance:
- **Published OData is required.** The server works only through the standard OData 1C interface. It does not use or require direct access to SQL, COM connections, or 1C server files.
- **The object must be in "OData Composition".** If the object is not published, the tool will return a polite hint with the object name and the path to add it. Publish as needed.
- **Target configuration — Enterprise Accounting 3.0.** Object names are auto-determined from `$metadata`, but analytics (accounts receivable/balances) and document accounting are calculated based on the BP 3.0 chart of accounts. For UT/ERP and custom configurations, reading directories/documents works, but accounting analytics may require refinement.
- **Documents are created unposted.** Postings are formed by 1C itself during posting (`post_document` or manually) — the server does not draw postings directly.
- **Payment (`create_payment`).** The document is created and posted, but accounting postings Dt 51 Kt 62 are formed only if the organization's bank account has a set account (51) — this is a 1C setting.
- **OGRN and other additional details.** They are written only if the corresponding "additional detail" is set in the database (Administration → Additional details). Otherwise, the tool honestly reports that there is nowhere to write.
- **Address** is written as a text representation (not a structured FIAS address).
- **Pagination and limits.** To avoid downloading thousands of rows, a page size and protective maximum (`ODATA_PAGE_SIZE` / `ODATA_MAX_ROWS`) apply; large queries are truncated with a mark.
---
## How it works
A local process on Node.js communicates with the client via the MCP protocol through **stdio** and with 1C via HTTP to OData (Basic authentication). Stack: **Node.js 20+**, **TypeScript** (strict), official `@modelcontextprotocol/sdk`, native `fetch`, `zod` (validation), `pino` (logs to stderr), `fast-xml-parser` (parsing `$metadata`).
The object map is built automatically from the database's `$metadata` and cached; queries are assembled by a type-safe builder. Multiple databases — each has its own client and metadata cache.
```
src/
index.ts entry point
context.ts database registry: Connection (client + $metadata cache) + ServerContext
mcp/server.ts MCP SDK initialization, tool registration, stdio
odata/ client, query builder, pagination, $metadata parsing, analytics,
reference resolvers, error handling, publication check
tools/ tools: meta, counterparties, documents, registers, write
config/ configuration (.env, multi-database) and name/account mapping
types/ OData types and domain types
```
---
## Technical notes
- **`+` vs `%20` in OData 1C.** 1C does not decode `+` to a space within `$filter` (returns 400), so the query string is collected via `encodeURIComponent` (space → `%20`), not `URLSearchParams`.
- **Document accounting** are not automatically substituted through OData (this is done by the 1C form when choosing a nomenclature) — the server takes them from the "Accounting accounts for nomenclature" register, with a fallback to standard chart of accounts codes.
- **Logs and stderr.** `stdout` is occupied by JSON-RPC, so logs go to `stderr` — but only in the terminal. Under the MCP client (when `stdin` is a pipe), logs are written to a file `<tmpdir>/1c-odata-mcp/server.log` to avoid breaking clients that interpret any output in `stderr` as a fatal error. Return logs to `stderr`: `MCP_LOG_STDERR=1`.
---
## Frequently Asked Questions (FAQ)
**Claude "hangs" / request times out.**
If even small calls (`health_check`, `list_databases`) hang — it's almost always **stuck MCP process in Claude Desktop**, not the database. Completely restart the application (Cmd+Q and again). A healthy `health_check` responds within a second.
**I specify a different database, but it's "unavailable" / only one responds.**
The `database` parameter is the **name** from `list_databases` (field `name`, e.g., `ooo`), not the "human" name (label, e.g., "LLC Romashka"). Refer to the name.
**The answer is empty / "0 objects".**
The **OData Composition** is not configured — add the necessary objects to 1C (see [docs/ODATA-SETUP.md](docs/ODATA-SETUP.md) and [docs/CONNECTING.md](docs/CONNECTING.md)).
**It's slow.**
This is the latency of your **1C / hosting**, not Claude: annual queries on "noisy" databases can take 10–30 seconds. Ask for a narrower period (quarter/month) — the answer comes in seconds.
**Do I need access to the database SQL or COM?**
No. The server uses only **OData** — nothing is installed inside 1C; it does not directly access SQL.
**Is it safe to let AI access the combat database?**
By default, **read-only**. Writing is enabled by two independent flags and works through a dry run with confirmation. There is no physical deletion (only marking). See [Security](#security).
**Which 1C is suitable?**
Any that has OData enabled — cloud (Scloud/1cFresh), server with SQL, or local file database. Step-by-step for each case — [docs/ODATA-SETUP.md](docs/ODATA-SETUP.md).
---
## License
[MIT](LICENSE). The project is open — use, fork, submit issues, and PRs: <https://github.com/evilbruce666/1c-odata-mcp>.
> ⭐ If the connector was useful — **put a star on GitHub** and tell us in [Discussions](https://github.com/evilbruce666/1c-odata-mcp/discussions) what questions you are asking your 1C. This is the best motivation to develop the project.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available