Skip to main content

Platform42 MCP Proxy for 1C

Python MCP-прокси между MCP-клиентами и HTTP-сервисом 1С. Репозиторий содержит только Python proxy-server, без 1С-расширения/конфигурации.

Основано на src/py_server проекта https://github.com/vladimir-kharin/1c_mcp.

Режимы выбора базы

1. Fixed-base: MCP_ONEC_URL задан

Если MCP_ONEC_URL задан, прокси работает только с этой публикацией 1С:

MCP_ONEC_URL=https://host/base
MCP_ONEC_USERNAME=Admin
MCP_ONEC_PASSWORD=secret
MCP_ONEC_SERVICE_ROOT=mcp

Мы рекомендуем создать служебного пользователя OData через Администрирование - Синхронизация данных - Настройки стандартного интерфейса OData. Весь функционал mcp также будет доступен под пользователем с ролью Администратор.

В этом режиме параметр _base_url запрещён. Если MCP-клиент передаст _base_url в tools/call, прокси вернёт ошибку.

2. Dynamic-base: MCP_ONEC_URL не задан

Если MCP_ONEC_URL не задан, прокси не привязан к конкретной базе. Тогда:

  • tools/list берётся из отдельного catalog source;
  • в schema каждого tool автоматически добавляется обязательный параметр _base_url;
  • каждый tools/call обязан передать _base_url;
  • _base_url используется только прокси и не передаётся в 1С;
  • логин/пароль для фактического вызова обычно берутся из MCP_ONEC_USERNAME / MCP_ONEC_PASSWORD;
  • если MCP_ONEC_USERNAME и/или MCP_ONEC_PASSWORD не заданы, прокси добавляет в schema tools обязательные proxy-only параметры _username и/или _password;
  • _username и _password используются только прокси для HTTP Basic Auth к целевой базе 1С и вырезаются перед отправкой JSON-RPC в 1С;
  • в fixed-base режиме _username / _password в tools/call запрещены, как и _base_url.

Пример вызова tool в dynamic-base:

{
  "_base_url": "https://host/base-or-data-area",
  "_username": "Admin",
  "_password": "secret",
  "actualParameter": "value"
}

В 1С уйдёт только:

{
  "actualParameter": "value"
}

Если логин/пароль заданы в окружении прокси, _username / _password передавать не нужно:

{
  "_base_url": "https://host/base-or-data-area",
  "actualParameter": "value"
}

Если в окружении задан только один credential, например MCP_ONEC_USERNAME, то schema потребует только отсутствующий _password. Аналогично, при отсутствии только MCP_ONEC_USERNAME требуется только _username.

Catalog source для tools/list в dynamic-base

MCP tools/list не принимает arguments, поэтому адрес/логин/пароль для получения списка tools задаются в конфигурации прокси.

Источник onec

Список tools берётся из обычной базы 1С:

MCP_TOOLS_CATALOG_SOURCE=onec
MCP_TOOLS_CATALOG_URL=https://host/catalog-base
MCP_TOOLS_CATALOG_USERNAME=Admin
MCP_TOOLS_CATALOG_PASSWORD=secret
MCP_TOOLS_CATALOG_SERVICE_ROOT=mcp

MCP_ONEC_USERNAME=Admin
MCP_ONEC_PASSWORD=secret
MCP_ONEC_SERVICE_ROOT=mcp

Если MCP_TOOLS_CATALOG_USERNAME/PASSWORD не заданы, используются MCP_ONEC_USERNAME/PASSWORD.

Источник file

MCP_TOOLS_CATALOG_SOURCE=file
MCP_TOOLS_CATALOG_PATH=/opt/mcp-proxy/tools.json

MCP_ONEC_USERNAME=Admin
MCP_ONEC_PASSWORD=secret

Формат файла:

{
  "tools": [
    {
      "name": "example_tool",
      "description": "Example tool",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {"type": "string"}
        },
        "required": ["name"]
      }
    }
  ]
}

Также поддерживается raw array tools.

Источник http

MCP_TOOLS_CATALOG_SOURCE=http
MCP_TOOLS_CATALOG_URL=https://example.com/tools.json
MCP_TOOLS_CATALOG_USERNAME=optional-basic-auth-user
MCP_TOOLS_CATALOG_PASSWORD=optional-basic-auth-password

MCP_ONEC_USERNAME=Admin
MCP_ONEC_PASSWORD=secret

Безопасность _base_url

В dynamic-base режиме _base_url может превратить прокси в SSRF-примитив с Basic Auth кредами. Для production рекомендуется задавать allowlist:

MCP_ONEC_ALLOWED_BASE_URLS=https://host/base1,https://host/base2

или JSON array:

MCP_ONEC_ALLOWED_BASE_URLS=["https://host/base1", "https://host/base2"]

Если allowlist задан, _base_url обязан совпадать с одним из разрешённых URL после удаления trailing slash. Поддерживаются shell-style wildcard-шаблоны (*, ?, [seq]), например:

MCP_ONEC_ALLOWED_BASE_URLS=https://*.example.com/base/*,https://*.example.org/1c

Polling списка инструментов

Прокси периодически проверяет список инструментов (tools catalog) и при обнаружении изменений отправляет MCP-клиентам уведомление notifications/tools/list_changed. После получения уведомления клиент повторно вызывает tools/list и получает актуальный список.

Polling работает во всех режимах:

  • Fixed-base: список инструментов берётся из 1С через JSON-RPC tools/list.
  • Dynamic-base (onec): список из MCP_TOOLS_CATALOG_URL.
  • Dynamic-base (file): список из JSON-файла MCP_TOOLS_CATALOG_PATH.
  • Dynamic-base (http): список из HTTP-источника MCP_TOOLS_CATALOG_URL.

Настройка интервала polling:

# По умолчанию: 1800 секунд (30 минут)
MCP_TOOLS_POLL_INTERVAL_SECONDS=1800

# Отключить polling
MCP_TOOLS_POLL_INTERVAL_SECONDS=0

При ошибке чтения каталога (1С недоступна, файл удалён и т.п.) прокси логирует предупреждение и сохраняет последний успешный snapshot — уведомление не отправляется.\nDead/недоступные MCP-сессии удаляются из registry при неудачной попытке отправки уведомления.

Загрузка файлов через локальный путь

В stdio-режиме для инструмента upload_attached_file прокси добавляет proxy-only параметр _file_path. Это позволяет MCP-клиенту не передавать большой base64 в tools/call: прокси сам читает локальный файл, кодирует его в base64, удаляет _file_path из аргументов и отправляет в 1С прежний payload.

Пример MCP tools/call arguments:

{
  "ownerMetadata": "Документ.РеализацияТоваровУслуг",
  "ownerRef_Key": "00000000-0000-0000-0000-000000000000",
  "fileName": "scan.pdf",
  "_file_path": "/opt/uploads/scan.pdf",
  "Zone": 1
}

В 1С при этом уйдёт обычный формат, совместимый с существующим 1С-кодом:

{
  "ownerMetadata": "Документ.РеализацияТоваровУслуг",
  "ownerRef_Key": "00000000-0000-0000-0000-000000000000",
  "fileName": "scan.pdf",
  "base64": "...",
  "Zone": 1
}

Особенности:

  • _file_path доступен только в stdio-режиме.
  • Если fileName не передан, используется имя файла из _file_path.
  • Одновременная передача base64 и _file_path запрещена.
  • Для 1С API изменений не требуется: сервис по-прежнему получает base64.

Для долгих загрузок есть отдельный timeout только для upload_attached_file:

MCP_ONEC_UPLOAD_TIMEOUT=300

Значение по умолчанию — 300 секунд. Обычные JSON-RPC вызовы продолжают использовать прежний HTTP timeout клиента 30 секунд.

Установка

python -m pip install platform42-mcp-proxy

Из исходников:

python -m pip install -e .

Запуск

Stdio

python -m src.py_server stdio
# или после установки пакета
mcp-proxy-1c stdio

HTTP

python -m src.py_server http --port 8000
# или
mcp-proxy-1c http --port 8000

Endpoints HTTP-режима:

  • /mcp/ — Streamable HTTP MCP transport;
  • /sse — SSE transport;
  • /health — health check;
  • /info — server info.

Stdio конфигурация для агентов

