MCP Universal EC E-Invoice Server

MCP Universal EC E-Invoice Server

Enables AI agents to issue, void, query, and manage Taiwan e-invoices via 27 MCP tools, wrapping the Universal EC POS Web Service.

Category
访问服务器

README

MCP Universal EC E-Invoice Server

PyPI version Python versions License: MIT GitHub stars GitHub issues GitHub last commit

繁體中文

An open-source MCP (Model Context Protocol) server wrapping the Universal EC (汎宇電商) Taiwan E-Invoice POS Web Service (JSON format, MIG4.1). Exposes 27 AI-callable tools covering all available function codes via stdio JSON-RPC 2.0.

Built for Claude Code and any MCP-compatible AI client. Enables AI agents to issue invoices, void invoices, manage invoice numbers, query cancellation status, and handle allowances through natural language.

Features

  • 27 MCP tools — Full coverage of all Universal EC e-invoice API function codes
  • stdio JSON-RPC 2.0 — Standard MCP transport protocol
  • 3 wrapper formats — INDEX, Invoice, Allowance (auto-selected per function)
  • Credential injection — SELLERID/POSID/POSSN auto-injected by connector
  • TDD tested — 53 unit tests + 5 live regression tests

Quick Start

# Setup
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"

# Configure credentials
cp .env.example .env
# Edit .env with your Universal EC credentials

# Run server
python mcp_server.py

Configuration

Create a .env file with your Universal EC POS credentials:

EINVOICE_BASE_URL=https://epostw.einvoice.com.tw/GetInvoice.ashx
EINVOICE_SELLER_ID=your_seller_id
EINVOICE_POS_ID=your_pos_id
EINVOICE_POS_SN=your_pos_sn
Environment URL
Test (測試機) https://epostw.einvoice.com.tw/GetInvoice.ashx
Production (正式機) https://eposw.einvoice.com.tw/GetInvoice.ashx

Project Structure

mcp-universalec-e-invoice/
├── app.py                          # FastMCP singleton
├── mcp_server.py                   # Entry point (stdio transport)
├── config/
│   └── settings.py                 # URL + credentials from .env
├── connectors/
│   └── einvoice_client.py          # Single POST connector (3 wrappers)
├── tools/
│   ├── system_tools.py             # Y01
│   ├── invoice_number_tools.py     # A01, C01, Z21, Z22
│   ├── b2c_invoice_tools.py        # C0401, C0401N, C0501
│   ├── b2b_invoice_tools.py        # A0401, A0501, A0101, A0201
│   ├── allowance_tools.py          # D0401, D0401N, D0501, B0401, B0501, B0101
│   ├── cancel_tools.py             # C0701, B0701
│   ├── query_tools.py              # Z11, Z31, Z33, Z34
│   └── admin_tools.py              # Z32, E0401, E0402
└── tests/
    ├── conftest.py                 # Shared fixtures
    ├── test_einvoice_client.py     # Connector unit tests
    ├── test_system_tools.py        # Y01 tests
    ├── test_invoice_number_tools.py
    ├── test_b2c_invoice_tools.py
    ├── test_b2b_invoice_tools.py
    ├── test_allowance_tools.py
    ├── test_cancel_tools.py
    ├── test_query_tools.py
    ├── test_admin_tools.py
    └── test_regression.py          # Live API tests

Tools (27 total)

System

Tool Code Description
get_system_time Y01 Connection test / get server time

Invoice Number Management

Tool Code Description
get_invoice_numbers A01 Get invoice number allocation (current period)
get_next_period_numbers C01 Get invoice number allocation (next period)
get_invoice_numbers_expanded Z21 Get numbers expanded per-invoice with AESKEY
get_next_period_numbers_expanded Z22 Get next period numbers expanded with AESKEY

B2C Invoices

Tool Code Description
create_b2c_invoice C0401 Create B2C invoice (positional field format)
create_b2c_invoice_named C0401N Create B2C invoice (named field format)
void_b2c_invoice C0501 Void a B2C invoice

B2B Invoices

Tool Code Description
create_b2b_invoice A0401 Create B2B invoice (platform certified)
void_b2b_invoice A0501 Void a B2B invoice
create_b2b_exchange_invoice A0101 Create B2B exchange invoice
void_b2b_exchange_invoice A0201 Void a B2B exchange invoice

Allowances (折讓)

Tool Code Description
create_b2c_allowance D0401 Create B2C allowance
create_b2c_allowance_named D0401N Create B2C allowance (named format)
void_b2c_allowance D0501 Void a B2C allowance
create_b2b_allowance B0401 Create B2B allowance
void_b2b_allowance B0501 Void a B2B allowance
create_b2b_exchange_allowance B0101 Create B2B exchange allowance

Cancellation (註銷)

Tool Code Description
cancel_invoice C0701 Cancel an invoice
batch_cancel_invoice B0701 Batch cancel with full invoice data

Queries

Tool Code Description
get_cancel_status Z11 Get invoice cancel process status
get_downloaded_track_ranges Z31 Query downloaded track ranges
get_assignment_info Z33 Query tax ID number assignment
get_winning_list Z34 Download winning invoice list

Administration

Tool Code Description
upload_next_period_tracks Z32 Upload next period track numbers
assign_branch_tracks E0401 Branch office track assignment
report_unused_tracks E0402 Report unused track ranges

Usage Examples

Once the MCP server is running, an AI assistant (e.g. Claude) can call these tools on your behalf. Here are real-world scenarios showing what you say and how the AI responds.


"Help me check if the e-invoice system is connected"

You: 幫我測試一下電子發票系統有沒有連線成功

AI calls: get_system_time()

Result: The system returns REPLY: "1" with MESSAGE: "連線成功" and the server time 2026/04/01 22:29:03. Your connection is working.


"What invoice numbers do I have available right now?"

You: 我目前有哪些可用的發票號碼?

AI calls: get_invoice_numbers()

Result: Current period is 115 年 03-04 月, track GS, numbers 82775400 ~ 82775449 (50 invoices available). The AI can also explain the QRCode AES key returned for barcode generation.


"I need to get the detailed invoice numbers with AES keys for printing"

You: 我需要取得每張發票的 AESKEY 跟隨機碼,準備列印用

AI calls: get_invoice_numbers_expanded()

Result: Returns 50 individual invoices, each with its own number, AESKEY, and random number:

GS82775450 → AESKEY: Xymp9aqy..., RandomNumber: 7833
GS82775451 → AESKEY: XausdWBO..., RandomNumber: 4581
...

"Issue an invoice for a customer who bought 2 lattes and 1 cake"

You: 幫我開一張發票,客人買了 2 杯拿鐵 65 元、1 個巧克力蛋糕 85 元,總共 215 元含稅,紙本發票已列印

AI calls: get_invoice_numbers_expanded() to get an available number, then:

create_b2c_invoice(
  invoice_number = "GS82775402",     ← from the allocation
  invoice_date   = "2026-04-01",
  invoice_time   = "14:30:00",
  buyer_id       = "0000000000",     ← consumer, no tax ID
  buyer_name     = "0000",
  invoice_type   = "07",
  donate_mark    = "0",
  print_mark     = "Y",
  random_number  = "6136",           ← from the allocation
  tax_type = "1", tax_rate = "0.05", tax_amount = "10",
  sales_amount = "205", free_tax = "0", zero_tax = "0", total = "215",
  items = [
    {B1:"1", B2:"拿鐵咖啡", B3:"2", B5:"65", B6:"130", B7:"1", B13:"1"},
    {B1:"2", B2:"巧克力蛋糕", B3:"1", B5:"85", B6:"85", B7:"2", B13:"1"},
  ]
)

Result: REPLY: "1", MESSAGE: "成功", invoice GS82775402 created.


"Please void invoice GS82775401"

You: 請幫我作廢發票 GS82775401,原因是客戶取消訂單

AI calls:

void_b2c_invoice(
  invoice_number = "GS82775401",
  invoice_date   = "2026-04-01",
  buyer_id       = "0000000000",
  seller_id      = "23997652",
  cancel_date    = "2026-04-01",
  cancel_time    = "15:00:00",
  cancel_reason  = "客戶取消訂單",
)

Result: REPLY: "1", MESSAGE: "成功" — invoice voided successfully.


"Check the cancellation status of invoice GS82775400"

You: 幫我查一下 GS82775400 這張發票的註銷狀態

AI calls: get_cancel_status(invoice_number="GS82775400", invoice_date="2026-04-01")

Result: STATUSCODE: "1" = completed, "2" = pending, "3" = failed. The AI interprets and tells you the current status in plain language.


"Cancel invoice GS82775400 — it was issued by mistake"

You: 發票 GS82775400 開錯了,幫我註銷

AI calls:

cancel_invoice(
  invoice_number = "GS82775400",
  invoice_date   = "2026-04-01",
  buyer_id       = "0000000000",
  seller_id      = "23997652",
  cancel_date    = "2026-04-01",
  cancel_time    = "16:00:00",
  cancel_reason  = "誤開發票",
)

Result: If the invoice has been uploaded to the tax authority, REPLY: "1" confirms cancellation. If it hasn't been uploaded yet, the system returns REPLY: "-1" with a message explaining the invoice is still being processed — the AI will tell you to try again later.

Note: "作廢" (C0501 void) and "註銷" (C0701 cancel) are different. Void happens before upload to tax authority; cancel happens after. The AI picks the right tool based on context.


"I need to check what invoice number ranges have been downloaded"

You: 查一下統編 23997652 在 11504 期的 GS 字軌已下載的配號區間

AI calls:

get_downloaded_track_ranges(
  head_ban      = "23997652",
  branch_ban    = "23997652",
  invoice_type  = "07",
  year_month    = "11504",
  invoice_track = "GS",
)

Result: Returns the track ranges that have been successfully downloaded for this period.

Testing

# Unit tests (mocked HTTP, no credentials needed)
pytest tests/ --ignore=tests/test_regression.py -v

# Regression tests (requires .env with valid credentials)
pytest tests/test_regression.py -v -s

Architecture

All 27 functions communicate through a single POST endpoint (GetInvoice.ashx), differentiated by function code in the JSON body. The connector auto-injects credentials (SELLERID, POSID, POSSN) and system time.

Three JSON wrapper formats:

  • INDEX — System/number functions (Y01, A01, C01, Z21, Z22, Z11)
  • Invoice — Invoice/allowance/admin CRUD (C0401, A0401, D0401, C0701, E0401, Z31, etc.)
  • Allowance — B0501 only (void B2B allowance)

License

MIT License — see LICENSE for details.

Part of the Asgard Ecosystem

See the full Asgard AI Platform for more MCP servers.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选