smartbill-interface 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+ *.egg
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+ ENV/
16
+
17
+ # IDE
18
+ .idea/
19
+ .vscode/
20
+ *.swp
21
+ *.swo
22
+
23
+ # Environment variables
24
+ .env
25
+ .env.*
26
+
27
+ # OS
28
+ .DS_Store
29
+ Thumbs.db
@@ -0,0 +1,27 @@
1
+ # SmartBill Interface
2
+
3
+ ## Build and Publish
4
+
5
+ ```bash
6
+ uv build
7
+
8
+ #test publish
9
+ uv publish --token xxxxTESTxxxxxxx --publish-url https://test.pypi.org/legacy/
10
+ uvx --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ smartbill-interface
11
+
12
+ #publish
13
+ uv publish --token xxxxxxxxxxxxxxx
14
+ ```
15
+
16
+ ## Run Locally
17
+
18
+ ```bash
19
+ uvx --from . smartbill-interface
20
+
21
+ #or
22
+
23
+ uvx --from /mnt/c/projects/smartbill-mcp-server smartbill-interface
24
+
25
+ #or run from wheel file
26
+ uvx --from ./dist/smartbill_interface-0.1.1-py3-none-any.whl smartbill-interface
27
+ ```
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: smartbill-interface
3
+ Version: 0.1.1
4
+ Summary: MCP server for interfacing with smartbill.ro for conducting financial operations
5
+ Requires-Python: >=3.10
6
+ Requires-Dist: fastmcp>=2.14.5
7
+ Requires-Dist: requests>=2.32.5
8
+ Requires-Dist: starlette>=0.52.1
9
+ Requires-Dist: uvicorn>=0.40.0
10
+ Description-Content-Type: text/markdown
11
+
12
+ # SmartBill Interface MCP Server
13
+
14
+ MCP server for interfacing with smartbill.ro for conducting financial operations.
15
+
16
+ ## MCP Server - Stdio
17
+
18
+ ### Run
19
+
20
+ ```bash
21
+ export SMARTBILL_USERNAME="myname@mycompany.ro"
22
+ export SMARTBILL_TOKEN="xxxxxxxxxxxxxx"
23
+ uvx smartbill-interface
24
+ ```
25
+
26
+ ### Use from Claude Code
27
+
28
+ ```json
29
+ "mcpServers": {
30
+ "smartbill-interface": {
31
+ "type": "stdio",
32
+ "command": "uvx",
33
+ "args": [
34
+ "smartbill-interface"
35
+ ]
36
+ "env": {
37
+ "SMARTBILL_USERNAME": "${SMARTBILL_USERNAME}",
38
+ "SMARTBILL_TOKEN": "${SMARTBILL_TOKEN}"
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ Before running `claude`, export the 2 environment variables with the real values for your smartbill account:
45
+
46
+ ```
47
+ export SMARTBILL_USERNAME="myname@mycompany.ro"
48
+ export SMARTBILL_TOKEN="xxxxxxxxxxxxxx"
49
+ ```
50
+
51
+ #### Sample Prompt 1
52
+
53
+ `Get the payment status for a bill with CIF RO39999999, series XX2025, number 0003`
54
+
55
+ Response:
56
+
57
+ ```
58
+ ● smartbill-interface - _get_payment_status (MCP)(cif: "RO39999999", series: "XX2025", number: "0003")
59
+
60
+ ● Here's the payment status for the bill:
61
+
62
+ ┌───────────────┬────────┐
63
+ │ Field │ Amount │
64
+ ├───────────────┼────────┤
65
+ │ Total Amount │ 111.62 │
66
+ ├───────────────┼────────┤
67
+ │ Paid Amount │ 0.00 │
68
+ ├───────────────┼────────┤
69
+ │ Unpaid Amount │ 111.62 │
70
+ └───────────────┴────────┘
71
+
72
+ The bill (series XX2025, number 0003, CIF RO39999999) is fully unpaid — no payments have been recorded against the total of 111.62.
73
+ ```
74
+
75
+ #### Sample Prompt 2
76
+
77
+ `Get the bill with CIF RO39999999, series XX2025, number 0003`
78
+
79
+ Response:
80
+
81
+ ```
82
+ smartbill-interface - _get_bill (MCP)(cif: "RO39999999", series: "XX2025", number: "0003")
83
+
84
+ ● The bill was retrieved as a PDF blob. Let me extract and save it as a PDF file for you.
85
+
86
+ ● Read 1 file (ctrl+o to expand)
87
+
88
+ ● Bash(cat /home/mio/.claude/projects/myproject/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/tool-results/mcp-smartbill-interface-_get_bill-1111111111111.txt | python3 -c…)
89
+
90
+ ● The bill has been saved as bill_XX2025_0003.pdf (59 KB) in your working directory (/myproject/). You can open it directly from there.
91
+ ```
92
+
93
+ ### Test
94
+
95
+ Test using MCP Inspector UI:
96
+
97
+ ```bash
98
+ npx @modelcontextprotocol/inspector uvx smartbill-interface
99
+ ```
100
+
101
+ Test from the command line:
102
+
103
+ ```bash
104
+ npx @modelcontextprotocol/inspector --cli --method tools/list uvx smartbill-interface | jq -r .tools.[].name
105
+
106
+ _get_payment_status
107
+ _get_bill
108
+ ```
@@ -0,0 +1,97 @@
1
+ # SmartBill Interface MCP Server
2
+
3
+ MCP server for interfacing with smartbill.ro for conducting financial operations.
4
+
5
+ ## MCP Server - Stdio
6
+
7
+ ### Run
8
+
9
+ ```bash
10
+ export SMARTBILL_USERNAME="myname@mycompany.ro"
11
+ export SMARTBILL_TOKEN="xxxxxxxxxxxxxx"
12
+ uvx smartbill-interface
13
+ ```
14
+
15
+ ### Use from Claude Code
16
+
17
+ ```json
18
+ "mcpServers": {
19
+ "smartbill-interface": {
20
+ "type": "stdio",
21
+ "command": "uvx",
22
+ "args": [
23
+ "smartbill-interface"
24
+ ]
25
+ "env": {
26
+ "SMARTBILL_USERNAME": "${SMARTBILL_USERNAME}",
27
+ "SMARTBILL_TOKEN": "${SMARTBILL_TOKEN}"
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ Before running `claude`, export the 2 environment variables with the real values for your smartbill account:
34
+
35
+ ```
36
+ export SMARTBILL_USERNAME="myname@mycompany.ro"
37
+ export SMARTBILL_TOKEN="xxxxxxxxxxxxxx"
38
+ ```
39
+
40
+ #### Sample Prompt 1
41
+
42
+ `Get the payment status for a bill with CIF RO39999999, series XX2025, number 0003`
43
+
44
+ Response:
45
+
46
+ ```
47
+ ● smartbill-interface - _get_payment_status (MCP)(cif: "RO39999999", series: "XX2025", number: "0003")
48
+
49
+ ● Here's the payment status for the bill:
50
+
51
+ ┌───────────────┬────────┐
52
+ │ Field │ Amount │
53
+ ├───────────────┼────────┤
54
+ │ Total Amount │ 111.62 │
55
+ ├───────────────┼────────┤
56
+ │ Paid Amount │ 0.00 │
57
+ ├───────────────┼────────┤
58
+ │ Unpaid Amount │ 111.62 │
59
+ └───────────────┴────────┘
60
+
61
+ The bill (series XX2025, number 0003, CIF RO39999999) is fully unpaid — no payments have been recorded against the total of 111.62.
62
+ ```
63
+
64
+ #### Sample Prompt 2
65
+
66
+ `Get the bill with CIF RO39999999, series XX2025, number 0003`
67
+
68
+ Response:
69
+
70
+ ```
71
+ smartbill-interface - _get_bill (MCP)(cif: "RO39999999", series: "XX2025", number: "0003")
72
+
73
+ ● The bill was retrieved as a PDF blob. Let me extract and save it as a PDF file for you.
74
+
75
+ ● Read 1 file (ctrl+o to expand)
76
+
77
+ ● Bash(cat /home/mio/.claude/projects/myproject/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/tool-results/mcp-smartbill-interface-_get_bill-1111111111111.txt | python3 -c…)
78
+
79
+ ● The bill has been saved as bill_XX2025_0003.pdf (59 KB) in your working directory (/myproject/). You can open it directly from there.
80
+ ```
81
+
82
+ ### Test
83
+
84
+ Test using MCP Inspector UI:
85
+
86
+ ```bash
87
+ npx @modelcontextprotocol/inspector uvx smartbill-interface
88
+ ```
89
+
90
+ Test from the command line:
91
+
92
+ ```bash
93
+ npx @modelcontextprotocol/inspector --cli --method tools/list uvx smartbill-interface | jq -r .tools.[].name
94
+
95
+ _get_payment_status
96
+ _get_bill
97
+ ```
@@ -0,0 +1,22 @@
1
+ [project]
2
+ name = "smartbill-interface"
3
+ version = "0.1.1"
4
+ description = "MCP server for interfacing with smartbill.ro for conducting financial operations"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ dependencies = [
8
+ "fastmcp>=2.14.5",
9
+ "starlette>=0.52.1",
10
+ "uvicorn>=0.40.0",
11
+ "requests>=2.32.5",
12
+ ]
13
+
14
+ [project.scripts]
15
+ smartbill-interface = "smartbillinterface.main:main"
16
+
17
+ [build-system]
18
+ requires = ["hatchling"]
19
+ build-backend = "hatchling.build"
20
+
21
+ [tool.hatch.build.targets.wheel]
22
+ packages = ["src/smartbillinterface"]
@@ -0,0 +1,4 @@
1
+ fastmcp==2.14.5
2
+ starlette==0.52.1
3
+ uvicorn==0.40.0
4
+ requests==2.32.5
@@ -0,0 +1 @@
1
+ """SmartBill Interface MCP Server - Interfacing with smartbill.ro for conducting financial operations."""
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env python
2
+ #MCP server for interfacing with smartbill.ro for conducting financial operations
3
+ from urllib.request import urlopen, Request
4
+ from urllib.error import HTTPError
5
+ import mcp.server.fastmcp
6
+ import mcp.types
7
+ import logging
8
+ import xml.etree.ElementTree as ET
9
+ import os
10
+ import base64
11
+
12
+ logging.basicConfig(level=logging.DEBUG)
13
+ logger = logging.getLogger(__name__)
14
+
15
+ SMARTBILL_BASE_URL = "https://ws.smartbill.ro/SBORO/api"
16
+ SMARTBILL_BILL_ID = "cif={cif}&seriesname={series}&number={number}"
17
+ SMARTBILL_PAYMENT_STATUS_URL = SMARTBILL_BASE_URL + "/invoice/paymentstatus?" + SMARTBILL_BILL_ID
18
+ SMARTBILL_GET_BILL_URL = SMARTBILL_BASE_URL + "/invoice/pdf?" + SMARTBILL_BILL_ID
19
+
20
+ def _build_auth() -> str:
21
+ username = os.environ["SMARTBILL_USERNAME"]
22
+ token = os.environ["SMARTBILL_TOKEN"]
23
+ return base64.b64encode(f"{username}:{token}".encode()).decode()
24
+
25
+ mymcp = mcp.server.fastmcp.FastMCP("SmartBill Interface Server")
26
+
27
+ @mymcp.tool()
28
+ def _get_payment_status(cif: str, series: str, number: str) -> tuple[float, float, float]:
29
+ """Get the payment status for a bill.
30
+
31
+ Returns total amount, paid amount and unpaid amount.
32
+ """
33
+ logger.debug(f"_get_payment_status for bill with cif: {cif}, series: {series} and number: {number}")
34
+ url = SMARTBILL_PAYMENT_STATUS_URL.format(cif=cif, series=series, number=number)
35
+ req = Request(url, headers={
36
+ "Content-Type": "application/xml",
37
+ "Accept": "application/xml",
38
+ "Authorization": f"Basic {_build_auth()}",
39
+ })
40
+ try:
41
+ with urlopen(req) as response:
42
+ xml_data = response.read()
43
+ logger.debug(f"Received answer: {xml_data}")
44
+ root = ET.fromstring(xml_data)
45
+ total_amount = float(root.findtext("invoiceTotalAmount"))
46
+ logger.debug(f"Answer contains total amount: {total_amount}")
47
+ paid_amount = float(root.findtext("paidAmount"))
48
+ logger.debug(f"Answer contains paid amount: {paid_amount}")
49
+ unpaid_amount = float(root.findtext("unpaidAmount"))
50
+ logger.debug(f"Answer contains unpaid amount: {unpaid_amount}")
51
+ return total_amount, paid_amount, unpaid_amount
52
+ except HTTPError as e:
53
+ logger.error(f"HTTP error {e.code} for URL {url}: {e.reason}")
54
+ raise
55
+
56
+ @mymcp.tool()
57
+ def _get_bill(cif: str, series: str, number: str) -> mcp.types.BlobResourceContents:
58
+ """Get a bill.
59
+
60
+ Returns the bill in PDF format as a blob.
61
+ """
62
+ logger.debug(f"_get_bill for bill with cif: {cif}, series: {series} and number: {number}")
63
+ url = SMARTBILL_GET_BILL_URL.format(cif=cif, series=series, number=number)
64
+ req = Request(url, headers={
65
+ "Content-Type": "application/xml",
66
+ "Accept": "application/xml",
67
+ "Accept": "application/octet-stream",
68
+ "Authorization": f"Basic {_build_auth()}",
69
+ "Content-Disposition": "attachment; filename=\"bill.pdf\"",
70
+ })
71
+ try:
72
+ with urlopen(req) as response:
73
+ bill = response.read()
74
+ logger.debug(f"Received {len(bill)} bytes")
75
+ return mcp.types.BlobResourceContents(
76
+ uri=url,
77
+ blob=base64.b64encode(bill).decode(),
78
+ mimeType="application/pdf",
79
+ )
80
+ except HTTPError as e:
81
+ logger.error(f"HTTP error {e.code} for URL {url}: {e.reason}")
82
+ raise
83
+
84
+ def main():
85
+ """Entry point for the SmartBill MCP server."""
86
+ missing = [v for v in ("SMARTBILL_USERNAME", "SMARTBILL_TOKEN") if not os.environ.get(v)]
87
+ if missing:
88
+ logger.error(f"Missing required environment variables: {', '.join(missing)}")
89
+ return
90
+ mymcp.run(transport="stdio")
91
+
92
+ if __name__ == "__main__":
93
+ main()