Efatura Kontrol

io.github.BerkantACUN由 GitHub 账号 BerkantACUN 发布v0.1.0更新于 Oct 24, 2026

GİB e-Fatura/e-Arşiv/e-İrsaliye belgelerini GİB'in XSD ve şematron kurallarıyla yerelde denetler

概览

AI 生成的概览

在本地依据 GİB 自身的 XSD 与 schematron 规则校验土耳其 UBL-TR 电子发票、e-Arşiv 与 e-İrsaliye 文档。

可以做什么
在本地对 e-Fatura、e-Arşiv、e-İrsaliye 及信封文件运行 GİB 发布的 XSD 与 schematron 规则,并检查行、税、代扣税与合计的算术以及签名结构。每条发现都带有行号、GİB 原始消息、土耳其语说明和修复建议。工具包括 belge_dogrula(校验)、belge_ozeti(摘要)、bulgu_acikla(解释发现代码)、kod_listesi 与 kod_listeleri(GİB 代码表)以及 ornek_fatura(生成示例发票)。
适用场景
在向 GİB 发送土耳其电子文档之前使用,可在本地发现模式、schematron 与算术错误,而不必等到提交后才知道。也适合批量检查文件夹中的 XML 文件,或生成有效的示例发票用于测试。
运行要求
以 uvx 或 pip 运行的本地进程;需要 Python 3.10 或更高版本,以及 lxml 和 SaxonC-HE(saxonche,约 40 MB 的 wheel)。本地使用无需账户、API 密钥或网络访问。可选的远程 HTTP 模式由 Docker 镜像运行,使用 EFATURA_HOST、EFATURA_PORT 和 EFATURA_API_KEY。
安装前请注意
所有工具均为只读,本地模式下不会向网络发送任何内容。在远程 HTTP 模式下,若未设置 EFATURA_API_KEY,服务器会记录警告并对任何人开放;该密钥只是简单的共享密钥,因此应置于终止 TLS 的反向代理之后。远程模式禁用文件路径参数,只接受文档内容。签名检查仅针对结构而非密码学验证,且不包含 GİB 的实时检查。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Efatura Kontrol,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

efatura-kontrol

GİB'e göndermeden önce e-Fatura, e-Arşiv Fatura, e-İrsaliye ve zarf dosyalarını GİB'in kendi kurallarıyla kontrol eder: OASIS UBL 2.1 XSD'si, GİB'in e-Fatura Paketi şematronu (498 kural, 41 kod listesi), satır/vergi/tevkifat/dip toplam aritmetiği ve imza yapısı. Her bulgu satır numarası, GİB'in özgün mesajı, Türkçe açıklama ve düzeltme önerisiyle gelir. Komut satırı, Python kütüphanesi ve MCP sunucusu; hiçbir veri ağa gitmez.

Validates Turkish UBL-TR e-invoices (e-Fatura, e-Arşiv, e-İrsaliye, envelopes) offline with the Revenue Administration's own XSD and schematron rules, plus arithmetic and signature-structure checks; explains every finding in Turkish with a fix. CLI, Python API and MCP server (local stdio or remote HTTP). English documentation ↓

mcp-name: io.github.BerkantACUN/efatura-kontrol

$ efatura-kontrol dogrula fatura.xmlfatura.xml: GEÇERSİZ — 1 hata, 1 uyarı, 1 bilgi (fatura / TEMELFATURA / SATIS, 6.2 ms)  HATA  sch-GeneralUnitCodeCheck-1 [satır 138]: Geçersiz unitCode niteliği : 'ADET'. Geçerli değerler için kod listesine bakınız.        → Adet için C62, kilogram KGM, gram GRM, metre MTR, litre LTR, saat HUR, gün DAY, ay MON, kutu BX, paket PA, çift PR yazın.  UYARI hesap-dip-odenecek [satır 134]: Ödenecek tutar vergiler dahil tutar − tevkifat + yuvarlama ile uyuşmuyor: yazılan 18.88, hesaplanan 17.88        → Tevkifatlı faturada tevkifatı düşün; yuvarlama varsa PayableRoundingAmount yazın.  BILGI imza-yok [satır 3]: Belge elektronik imza taşımıyor; GİB'e gönderilecek belgede XAdES imzası bulunmalıdır, taslak için normaldir

