Language Server Protocol (LSP) server for authoring camt053 ISO 20022 camt.053 reversing-entry data files.
Project description
camt053-lsp: A Language Server for Authoring ISO 20022 Reversing-Entry Files
Real-time editor help for ISO 20022 reversing-entry files — diagnostics,
completion, and hover as you author the JSON records that drive camt.053
reversal generation.
Latest release: v0.0.5 — a pygls-based Language Server with schema + IBAN/BIC diagnostics, field and message-type completion, and schema-description hover, all backed by
camt053.services. See what's new →
Contents
- Overview
- Install
- Quick Start
- Features
- Using the helpers
- Examples
- The camt053 suite
- When not to use camt053-lsp
- Development
- Security
- Documentation
- License
- Contributing
- Acknowledgements
Overview
A Language Server speaks the
Language Server Protocol (LSP) — the editor-agnostic protocol that lets a
single backend deliver diagnostics, completion, hover, and more to any LSP
client (VS Code, Neovim, Helix, Emacs, …). camt053-lsp is that backend for
reversing-entry data JSON files: the JSON arrays of flat reversing-entry
records that drive ISO 20022 camt.053 reversal generation in the
camt053 suite.
- Website: https://sebastienrousseau.github.io/camt053/
- Source code: https://github.com/sebastienrousseau/camt053-lsp
- Bug reports: https://github.com/sebastienrousseau/camt053-lsp/issues
It gives editors three features as you type, all backed by
camt053.services so they behave identically to the CLI, REST API, and MCP
server:
- Diagnostics — each record is validated against a message type's input JSON Schema, and any IBAN / BIC identifier values are additionally checked with the dedicated validators.
- Completion — every input field (with its description) plus the list of
supported
camtmessage types. - Hover — the schema description for the field under the cursor.
The intended message type defaults to camt.053.001.14 (Bank to Customer
Statement); the pure helpers accept a message_type argument so a different
type can be configured.
camt053-lsp is part of the camt053 suite — a set of independently
installable packages (all Python 3.10+) sharing the camt053.services layer:
| Package | Role |
|---|---|
camt053 |
Core library + Click CLI + FastAPI REST API |
camt053-mcp |
Model Context Protocol server (for AI agents) |
camt053-lsp |
Language Server Protocol server (this package) |
flowchart LR
A["Editor (VS Code / Neovim / …)"] -->|LSP over stdio| B["camt053-lsp"]
B -->|compute_diagnostics / completion_items / hover_text| C["camt053.services"]
C -->|schema + IBAN/BIC validation| B
B -->|diagnostics · completion · hover| A
Install
camt053-lsp runs on macOS, Linux, and Windows and requires Python 3.10+
and pip. It pulls in the core camt053 library and
pygls automatically.
python -m pip install camt053-lsp
Verify the installation:
python -c "import camt053_lsp; print('camt053-lsp', camt053_lsp.__version__)"
Using an isolated virtual environment (recommended)
python -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows
python -m pip install -U camt053-lsp
Quick Start
The package installs a camt053-lsp console entry point that starts the
language server over stdio:
camt053-lsp
The command speaks LSP on stdin/stdout — it is meant to be launched by your editor's LSP client, not used interactively. Point your editor at it for JSON reversing-entry data files and you get diagnostics, completion, and hover as you type.
Editor wiring
Register camt053-lsp as the server cmd for JSON files in your editor's LSP
client.
Neovim (built-in vim.lsp.config)
vim.lsp.config["camt053"] = {
cmd = { "camt053-lsp" },
filetypes = { "json" },
root_markers = { ".git" },
}
vim.lsp.enable("camt053")
VS Code (generic LSP client)
Configure a generic LSP client extension to spawn the camt053-lsp command over
stdio for the json language, or wrap it in a small extension whose
serverOptions is { command: "camt053-lsp", transport: TransportKind.stdio }.
Open a JSON array of reversing-entry records and the server validates each record on open and on every change, surfaces completion for field names and message types, and shows schema descriptions on hover.
Features
For reversing-entry data JSON files (a JSON array of flat reversing-entry records, or a single record object treated as one record):
- Diagnostics — schema validation reports missing required fields, wrong
types, and pattern/length violations; identifier fields (
account_id,account_servicer_bic,counterparty_account) are additionally checked as IBAN / BIC. Malformed JSON yields a single syntax diagnostic at the offending position. - Completion — every input field for the message type (with its schema
description as the detail) plus every supported
camtmessage type. - Hover — the schema
descriptionfor the field name under the cursor, or the human-readable name when the token is a supportedcamt.05xmessage type (e.g.camt.053.001.14 — Bank To Customer Statement). - Code actions — for each record missing required fields, a quick-fix inserts the missing keys (with empty placeholder values) into that record. Valid records and malformed JSON propose no action.
- Document symbols (outline) — one symbol per record (named
Record N, with itsstatement_msg_id/entry_refas the detail) and a child symbol for every field, so editors can render an outline / breadcrumb. Malformed JSON yields an empty outline. - Formatting — pretty-prints the whole document with a stable 2-space indent while preserving key order, returned as a single full-document edit. Invalid JSON leaves the document unchanged.
- JSONC tolerance —
//line comments and trailing commas are stripped before parsing, so all of the above work on JSONC data files. Clean JSON is unaffected. (YAML data files are a planned future enhancement.)
The feature logic lives in pure, importable helpers (compute_diagnostics,
completion_items, hover_text, hover_markup, message_type_name,
code_actions, document_symbols, format_text) backed by the shared
camt053.services layer, so editor behaviour stays in lockstep with
the CLI, REST API, and MCP server. The LSP handlers are thin glue that map those
plain dicts to lsprotocol types.
Using the helpers
Because the feature logic is pure, you can call it directly — no editor or server process required. This is exactly what the server runs on each edit:
import json
from camt053_lsp.server import (
code_actions,
completion_items,
compute_diagnostics,
document_symbols,
format_text,
hover_markup,
hover_text,
)
# A complete, valid reversing-entry record produces no diagnostics.
valid_doc = json.dumps(
[
{
"statement_msg_id": "RVSL-STMT-0001",
"creation_date_time": "2026-06-15T08:00:00",
"statement_id": "RVSL-STMT-0001",
"account_id": "GB29NWBK60161331926819",
"account_currency": "EUR",
"account_servicer_bic": "NWBKGB2LXXX",
"amount": "1500.00",
"currency": "EUR",
"credit_debit": "DBIT",
"reason_code": "AC04",
"counterparty_account": "DE89370400440532013000",
}
]
)
assert compute_diagnostics(valid_doc) == []
# Missing required fields are reported as errors.
missing = json.dumps([{"statement_msg_id": "ONLY-ID"}])
print(len(compute_diagnostics(missing)), "issue(s)")
# An invalid BIC is flagged as a warning.
bad_bic = json.dumps([{"account_servicer_bic": "INVALID"}])
print(compute_diagnostics(bad_bic)[:1])
# Completion offers field names and message types; hover shows descriptions.
items = completion_items()
print(len(items), "completion items, e.g.", items[0]["label"])
print(hover_text("account_servicer_bic")) # -> the field's schema description
print(hover_text("nope")) # -> None
# Hover markup also names a message type under the cursor.
print(hover_markup("camt.053.001.14")) # -> "camt.053.001.14 — Bank ..."
# Code actions propose inserting a record's missing required fields.
fixes = code_actions(missing)
print(fixes[0]["title"]) # -> "Insert missing required ..."
print(code_actions(valid_doc)) # -> [] (nothing to fix)
# Document symbols build an outline: one symbol per record, fields as children.
outline = document_symbols(valid_doc)
print(outline[0]["name"], "->", len(outline[0]["children"]), "fields")
# Formatting pretty-prints the document (2-space indent, key order preserved).
print(format_text('[{"b":1,"a":2}]')) # -> formatted JSON string
print(format_text("[{not json}]")) # -> None (left unchanged)
# JSONC sugar (// comments, trailing commas) is tolerated everywhere.
jsonc = '[\n // a record\n {"statement_msg_id": "ID-1",},\n]'
print(compute_diagnostics(jsonc)[:1]) # parses fine
Each diagnostic is a plain dict —
{"line": int, "character": int, "severity": "error" | "warning", "message": str} —
which the server maps to lsprotocol Diagnostic objects before publishing.
See examples/lsp_helpers.py for the full runnable
script.
Examples
The examples/ directory contains a self-contained, runnable
script for the helper API:
| Example | Demonstrates |
|---|---|
lsp_helpers.py |
The LSP diagnostics / completion / hover helpers |
git clone https://github.com/sebastienrousseau/camt053-lsp.git && cd camt053-lsp
python examples/lsp_helpers.py
The camt053 suite
camt053-lsp is part of a set of independently installable packages
built around the camt053 library — pick whichever ones
your stack needs:
| Package | Role |
|---|---|
camt053 |
Core library + CLI + FastAPI REST API |
camt053-mcp |
Model Context Protocol server (for AI agents) |
camt053-lsp |
Language Server Protocol server (this package) |
camt053-writer-xlsx |
Excel .xlsx writer for parsed statements |
camt053-loader-mt940 |
SWIFT MT940 → camt.053 loader |
Every helper here is a thin typed wrapper over camt053.services —
the same facade the CLI, REST API, and MCP server use — so all four
interfaces behave identically.
When not to use camt053-lsp
- You have no LSP-capable editor. This server only makes sense paired with an LSP client (VS Code, Neovim, Helix, Sublime LSP, etc.). Scripted / CI use is better served by the camt053 CLI and REST API.
- You are authoring camt.053 XML statements (rather than the reversing-entry JSON the LSP targets). The CBPR+ Nov 2026 diagnostics added in v0.0.6 do fire on opened XML files (auto- detected by content), but full XML-authoring features (completion, schema-aware hover) are not the LSP's primary mode.
- You need single-file linting outside an editor. Use the CLI:
camt053 check-cbpr-readiness statement.xmlcovers the same ground the LSP surfaces on save. - You need to generate pain.001 outbound payment files. Out of
scope; use the
pain001-lspfor that workflow.
Development
camt053-lsp uses Poetry and mise.
git clone https://github.com/sebastienrousseau/camt053-lsp.git && cd camt053-lsp
mise install
poetry install
poetry shell
A Makefile orchestrates the quality gates (kept in lockstep with CI):
make check # all gates (REQUIRED before commit)
make test # pytest
make lint # ruff + black
make type-check # mypy --strict
make examples # run the example script
Security
camt053-lsp is a thin wrapper — every helper delegates to
camt053.services, where the defence-in-depth (defusedxml +
xml_guard byte cap + DOCTYPE / ENTITY pre-flight) lives. The LSP
itself does no network I/O and treats the open document as
untrusted text. Reporting practice, supported versions, and the
full supply-chain posture are documented in
SECURITY.md. Vulnerabilities go via GitHub Private
Vulnerability Reporting, not public issues.
Documentation
README.md— this fileCHANGELOG.md— release notesSECURITY.md— disclosure + supported versionsSUPPORT.md— how to get helpMAINTAINERS.md— who can mergeexamples/— runnable scripts
License
Licensed under the Apache License, Version 2.0. Any contribution submitted for inclusion shall be licensed as above, without additional terms.
Contributing
Contributions are welcome — see the contributing instructions. Thanks to all contributors.
Acknowledgements
Built on pygls and lsprotocol by the
Open Law Library, and on the core
camt053 library that powers the shared service layer.
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 camt053_lsp-0.0.6.tar.gz.
File metadata
- Download URL: camt053_lsp-0.0.6.tar.gz
- Upload date:
- Size: 22.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a743d7e7ecc5a0fa6cc7780d2311802608180e3d3d5ab1ad1fb39975ca7d0719
|
|
| MD5 |
f6ffd2ee0d8e55268abe7842183f2d91
|
|
| BLAKE2b-256 |
f78733df2a85abcd35502ee1a23ec5a961ce8b0d24075224a6d32ba795502fbf
|
Provenance
The following attestation bundles were made for camt053_lsp-0.0.6.tar.gz:
Publisher:
release.yml on sebastienrousseau/camt053-lsp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
camt053_lsp-0.0.6.tar.gz -
Subject digest:
a743d7e7ecc5a0fa6cc7780d2311802608180e3d3d5ab1ad1fb39975ca7d0719 - Sigstore transparency entry: 1915450175
- Sigstore integration time:
-
Permalink:
sebastienrousseau/camt053-lsp@12e6f3c89c09653eaf7fcfcd1265b8f55e9904b8 -
Branch / Tag:
refs/tags/v0.0.6 - Owner: https://github.com/sebastienrousseau
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@12e6f3c89c09653eaf7fcfcd1265b8f55e9904b8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file camt053_lsp-0.0.6-py3-none-any.whl.
File metadata
- Download URL: camt053_lsp-0.0.6-py3-none-any.whl
- Upload date:
- Size: 19.8 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 |
e942e7936518a9d158f960de1f888066e8abea478e689523982bd2b5e25a7504
|
|
| MD5 |
9147eca309487be81324b06c2c4fc80a
|
|
| BLAKE2b-256 |
222999338296748bb4ace19948212b1ba48d05a28fb97a1301a77d9164f96f0a
|
Provenance
The following attestation bundles were made for camt053_lsp-0.0.6-py3-none-any.whl:
Publisher:
release.yml on sebastienrousseau/camt053-lsp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
camt053_lsp-0.0.6-py3-none-any.whl -
Subject digest:
e942e7936518a9d158f960de1f888066e8abea478e689523982bd2b5e25a7504 - Sigstore transparency entry: 1915451125
- Sigstore integration time:
-
Permalink:
sebastienrousseau/camt053-lsp@12e6f3c89c09653eaf7fcfcd1265b8f55e9904b8 -
Branch / Tag:
refs/tags/v0.0.6 - Owner: https://github.com/sebastienrousseau
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@12e6f3c89c09653eaf7fcfcd1265b8f55e9904b8 -
Trigger Event:
push
-
Statement type: