Shared JSONL audit log for BAF MCP services (mcp-baf, baf-write-mcp, hermes)
Project description
mcp-baf-audit
Єдиний JSONL-журнал аудиту для сервісів BAF. Формат запису — спільний контракт, щоб логи не розходилися між сервісами.
Пакет повністю незалежний: без рантайм-залежностей, тільки стандартна бібліотека Python (≥3.11). Він нічого не імпортує зі споживачів — навпаки, споживачі залежать від нього.
Споживачі
- mcp-baf — MCP-сервер читання 1С (інтеграція запланована окремим PR).
- baf-write-mcp — MCP-сервер контрольованого створення номенклатури в 1С (вже переведений на цей пакет).
- hermes — інтеграція запланована.
Схема запису (v2)
Кожен рядок журналу — один JSON-об'єкт зі спільним конвертом:
{
"schema_version": "2",
"ts": "2026-06-14T10:51:23.354+00:00",
"service": "baf-write-mcp",
"session": "d6dfd09f2d7d",
"seq": 1043,
"trace_id": "abc123…",
"event": "product.create",
"level": "info",
"tool": "create_product_catalog_item",
"request_id": "req-7",
"object": { "type": "product", "ref": "uuid…", "code": "000001", "name": "Болт" },
"actor": "write-svc",
"source_channel": "mcp",
"ok": true,
"duration_ms": 87,
"status": 200,
"payload": { },
"error": null
}
service — ім'я сервіса (mcp-baf | baf-write-mcp | hermes);
session — hex12, один на процес; seq — монотонний лічильник у сеансі;
trace_id — наскрізний ідентифікатор операції між сервісами, ніколи не
null у нових записах (вкладені події успадковують його через contextvar).
Optional-поля конверта v2 (request_id, object, actor, source_channel,
ok, duration_ms, status) nullable: їхня відсутність у рядку (зокрема в
логах v1) не ламає читання. Редакція секретів застосовується і до payload,
і до object.
Будь-яка зміна формату рядка → bump
SCHEMA_VERSIONуwriter.pyі minor/major тега пакета. v2 додав optional-поля конверта; читач розуміє і v1, і v2.
Канонічні імена подій
events.py фіксує namespaced-таксономію (tool.call, product.create,
counterparty.propose, one_c.http, index.search, …). Writer нормалізує
ім'я кожного запису через canonical(), тож нові логи завжди канонічні —
навіть якщо доменний код передає звичне плоске ім'я. Старі логи лишаються
читабельними: той самий canonical() мапить плоскі імена v1 у канонічні.
from mcp_baf_audit import canonical, events
canonical("create") # -> "product.create"
canonical("tool_call") # -> "tool.call"
canonical("product.create") # -> "product.create" (ідемпотентно)
events.PRODUCT_CREATE # "product.create"
Використання
from mcp_baf_audit import AuditWriter, traced, iter_events
audit = AuditWriter(service="mcp-baf", path="/path/to/audit.log")
audit.server_start(version="1.2.3")
# Канонічний метод v2 (payload і object редагуються від секретів):
audit.event("product.create", tool="create_product_catalog_item",
request_id="req-7", status=200, duration_ms=12, ok=True,
obj={"type": "product", "ref": "uuid…", "name": "Болт"},
payload={"name": "Болт"})
# Обгортка інструмента: пише tool.call/tool.error, міряє duration,
# гарантує не-null trace_id (явний -> contextvar -> новий) і фіксує його
# в contextvar, щоб вкладені події успадкували.
result_json = await traced(audit, "query", call, args={"limit": 10})
Читання журналу
iter_events() — єдина читацька функція. Вона обходить ротовані архіви в
хронологічному порядку, мовчки пропускає биті рядки (повідомляє про кожен
через on_bad_line) і нормалізує event через canonical(). На ній
будуються зовнішні проєкція/дашборд — сама бібліотека ні БД, ні форматів
представлення не знає.
from mcp_baf_audit import iter_events
bad: list[str] = []
for ev in iter_events("/path/to/audit.log", on_bad_line=bad.append):
print(ev["seq"], ev["event"], ev.get("trace_id"))
print("пропущено битих рядків:", len(bad))
HTTP-події one_c.http
baf-write-mcp передає аудит у HTTP-клієнт (OneCClient(config, audit=audit)),
і кожен виклик 1С лишає рівно одну подію one_c.http (метод, ендпоінт,
статус, duration_ms, response_bytes, request_id, trace_id). Тіло
запиту/відповіді не логується; помилки пишуться з level:"error", ok:false.
Секрети
Редакція централізована у writer'і: ключі password|token|authorization|secret
(регістронезалежно, рекурсивно) замінюються на *** у кожному записі.
Передавати «сирий» payload безпечно — секрети у лог не потрапляють.
Постачання / версіонування
Тег v0.2.0 (minor-bump: формат запису перейшов на schema v2). Споживачі
пінять версію:
pip install "git+https://github.com/andriy4k07/mcp-baf-audit.git@v0.2.0"
У монорепо — path-залежність від сусіднього каталогу:
pip install -e ../mcp-baf-audit
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 mcp_baf_audit-0.2.0.tar.gz.
File metadata
- Download URL: mcp_baf_audit-0.2.0.tar.gz
- Upload date:
- Size: 19.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53e1ee80c74aadc3d6d98bd5161b47bdcc73d979e1291f18f7456134c647e86c
|
|
| MD5 |
9396345dfecebe0c9c1a6371d422c771
|
|
| BLAKE2b-256 |
54adfa11aab34decb36cb068711396fe6359b773257f3973aa4e37b326deb42b
|
File details
Details for the file mcp_baf_audit-0.2.0-py3-none-any.whl.
File metadata
- Download URL: mcp_baf_audit-0.2.0-py3-none-any.whl
- Upload date:
- Size: 17.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ace2179480806a6fbcd3c0eab956f30f907f020d37771e2f5f639fdc8233b996
|
|
| MD5 |
070034f4d0744430ecd32782f1802ffd
|
|
| BLAKE2b-256 |
5b4ea9f1c2d07bb1536c53ce564fa7c600497bd3e911ca0273b9e4f078d0a217
|