Neden

GİB'in şematronu XPath 2.0 ile yazılmış, üç dosyaya bölünmüş, 133 soyut kural ve parça-içerme kullanır; sıradan araçlarla (lxml, çoğu Python şematron kütüphanesi) çalışmaz. Bu yüzden entegratörler hatayı ancak GİB'e ya da özel entegratöre gönderince öğrenir. efatura-kontrol GİB'in şematronunu düzleştirip XSLT 3.0'a bir kez derler (SchXslt2), Saxon ile çalıştırır: belge başına 2–20 ms, GİB'in verdiği mesajın aynısı, üstüne satır numarası ve düzeltme.

Kurulum

bash
uvx efatura-kontrol --help          # kurulumsuzpip install efatura-kontrol         # ya da kalıcı

Python ≥ 3.10; bağımlılıklar lxml ve SaxonC-HE (saxonche, ~40 MB wheel; Windows, macOS, Linux). İlk çalıştırma şematronu derlerken ~0,5 s alır, sonrası milisaniyeler.

Komutlar

KomutNe yapar
dogrula belge.xml [belge2.xml…] [--tur fatura|earsiv|irsaliye|irsaliye-yaniti|uygulama-yaniti|zarf] [--json] [--sessiz]Tam denetim; hata varsa çıkış kodu 1
ozet belge.xmlSenaryo, tip, numara, taraflar (VKN/TCKN), satırlar, vergiler, dip toplamlar, imzalı mı
kod / kod UnitCodeList --ara KGMGİB kod listeleri (şematronun fiilen uyguladığı değerler)
acikla sch-GeneralUnitCodeCheck-1Bulgu kodunun açıklaması ve düzeltmesi
toplu klasor/ [--isci 8] [--json]Klasördeki tüm XML'leri paralel denetle; 200 belge (22 MB) ≈ 2 s
ornek-fatura [girdi.json|-] [-o fatura.xml] [--senaryo TEMELFATURA|TICARIFATURA|EARSIVFATURA]Taraflar, satırlar ve KDV oranından geçerli, imzasız UBL-TR örnek fatura üretir (girdi yoksa yerleşik örnek); çıktı kendi doğrulamasından geçer
mcp [--http] [--host H] [--port P]MCP sunucusu (stdio; --http ile streamable HTTP)

Belge türü kök elemandan ve cbc:ProfileID'den bulunur; EARSIVFATURA görünce e-Arşiv kuralları (type=earchive) uygulanır. --tur ile zorlanabilir.

MCP sunucusu

Claude Desktop / Claude Code / Cursor için:

json
{  "mcpServers": {    "efatura-kontrol": { "command": "uvx", "args": ["efatura-kontrol", "mcp"] }  }}

Araçlar (hepsi salt okunur, hiçbiri dosya yazmaz): belge_dogrula(dosya|xml, tur), belge_ozeti(dosya|xml), bulgu_acikla(kod), kod_listesi(liste, ara), kod_listeleri(), ornek_fatura(satici, alici, satirlar, senaryo, no, tarih). Resmî MCP kayıt defterinde io.github.BerkantACUN/efatura-kontrol.

Cline gibi ajanlar kurulumu llms-install.md ile kendi başına yapabilir.

Uzak sunucu (Docker)

efatura-kontrol mcp --http sunucuyu streamable HTTP ile http://<host>:8080/mcp adresinde açar (durumsuz; birden çok kopya yük dengeleyici arkasında çalışır). Hazır imaj her v* sürümünde yayımlanır:

bash
docker run --rm -p 8080:8080 -e EFATURA_API_KEY=gizli ghcr.io/berkantacun/efatura-kontrol
Ortam değişkeniVarsayılanAnlamı
EFATURA_HOST0.0.0.0Dinlenecek adres (Azure Container Apps IPv6 desteklemediği için IPv4)
EFATURA_PORT8080Port
EFATURA_API_KEY—Verilirse her istekte X-API-Key başlığı bu değere eşit olmalı, yoksa 401