Fixed-base

{
  "mcpServers": {
    "1c-mcp-proxy": {
      "command": "mcp-proxy-1c",
      "args": ["stdio"],
      "env": {
        "MCP_ONEC_URL": "https://host/base",
        "MCP_ONEC_USERNAME": "Admin",
        "MCP_ONEC_PASSWORD": "password",
        "MCP_ONEC_SERVICE_ROOT": "mcp"
      }
    }
  }
}

Dynamic-base

Вариант с общими credentials в окружении прокси:

{
  "mcpServers": {
    "1c-mcp-proxy": {
      "command": "mcp-proxy-1c",
      "args": ["stdio"],
      "env": {
        "MCP_ONEC_USERNAME": "Admin",
        "MCP_ONEC_PASSWORD": "password",
        "MCP_ONEC_SERVICE_ROOT": "mcp",
        "MCP_TOOLS_CATALOG_SOURCE": "onec",
        "MCP_TOOLS_CATALOG_URL": "https://host/catalog-base",
        "MCP_TOOLS_CATALOG_SERVICE_ROOT": "mcp",
        "MCP_ONEC_ALLOWED_BASE_URLS": "https://host/base1,https://host/base2"
      }
    }
  }
}

Вариант, когда credentials передаются при каждом tools/call и не хранятся в окружении прокси:

{
  "mcpServers": {
    "1c-mcp-proxy": {
      "command": "mcp-proxy-1c",
      "args": ["stdio"],
      "env": {
        "MCP_ONEC_SERVICE_ROOT": "mcp",
        "MCP_TOOLS_CATALOG_SOURCE": "onec",
        "MCP_TOOLS_CATALOG_URL": "https://host/catalog-base",
        "MCP_TOOLS_CATALOG_USERNAME": "Admin",
        "MCP_TOOLS_CATALOG_PASSWORD": "password",
        "MCP_TOOLS_CATALOG_SERVICE_ROOT": "mcp",
        "MCP_ONEC_ALLOWED_BASE_URLS": "https://host/base1,https://host/base2"
      }
    }
  }
}

В dynamic-base каждый tools/call обязан передавать _base_url. Если MCP_ONEC_USERNAME / MCP_ONEC_PASSWORD не заданы, каждый tools/call также обязан передавать _username / _password — эти параметры не попадут в аргументы инструмента в 1С.

Пароль из _password санитизируется в debug-логах прокси (***). MCP-клиент всё равно должен передавать эти параметры по защищённому транспорту и не логировать tool arguments на своей стороне.

Сборка пакета

python -m pip install -U build twine
python -m build
python -m twine check dist/*

Metadata

Release files for platform42-mcp-proxy 0.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for platform42-mcp-proxy 0.5.1
File Size Uploaded Provenance Actions
platform42_mcp_proxy-0.5.1.tar.gz 69.1 kB Without provenance Details for platform42_mcp_proxy-0.5.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for platform42-mcp-proxy 0.5.1
File Interpreter ABI Platform Actions
platform42_mcp_proxy-0.5.1-py3-none-any.whl Python 3 none any Details for platform42_mcp_proxy-0.5.1-py3-none-any.whl

Total release size: 125.2 kB

Release files / platform42_mcp_proxy-0.5.1.tar.gz

Download URL platform42_mcp_proxy-0.5.1.tar.gz
Size 69.1 kB
Tags Source
SHA-256 checksum
How to use checksums
10c6d77f1785e9285fe0ac323b5e091d2c02714a423e5f38ea53b1165e157c88
BLAKE2b-256 checksum
How to use checksums
1ef7ad81df0d3769fc5b087c4fe8c8151004023adfee934572ce71f194b8a36f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release files / platform42_mcp_proxy-0.5.1-py3-none-any.whl

Download URL platform42_mcp_proxy-0.5.1-py3-none-any.whl
Size 56.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6151d79fe07e170450cc57441ac1394a3803f783b3e6b829ef263ed61f0bc122
BLAKE2b-256 checksum
How to use checksums
dede33ff8b97b2f207cefa4be07d6902ef0ca96a5451751ccce23ad3157fddd6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Security for platform42-mcp-proxy 0.5.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page