agentbill-mcp 0.1.0__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,18 @@
1
+ # Environment — never commit real credentials
2
+ .env
3
+ .env.local
4
+
5
+ # Dependencies
6
+ node_modules/
7
+ sdk/node/node_modules/
8
+
9
+ # Build output
10
+ dist/
11
+ sdk/node/dist/
12
+
13
+ # macOS
14
+ .DS_Store
15
+
16
+ # Logs
17
+ *.log
18
+ npm-debug.log*
@@ -0,0 +1,107 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentbill-mcp
3
+ Version: 0.1.0
4
+ Summary: AgentBill MCP server. Add spend controls and billing to any AI agent in 3 lines.
5
+ Project-URL: Homepage, https://agentbill.dev
6
+ Project-URL: Repository, https://github.com/marketinglior-pixel/agentbill
7
+ Project-URL: Documentation, https://github.com/marketinglior-pixel/agentbill#readme
8
+ Author-email: AgentBill <marketinglior@gmail.com>
9
+ License: MIT
10
+ Keywords: agent-billing,ai-agents,billing,claude,langchain,llm,mcp,preflight,spend-ceiling,usage-based
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.9
21
+ Requires-Dist: httpx>=0.27
22
+ Requires-Dist: mcp[cli]>=1.0.0
23
+ Description-Content-Type: text/markdown
24
+
25
+ # agentbill-mcp
26
+
27
+ AgentBill MCP server. Add spend controls and usage billing to any AI agent in 3 lines.
28
+
29
+ ## What it does
30
+
31
+ Exposes two tools to any MCP-compatible agent host (Claude Code, Cursor, Windsurf, etc.):
32
+
33
+ - `preflight(agent_id, customer_id, estimated_units, ceiling)` — check if a customer has budget before starting work. Blocks if exhausted.
34
+ - `record_event(agent_id, units, customer_id, metadata)` — bill a customer after work completes. Idempotent.
35
+
36
+ ## Install
37
+
38
+ ```bash
39
+ uvx agentbill-mcp
40
+ ```
41
+
42
+ No install needed. `uvx` runs it directly.
43
+
44
+ ## Configure
45
+
46
+ ### Claude Code
47
+
48
+ Add to `~/.claude/settings.json`:
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "agentbill": {
54
+ "command": "uvx",
55
+ "args": ["agentbill-mcp"],
56
+ "env": {
57
+ "AGENTBILL_API_KEY": "sk_live_your_key_here"
58
+ }
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ ### Cursor / Windsurf / other MCP clients
65
+
66
+ Add to your MCP config:
67
+
68
+ ```json
69
+ {
70
+ "agentbill": {
71
+ "command": "uvx",
72
+ "args": ["agentbill-mcp"],
73
+ "env": {
74
+ "AGENTBILL_API_KEY": "sk_live_your_key_here"
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ Get your API key at [agentbill.dev/dashboard](https://agentbill.dev/dashboard).
81
+
82
+ ## Usage
83
+
84
+ Once configured, any agent using this MCP server can:
85
+
86
+ ```
87
+ # Before running a task:
88
+ preflight(agent_id="research_agent", customer_id="user_123", estimated_units=5)
89
+
90
+ # After completing the task:
91
+ record_event(agent_id="research_agent", units=5, customer_id="user_123")
92
+ ```
93
+
94
+ The server blocks the run if the customer has no remaining budget. No code changes needed in your agent.
95
+
96
+ ## Environment variables
97
+
98
+ | Variable | Required | Default | Description |
99
+ |---|---|---|---|
100
+ | `AGENTBILL_API_KEY` | Yes | — | Your AgentBill API key |
101
+ | `AGENTBILL_BASE_URL` | No | `https://agentbill.fly.dev` | Override for self-hosted |
102
+
103
+ ## Links
104
+
105
+ - Docs: [agentbill.dev](https://agentbill.dev)
106
+ - Python SDK: `pip install agentbill-sdk`
107
+ - GitHub: [github.com/marketinglior-pixel/agentbill](https://github.com/marketinglior-pixel/agentbill)
@@ -0,0 +1,83 @@
1
+ # agentbill-mcp
2
+
3
+ AgentBill MCP server. Add spend controls and usage billing to any AI agent in 3 lines.
4
+
5
+ ## What it does
6
+
7
+ Exposes two tools to any MCP-compatible agent host (Claude Code, Cursor, Windsurf, etc.):
8
+
9
+ - `preflight(agent_id, customer_id, estimated_units, ceiling)` — check if a customer has budget before starting work. Blocks if exhausted.
10
+ - `record_event(agent_id, units, customer_id, metadata)` — bill a customer after work completes. Idempotent.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ uvx agentbill-mcp
16
+ ```
17
+
18
+ No install needed. `uvx` runs it directly.
19
+
20
+ ## Configure
21
+
22
+ ### Claude Code
23
+
24
+ Add to `~/.claude/settings.json`:
25
+
26
+ ```json
27
+ {
28
+ "mcpServers": {
29
+ "agentbill": {
30
+ "command": "uvx",
31
+ "args": ["agentbill-mcp"],
32
+ "env": {
33
+ "AGENTBILL_API_KEY": "sk_live_your_key_here"
34
+ }
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ ### Cursor / Windsurf / other MCP clients
41
+
42
+ Add to your MCP config:
43
+
44
+ ```json
45
+ {
46
+ "agentbill": {
47
+ "command": "uvx",
48
+ "args": ["agentbill-mcp"],
49
+ "env": {
50
+ "AGENTBILL_API_KEY": "sk_live_your_key_here"
51
+ }
52
+ }
53
+ }
54
+ ```
55
+
56
+ Get your API key at [agentbill.dev/dashboard](https://agentbill.dev/dashboard).
57
+
58
+ ## Usage
59
+
60
+ Once configured, any agent using this MCP server can:
61
+
62
+ ```
63
+ # Before running a task:
64
+ preflight(agent_id="research_agent", customer_id="user_123", estimated_units=5)
65
+
66
+ # After completing the task:
67
+ record_event(agent_id="research_agent", units=5, customer_id="user_123")
68
+ ```
69
+
70
+ The server blocks the run if the customer has no remaining budget. No code changes needed in your agent.
71
+
72
+ ## Environment variables
73
+
74
+ | Variable | Required | Default | Description |
75
+ |---|---|---|---|
76
+ | `AGENTBILL_API_KEY` | Yes | — | Your AgentBill API key |
77
+ | `AGENTBILL_BASE_URL` | No | `https://agentbill.fly.dev` | Override for self-hosted |
78
+
79
+ ## Links
80
+
81
+ - Docs: [agentbill.dev](https://agentbill.dev)
82
+ - Python SDK: `pip install agentbill-sdk`
83
+ - GitHub: [github.com/marketinglior-pixel/agentbill](https://github.com/marketinglior-pixel/agentbill)
File without changes
@@ -0,0 +1,149 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import uuid
5
+ from typing import Optional
6
+ import httpx
7
+ from mcp.server.fastmcp import FastMCP
8
+
9
+ mcp = FastMCP(
10
+ "agentbill",
11
+ instructions=(
12
+ "AgentBill is billing infrastructure for AI agents. "
13
+ "Call preflight() before starting any agent work to check if the customer has budget. "
14
+ "Call record_event() after work completes to bill the customer. "
15
+ "Set AGENTBILL_API_KEY in your environment before use."
16
+ ),
17
+ )
18
+
19
+ BASE_URL = os.getenv("AGENTBILL_BASE_URL", "https://agentbill.fly.dev")
20
+
21
+
22
+ def _headers() -> dict:
23
+ api_key = os.getenv("AGENTBILL_API_KEY")
24
+ if not api_key:
25
+ raise ValueError(
26
+ "AGENTBILL_API_KEY environment variable is not set. "
27
+ "Get your key at agentbill.dev/dashboard"
28
+ )
29
+ return {"Authorization": f"Bearer {api_key}"}
30
+
31
+
32
+ @mcp.tool()
33
+ def preflight(
34
+ agent_id: str,
35
+ customer_id: str = "default",
36
+ estimated_units: int = 1,
37
+ ceiling: Optional[int] = None,
38
+ ) -> dict:
39
+ """
40
+ Check if an agent is allowed to run before starting work.
41
+
42
+ Call this at the start of every agent invocation. Returns approved=True when
43
+ the customer has remaining budget. Returns approved=False with a reason when
44
+ the run should be blocked (budget_exhausted, ceiling_exceeded, free_tier_exceeded).
45
+
46
+ Args:
47
+ agent_id: Identifier for this agent or task type (e.g. "research_agent").
48
+ customer_id: Your internal customer identifier. Defaults to "default".
49
+ estimated_units: How many units this run is expected to consume. Used for ceiling check.
50
+ ceiling: Max units allowed per single run. Run is blocked if estimated_units exceeds this.
51
+ """
52
+ payload: dict = {"agent_id": agent_id, "customer_id": customer_id}
53
+ if estimated_units is not None:
54
+ payload["estimated_units"] = estimated_units
55
+ if ceiling is not None:
56
+ payload["ceiling"] = ceiling
57
+
58
+ with httpx.Client(timeout=5) as client:
59
+ resp = client.post(f"{BASE_URL}/preflight", json=payload, headers=_headers())
60
+
61
+ data = resp.json()
62
+
63
+ if not data.get("approved", True):
64
+ reason = data.get("reason", "unknown")
65
+ return {
66
+ "approved": False,
67
+ "reason": reason,
68
+ "remaining_units": data.get("remaining_units"),
69
+ "upgrade_url": data.get("upgrade_url"),
70
+ "message": _blocked_message(reason, data),
71
+ }
72
+
73
+ return {
74
+ "approved": True,
75
+ "remaining_units": data.get("remaining_units"),
76
+ "estimated_units": data.get("estimated_units"),
77
+ }
78
+
79
+
80
+ @mcp.tool()
81
+ def record_event(
82
+ agent_id: str,
83
+ units: int = 1,
84
+ customer_id: str = "default",
85
+ metadata: Optional[dict] = None,
86
+ ) -> dict:
87
+ """
88
+ Record a billable event after agent work is complete.
89
+
90
+ Call this once per unit of work completed. Safe to call from retried or
91
+ parallel workflows — duplicate submissions are ignored automatically.
92
+
93
+ Args:
94
+ agent_id: Identifier for this agent or task type. Appears in the dashboard.
95
+ units: Number of billable units this event represents. Default is 1.
96
+ customer_id: Your internal customer identifier. Defaults to "default".
97
+ metadata: Optional key-value pairs stored with the event (e.g. model name, latency).
98
+ """
99
+ payload: dict = {
100
+ "customer_id": customer_id,
101
+ "event_type": agent_id,
102
+ "idempotency_key": f"{agent_id}-{uuid.uuid4()}",
103
+ "units": units,
104
+ }
105
+ if metadata:
106
+ payload["metadata"] = metadata
107
+
108
+ with httpx.Client(timeout=5) as client:
109
+ resp = client.post(f"{BASE_URL}/events", json=payload, headers=_headers())
110
+
111
+ if resp.status_code == 402:
112
+ data = resp.json()
113
+ return {
114
+ "recorded": False,
115
+ "reason": "budget_exhausted",
116
+ "message": data.get("message", "Customer budget is exhausted."),
117
+ }
118
+
119
+ resp.raise_for_status()
120
+ data = resp.json()
121
+
122
+ return {
123
+ "recorded": True,
124
+ "event_id": data.get("event_id"),
125
+ "status": data.get("status"),
126
+ "customer_remaining_units": data.get("customer_remaining_units"),
127
+ }
128
+
129
+
130
+ def _blocked_message(reason: str, data: dict) -> str:
131
+ if reason == "ceiling_exceeded":
132
+ return (
133
+ f"Run blocked: estimated {data.get('estimated_units')} units "
134
+ f"exceeds per-request ceiling of {data.get('ceiling')}."
135
+ )
136
+ if reason == "budget_exhausted":
137
+ return "Run blocked: customer budget is exhausted."
138
+ if reason == "free_tier_exceeded":
139
+ url = data.get("upgrade_url", "agentbill.dev/dashboard")
140
+ return f"Run blocked: free tier limit reached. Upgrade at {url}"
141
+ return f"Run blocked: {reason}"
142
+
143
+
144
+ def main():
145
+ mcp.run()
146
+
147
+
148
+ if __name__ == "__main__":
149
+ main()
@@ -0,0 +1,52 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "agentbill-mcp"
7
+ version = "0.1.0"
8
+ description = "AgentBill MCP server. Add spend controls and billing to any AI agent in 3 lines."
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.9"
12
+ dependencies = [
13
+ "mcp[cli]>=1.0.0",
14
+ "httpx>=0.27",
15
+ ]
16
+ authors = [
17
+ { name = "AgentBill", email = "marketinglior@gmail.com" }
18
+ ]
19
+ keywords = [
20
+ "mcp",
21
+ "ai-agents",
22
+ "billing",
23
+ "llm",
24
+ "agent-billing",
25
+ "spend-ceiling",
26
+ "preflight",
27
+ "usage-based",
28
+ "langchain",
29
+ "claude",
30
+ ]
31
+ classifiers = [
32
+ "Development Status :: 3 - Alpha",
33
+ "Intended Audience :: Developers",
34
+ "License :: OSI Approved :: MIT License",
35
+ "Programming Language :: Python :: 3",
36
+ "Programming Language :: Python :: 3.9",
37
+ "Programming Language :: Python :: 3.10",
38
+ "Programming Language :: Python :: 3.11",
39
+ "Programming Language :: Python :: 3.12",
40
+ "Topic :: Software Development :: Libraries :: Python Modules",
41
+ ]
42
+
43
+ [project.urls]
44
+ Homepage = "https://agentbill.dev"
45
+ Repository = "https://github.com/marketinglior-pixel/agentbill"
46
+ Documentation = "https://github.com/marketinglior-pixel/agentbill#readme"
47
+
48
+ [project.scripts]
49
+ agentbill-mcp = "agentbill_mcp.server:main"
50
+
51
+ [tool.hatch.build.targets.wheel]
52
+ packages = ["agentbill_mcp"]