İstemci tarafı:

json
{  "mcpServers": {    "efatura-kontrol": {      "type": "http",      "url": "https://sunucu.example.com/mcp",      "headers": { "X-API-Key": "gizli" }    }  }}

Uzak modda dosya parametresi kapalıdır (sunucu kendi diskini okumaz, uzak-dosya-kapali hatası döner); belgeyi xml parametresiyle gönderin. İstek gövdesi 64 MB ile sınırlıdır. Anahtar yalnız basit bir paylaşımlı sırdır; sunucuyu internete açarken TLS sonlandıran bir ters vekil (Container Apps ingress gibi) arkasında çalıştırın.

Örnek fatura üretme

bash
efatura-kontrol ornek-fatura girdi.json -o fatura.xml
json
{  "satici": {"vkn_tckn": "1288331521", "unvan": "AAA Anonim Şirketi", "vergi_dairesi": "Büyük Mükellefler", "ilce": "Beşiktaş", "sehir": "İstanbul"},  "alici": {"vkn_tckn": "11111111110", "ad": "Ali", "soyad": "Yılmaz", "ilce": "Çankaya", "sehir": "Ankara"},  "satirlar": [    {"ad": "Danışmanlık", "miktar": "3", "birim": "HUR", "birim_fiyat": "500", "kdv_orani": "20"},    {"ad": "Kitap", "miktar": "2", "birim_fiyat": "45.50", "kdv_orani": "10"}  ],  "senaryo": "TEMELFATURA"}

Satır tutarı, oran başına KDV alt toplamları ve dip toplamlar hesaplanır; belge XSD, şematron ve aritmetik denetimden hatasız geçer (tek bulgu imza-yok bilgisi). Kapsam bilinçli olarak dar: SATIS tipi, TRY, KDV oranı > 0; indirim, tevkifat, istisna ve döviz yok. Belge imzasızdır; test ve öğrenme içindir, GİB'e gönderilecek belgeyi entegratör ya da mali mühür imzalar.

Python

python
from efatura_kontrol.kontrol import kontrol_et, ozet
rapor = kontrol_et("fatura.xml")  # ya da bytes, tur="earsiv"rapor.gecerli, rapor.sayim("hata"), rapor.sozluk()for b in rapor.bulgular:    print(b.seviye, b.kod, b.satir, b.mesaj, b.duzeltme)

Ne kontrol edilir

KatmanKaynakSeviye
XML iyi biçimlilik, boyut (≤ 50 MB), kök elemanlxmlhata
XSDOASIS UBL 2.1 runtime şemaları (UBL-TR 1.2.1 paketi) + GİB zarf/HRXML şemalarıhata
ŞematronGİB e-Fatura Paketi (29), UBL-TR_Main/Common/Codelist, şematron güncellemesi 2026-07-01; 121 kural, 499 assert, 41 kod listesi (birim, para birimi, ülke, vergi, tevkifat kod+oran, istisna, ödeme şekli, senaryo, fatura tipi…)hata
Aritmetiksatır tutarı = miktar × fiyat − indirim + artırım; vergi = matrah × oran; vergi toplamı; tevkifat = KDV × oran; dip toplamlar (mal/hizmet, indirim, artırım, vergi hariç, vergiler dahil, ödenecek); currencyID tutarlılığıuyarı
İmzads:Signature var mı, SignedInfo/SignatureValue/X509Certificate/SigningTime/SigningCertificate, Reference URI'leri çözülüyor muhata/bilgi

"Uyarı" GİB'in reddetmeyebileceği ama alıcının reddedeceği şeydir; "bilgi" imza durumu gibi notlardır. HKS (hal) faturalarında dip toplam kuralları farklı olduğundan aritmetik dip kontrolü atlanır.

Bulgu biçimi

json
{"kod": "sch-GeneralUnitCodeCheck-1", "seviye": "hata", "kaynak": "sematron", "mesaj": "Geçersiz unitCode niteliği : 'ADET'. …", "gib_mesaj": "…", "kural": "not(//cbc:UBLVersionID = '2.1') or contains($UnitCodeList, …)", "konum": "/Q{…}Invoice[1]/Q{…}InvoiceLine[1]/Q{…}InvoicedQuantity[1]/@unitCode", "satir": 138, "aciklama": "…", "duzeltme": "Adet için C62, …"}

