macaroonnetwork-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,16 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .pytest_cache/
4
+ .tmp/
5
+ .mcp.json
6
+ .env
7
+ node_modules/
8
+ *.zip
9
+ !handover/*.zip
10
+ .venv/
11
+ .aider*
12
+ infra/lnd/
13
+ .env.save
14
+ .envcd
15
+ .env.local
16
+ .next/
@@ -0,0 +1,72 @@
1
+ Metadata-Version: 2.4
2
+ Name: macaroonnetwork-mcp
3
+ Version: 0.1.0
4
+ Summary: Discovery-only MCP client for Macaroon Network -- search and inspect a live marketplace where AI agents pay per query in Bitcoin over Lightning.
5
+ Project-URL: Homepage, https://macaroonnetwork.com
6
+ Project-URL: Repository, https://github.com/kevmoz/macaroonnetwork
7
+ Author: Kevin Smith
8
+ License-Expression: MIT
9
+ Keywords: agent-commerce,l402,lightning,marketplace,mcp,model-context-protocol
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: >=3.10
15
+ Requires-Dist: mcp>=1.0.0
16
+ Requires-Dist: requests>=2.31.0
17
+ Description-Content-Type: text/markdown
18
+
19
+ # macaroonnetwork-mcp
20
+
21
+ Discovery-only MCP client for [Macaroon Network](https://macaroonnetwork.com) —
22
+ a marketplace where AI agents discover, pay for (Bitcoin/Lightning via L402),
23
+ and buy live data.
24
+
25
+ ## What this does
26
+
27
+ Two tools, both free, no payment or configuration required:
28
+
29
+ - **`macaroons_search`** — semantic search over the live marketplace registry
30
+ by natural-language intent.
31
+ - **`macaroons_metadata`** — free freshness/content-hash metadata for a feed
32
+ target, before deciding whether to buy.
33
+
34
+ ## What this does *not* do (yet)
35
+
36
+ This package does not expose buying tools (`macaroons_purchase` /
37
+ `macaroons_execute`). The reference buyer implementation in the
38
+ [macaroonnetwork repo](https://github.com/kevmoz/macaroonnetwork) pays via a
39
+ regtest Lightning node that's part of that repo's own dev environment —
40
+ there's no way to make that work correctly for an arbitrary external
41
+ installation yet. Real-wallet payment support (a configurable Lightning node,
42
+ or the Polygon stablecoin credit rail) is planned; this package will grow
43
+ purchase tools once that exists. Shipping non-functional buy tools now would
44
+ mean they silently fail for every real user, which is exactly the kind of
45
+ thing this project's L402/predicate machinery exists to prevent on the seller
46
+ side — no reason to reintroduce it here.
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ pip install macaroonnetwork-mcp
52
+ ```
53
+
54
+ ## Use with an MCP client
55
+
56
+ ```json
57
+ {
58
+ "mcpServers": {
59
+ "macaroonnetwork": {
60
+ "command": "macaroonnetwork-mcp"
61
+ }
62
+ }
63
+ }
64
+ ```
65
+
66
+ Talks to `https://api.macaroonnetwork.com` by default. Override with
67
+ `MACAROONS_REGISTRY_URL` / `MACAROONS_FEED_URL` env vars to point at a local
68
+ dev stack instead.
69
+
70
+ ## License
71
+
72
+ MIT
@@ -0,0 +1,54 @@
1
+ # macaroonnetwork-mcp
2
+
3
+ Discovery-only MCP client for [Macaroon Network](https://macaroonnetwork.com) —
4
+ a marketplace where AI agents discover, pay for (Bitcoin/Lightning via L402),
5
+ and buy live data.
6
+
7
+ ## What this does
8
+
9
+ Two tools, both free, no payment or configuration required:
10
+
11
+ - **`macaroons_search`** — semantic search over the live marketplace registry
12
+ by natural-language intent.
13
+ - **`macaroons_metadata`** — free freshness/content-hash metadata for a feed
14
+ target, before deciding whether to buy.
15
+
16
+ ## What this does *not* do (yet)
17
+
18
+ This package does not expose buying tools (`macaroons_purchase` /
19
+ `macaroons_execute`). The reference buyer implementation in the
20
+ [macaroonnetwork repo](https://github.com/kevmoz/macaroonnetwork) pays via a
21
+ regtest Lightning node that's part of that repo's own dev environment —
22
+ there's no way to make that work correctly for an arbitrary external
23
+ installation yet. Real-wallet payment support (a configurable Lightning node,
24
+ or the Polygon stablecoin credit rail) is planned; this package will grow
25
+ purchase tools once that exists. Shipping non-functional buy tools now would
26
+ mean they silently fail for every real user, which is exactly the kind of
27
+ thing this project's L402/predicate machinery exists to prevent on the seller
28
+ side — no reason to reintroduce it here.
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install macaroonnetwork-mcp
34
+ ```
35
+
36
+ ## Use with an MCP client
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "macaroonnetwork": {
42
+ "command": "macaroonnetwork-mcp"
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ Talks to `https://api.macaroonnetwork.com` by default. Override with
49
+ `MACAROONS_REGISTRY_URL` / `MACAROONS_FEED_URL` env vars to point at a local
50
+ dev stack instead.
51
+
52
+ ## License
53
+
54
+ MIT
@@ -0,0 +1,6 @@
1
+ """macaroonnetwork-mcp — discovery-only MCP client for Macaroon Network.
2
+
3
+ See mcp_server.py's module docstring for what this does and does not do.
4
+ """
5
+
6
+ __version__ = "0.1.0"
@@ -0,0 +1,177 @@
1
+ """macaroonnetwork-mcp — discovery-only MCP server for Macaroon Network.
2
+
3
+ Exposes two read-only tools any MCP client can use with zero configuration:
4
+
5
+ - macaroons_search: semantic search over the live marketplace registry.
6
+ - macaroons_metadata: free metadata for a feed target (freshness, content
7
+ hash) before deciding whether to buy.
8
+
9
+ Deliberately does NOT expose macaroons_purchase / macaroons_execute (the
10
+ paid tools). The reference implementation of those in the macaroonnetwork
11
+ repo (packages/buyer/) pays by shelling out to this repo's own regtest
12
+ Lightning dev environment (docker compose exec lnd-buyer lncli payinvoice)
13
+ -- there is no docker-compose.dev.yml or regtest LND node on an external
14
+ user's machine, so those tools would silently fail for anyone who isn't
15
+ running inside that repo's checkout. Shipping them here would mean this
16
+ package's "buy" tools crash for every real external user -- exactly the
17
+ kind of unearned-passing-result this whole project exists to avoid on the
18
+ seller side. Real-wallet payment support (a configurable LND node, or the
19
+ Polygon x402/stablecoin credit rail) is a separate, not-yet-built piece of
20
+ work; this package will grow purchase/execute tools once that exists.
21
+
22
+ Talks to https://api.macaroonnetwork.com by default -- override with
23
+ MACAROONS_REGISTRY_URL / MACAROONS_FEED_URL for local development against
24
+ this repo's own dev stack.
25
+ """
26
+ from __future__ import annotations
27
+
28
+ import asyncio
29
+ import json
30
+ import os
31
+ from typing import Any
32
+
33
+ import requests
34
+
35
+ _REGISTRY_URL = os.environ.get("MACAROONS_REGISTRY_URL", "https://api.macaroonnetwork.com")
36
+ _FEED_URL = os.environ.get("MACAROONS_FEED_URL", "https://api.macaroonnetwork.com")
37
+
38
+
39
+ def get_tool_definitions() -> list[dict[str, Any]]:
40
+ return [
41
+ {
42
+ "name": "macaroons_search",
43
+ "description": (
44
+ "Search Macaroon Network for capabilities matching an intent. "
45
+ "Returns ranked listings with price, predicate hash, and freshness. "
46
+ "Free, no payment required."
47
+ ),
48
+ "inputSchema": {
49
+ "type": "object",
50
+ "properties": {
51
+ "intent": {
52
+ "type": "string",
53
+ "description": (
54
+ "Natural language description of what the agent needs. "
55
+ "E.g. 'GPU pricing data updated in the last 24 hours'"
56
+ ),
57
+ },
58
+ "limit": {
59
+ "type": "integer",
60
+ "default": 5,
61
+ "maximum": 20,
62
+ "description": "Maximum number of results to return",
63
+ },
64
+ },
65
+ "required": ["intent"],
66
+ },
67
+ },
68
+ {
69
+ "name": "macaroons_metadata",
70
+ "description": (
71
+ "Get free metadata for a feed target before purchasing. Returns "
72
+ "freshness and content_hash. No payment required."
73
+ ),
74
+ "inputSchema": {
75
+ "type": "object",
76
+ "properties": {
77
+ "target_id": {
78
+ "type": "string",
79
+ "description": "The feed target id (e.g. 'runpod').",
80
+ },
81
+ },
82
+ "required": ["target_id"],
83
+ },
84
+ },
85
+ ]
86
+
87
+
88
+ def _ok(data: Any) -> dict[str, Any]:
89
+ return {"isError": False, "content": [{"type": "text", "text": json.dumps(data)}]}
90
+
91
+
92
+ def _error(message: str) -> dict[str, Any]:
93
+ return {"isError": True, "content": [{"type": "text", "text": message}]}
94
+
95
+
96
+ async def _search(args: dict[str, Any]) -> dict[str, Any]:
97
+ def _do() -> list[dict[str, Any]]:
98
+ resp = requests.get(
99
+ f"{_REGISTRY_URL}/listings/search",
100
+ params={"intent": args["intent"], "limit": args.get("limit", 5)},
101
+ timeout=15,
102
+ )
103
+ resp.raise_for_status()
104
+ return resp.json().get("listings", [])
105
+
106
+ return _ok(await asyncio.to_thread(_do))
107
+
108
+
109
+ async def _metadata(args: dict[str, Any]) -> dict[str, Any]:
110
+ def _do() -> dict[str, Any]:
111
+ resp = requests.get(f"{_FEED_URL}/meta", timeout=15)
112
+ resp.raise_for_status()
113
+ target_id = args["target_id"]
114
+ for target in resp.json().get("targets", []):
115
+ if target["target_id"] == target_id:
116
+ return target
117
+ raise ValueError(f"unknown target_id: {target_id}")
118
+
119
+ try:
120
+ result = await asyncio.to_thread(_do)
121
+ except ValueError as exc:
122
+ return _error(str(exc))
123
+ return _ok(result)
124
+
125
+
126
+ async def call_tool(name: str, arguments: dict[str, Any]) -> dict[str, Any]:
127
+ if name == "macaroons_search":
128
+ return await _search(arguments)
129
+ if name == "macaroons_metadata":
130
+ return await _metadata(arguments)
131
+ return _error(f"unknown tool: {name}")
132
+
133
+
134
+ def _build_mcp_server():
135
+ """Wires get_tool_definitions()/call_tool() into a real mcp.server.Server
136
+ for stdio use. Imported lazily so offline unit tests (which only need
137
+ get_tool_definitions()/call_tool()) never require the mcp package."""
138
+ import mcp.types as types
139
+ from mcp.server import Server
140
+ from mcp.server.stdio import stdio_server
141
+
142
+ async def on_list_tools(ctx, params):
143
+ tools = [
144
+ types.Tool(
145
+ name=t["name"], description=t["description"], input_schema=t["inputSchema"]
146
+ )
147
+ for t in get_tool_definitions()
148
+ ]
149
+ return types.ListToolsResult(tools=tools)
150
+
151
+ async def on_call_tool(ctx, params):
152
+ result = await call_tool(params.name, params.arguments or {})
153
+ content = [types.TextContent(type="text", text=item["text"]) for item in result["content"]]
154
+ return types.CallToolResult(content=content, is_error=result["isError"])
155
+
156
+ server = Server(
157
+ "macaroon-network",
158
+ version="0.1.0",
159
+ on_list_tools=on_list_tools,
160
+ on_call_tool=on_call_tool,
161
+ )
162
+ return server, stdio_server
163
+
164
+
165
+ async def _main() -> None:
166
+ server, stdio_server = _build_mcp_server()
167
+ async with stdio_server() as (read_stream, write_stream):
168
+ await server.run(read_stream, write_stream, server.create_initialization_options())
169
+
170
+
171
+ def main() -> None:
172
+ """Console-script entry point (see pyproject.toml [project.scripts])."""
173
+ asyncio.run(_main())
174
+
175
+
176
+ if __name__ == "__main__":
177
+ main()
@@ -0,0 +1,33 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "macaroonnetwork-mcp"
7
+ version = "0.1.0"
8
+ description = "Discovery-only MCP client for Macaroon Network -- search and inspect a live marketplace where AI agents pay per query in Bitcoin over Lightning."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "Kevin Smith" }]
13
+ keywords = ["mcp", "model-context-protocol", "agent-commerce", "l402", "lightning", "marketplace"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ ]
20
+ dependencies = [
21
+ "mcp>=1.0.0",
22
+ "requests>=2.31.0",
23
+ ]
24
+
25
+ [project.urls]
26
+ Homepage = "https://macaroonnetwork.com"
27
+ Repository = "https://github.com/kevmoz/macaroonnetwork"
28
+
29
+ [project.scripts]
30
+ macaroonnetwork-mcp = "macaroonnetwork_mcp.mcp_server:main"
31
+
32
+ [tool.hatch.build.targets.wheel]
33
+ packages = ["macaroonnetwork_mcp"]