Şematron bulgu kodları GİB'in soyut kural adından türetilir (sch-<KuralAdı>-<sıra>); GİB kural sırasını değiştirirse kod kayar, mesaj aynı kalır.

GİB'in kendi örneklerinde sonuç

UBL-TR 1.2.1 paketindeki örnekler (hiçbir şey değiştirmeden):

ÖrnekSonuç
IDIS_Fatura, SARJ, SARJANLIK, OTV, OZELMATRAH, YTB_* (12 dosya), HKS-Ornek1 (şematron)geçerli
TemelFaturaOrnegifatura numarası biçimi (ABC2009123456789 kalıbı), 10 haneli TCKN
TEVKIFAT, ISTISNA-2, HASTANEunitCode yok (paket örnekleri 2022 öncesi kurala göre)
ISTISNA-1/2TRY dışı para biriminde kur yok
IadeFaturasiOrnegiTICARIFATURA'da IADE olmaz; iade referansı eksik
IHRACATimza yapısı eksik (örnek imzasız kesilmiş)
HKS-Ornek1/2XSD: boş ext:ExtensionContent
e-FaturaPaketi/xml/*UBL 2.0 / TR1.0 eski örnekler, şematron reddediyor

Yani araç GİB'in kendi paketindeki eskimiş örnekleri bile yakalıyor; ornekler/ altında düzeltilmiş, tam geçerli dört belge var.

Güncel kalma

araclar/paket_indir.py GİB paketlerini indirir (sha256 ile), efatura-kontrol derle kaynak şematronu düzleştirip derler, kod listelerini ve XSD'leri ekler/ altına yazar. CI her çalıştığında güncel GİB paketiyle üretilen çıktının repodakiyle aynı olduğunu doğrular; GİB paketi değiştiğinde iş kırmızıya döner ve yeni sürüm çıkar. Kullanılan paket sürümleri efatura_kontrol.PAKET içinde ve her raporun paket alanında.

Sınırlar

  • İmza kriptografik olarak doğrulanmaz (sertifika, özet, zaman damgası); yalnız yapısı denetlenir.
  • GİB'in canlı kontrolleri (mükellef kayıtlı mı, etiket geçerli mi, faaliyet kodu–KDV oranı eşleşmesi, mükerrer numara) bu araçta yoktur; bunlar ancak GİB sisteminde bilinir.
  • e-Arşiv raporu (eArsivRaporu) ve e-Defter kapsam dışıdır (sonraki sürüm).
  • "Geçerli" = GİB'in yayımladığı XSD ve şematronu geçer; GİB'in sistem tarafındaki ek kontrolleri için garanti değildir.

English

efatura-kontrol checks Turkish e-documents in the UBL-TR format (e-Fatura, e-Arşiv invoice, e-İrsaliye despatch advice, receipt/application responses and envelopes) before they are sent to the Revenue Administration (GİB). It runs GİB's own rules offline: the OASIS UBL 2.1 XSD shipped in the UBL-TR package, GİB's e-Fatura schematron (flattened and compiled to XSLT 3.0, run with Saxon), line / tax / withholding / total arithmetic and the structure of the XAdES signature. Nothing is sent over the network.

Install

bash
uvx efatura-kontrol --help      # no install, needs uv (https://docs.astral.sh/uv/)pip install efatura-kontrol     # or install permanently

Python ≥ 3.10. Dependencies are lxml and SaxonC-HE (saxonche, a ~40 MB wheel for Windows, macOS and Linux). The first run compiles the schematron in about half a second; after that a document takes milliseconds.

Command line

bash
efatura-kontrol dogrula invoice.xml            # validate; exit code 1 if there is an errorefatura-kontrol dogrula *.xml --json           # machine-readable reportefatura-kontrol ozet invoice.xml               # parties, lines, taxes, totalsefatura-kontrol kod UnitCodeList --ara KGM     # values of a GİB code listefatura-kontrol acikla sch-GeneralUnitCodeCheck-1efatura-kontrol toplu folder/ --json           # validate a folder in parallel (JSON lines)

Command names are Turkish: dogrula = validate, ozet = summary, kod = code list, acikla = explain, toplu = batch. The document type is detected from the root element and cbc:ProfileID; force it with --tur fatura|earsiv|irsaliye|irsaliye-yaniti|uygulama-yaniti|zarf.

Reading the result

Each finding has a kod (stable identifier, e.g. sch-GeneralUnitCodeCheck-1 for schematron rules, xsd-…, hesap-… for arithmetic, imza-… for signature), a seviye (severity) and a line number. Severity hata (error) means GİB will reject the document; uyari (warning) is an arithmetic or currency inconsistency GİB may accept but the buyer may reject; bilgi (info) is a note such as "not signed yet". gib_mesaj is GİB's original (Turkish) message; aciklama and duzeltme are a Turkish explanation and a suggested fix. The JSON keys are Turkish as well: gecerli = valid, bulgular = findings, satir = line.

MCP server (local)

For Claude Desktop, Claude Code, Cursor and other MCP clients:

json
{  "mcpServers": {    "efatura-kontrol": { "command": "uvx", "args": ["efatura-kontrol", "mcp"] }  }}

Tools (all read-only): belge_dogrula (validate a document by path dosya or content xml), belge_ozeti (summary), bulgu_acikla (explain a finding code), kod_listesi (values of a code list), kod_listeleri (available code lists and GİB package versions). Listed in the official MCP registry as io.github.BerkantACUN/efatura-kontrol.

Remote server (Docker / HTTP)

efatura-kontrol mcp --http serves the same tools over MCP streamable HTTP at http://<host>:8080/mcp. It is stateless, so several replicas can run behind a load balancer. An image is published to GitHub Container Registry for every v* release:

bash
docker run --rm -p 8080:8080 -e EFATURA_API_KEY=change-me ghcr.io/berkantacun/efatura-kontrol
VariableDefaultMeaning
EFATURA_HOST0.0.0.0Listen address (IPv4, because Azure Container Apps has no IPv6)
EFATURA_PORT8080Port
EFATURA_API_KEY—If set, every request must carry X-API-Key: <value>, otherwise 401. Without it the server logs a warning and is open to anyone

--host and --port override the variables. Client configuration:

json
{  "mcpServers": {    "efatura-kontrol": {      "type": "http",      "url": "https://your-server.example.com/mcp",      "headers": { "X-API-Key": "change-me" }    }  }}

In remote mode the dosya (file path) parameter is disabled for security (the server never reads its own disk; the tool returns uzak-dosya-kapali), so send the document content in the xml parameter. Request bodies are limited to 64 MB. The image runs Python 3.12 slim as a non-root user. The API key is a simple shared secret: put the server behind a TLS-terminating reverse proxy (such as the Container Apps ingress) before exposing it to the internet.

Python API

python
from efatura_kontrol.kontrol import kontrol_et, ozet
report = kontrol_et("invoice.xml")  # or bytes; tur="earsiv" forces the typereport.gecerli, report.sayim("hata"), report.sozluk()for f in report.bulgular:    print(f.seviye, f.kod, f.satir, f.mesaj, f.duzeltme)

Limits

  • The signature is checked for structure only, not cryptographically (certificate, digest, timestamp).
  • GİB's live checks (is the taxpayer registered, is the mailbox alias valid, duplicate numbers…) cannot be done offline and are not included.
  • The e-Arşiv report (eArsivRaporu) and e-Defter (e-ledger) are out of scope.
  • "Valid" means the document passes the XSD and schematron GİB publishes; it is not a guarantee against additional server-side checks.

Kaynaklar

Paketler, sürümler, şematrona yapılan düzleştirme müdahaleleri ve GİB paketinde bulunan tutarsızlıklar: KAYNAKLAR.md. Değişiklikler: CHANGELOG.md.

MIT lisansı. GİB ile bir bağı yoktur; "GİB", "e-Fatura", "UBL-TR" ilgili kurumların adlarıdır.

来源:README.md,提交 87c0ca0

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

1
  1. v0.1.0最新Sep 21, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分