axon-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,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: axon-mcp
3
+ Version: 0.1.0
4
+ Summary: Model Context Protocol (MCP) server for Axon Protocol
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: mcp>=0.1.0
8
+ Requires-Dist: httpx>=0.27.0
9
+
10
+ # Axon Model Context Protocol (MCP) Server
11
+
12
+ Exposes Axon's core backend capabilities as tools that can be run natively by AI agents.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install -e .
18
+ ```
19
+
20
+ ## Running
21
+
22
+ ```bash
23
+ axon-mcp
24
+ ```
@@ -0,0 +1,15 @@
1
+ # Axon Model Context Protocol (MCP) Server
2
+
3
+ Exposes Axon's core backend capabilities as tools that can be run natively by AI agents.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install -e .
9
+ ```
10
+
11
+ ## Running
12
+
13
+ ```bash
14
+ axon-mcp
15
+ ```
@@ -0,0 +1,3 @@
1
+ from axon_mcp.server import mcp, main
2
+
3
+ __all__ = ["mcp", "main"]
@@ -0,0 +1,245 @@
1
+ import os
2
+ import json
3
+ from pathlib import Path
4
+ from typing import Dict, Any, Optional
5
+ from mcp.server.fastmcp import FastMCP
6
+ import httpx
7
+
8
+ # FastMCP Server Instance
9
+ mcp = FastMCP("Axon Protocol")
10
+
11
+ def find_cwd_config() -> Optional[Path]:
12
+ config_path = Path.cwd() / ".axon"
13
+ if config_path.is_file():
14
+ return config_path
15
+ return None
16
+
17
+ def find_upward_config() -> Optional[Path]:
18
+ current = Path.cwd()
19
+ for parent in [current] + list(current.parents):
20
+ config_path = parent / ".axon"
21
+ if config_path.is_file():
22
+ return config_path
23
+ return None
24
+
25
+ def find_home_config() -> Optional[Path]:
26
+ home = Path.home()
27
+ # Try ~/.axon/config.json
28
+ config_json = home / ".axon" / "config.json"
29
+ if config_json.is_file():
30
+ return config_json
31
+ # Try ~/.axon
32
+ config_dot = home / ".axon"
33
+ if config_dot.is_file():
34
+ return config_dot
35
+ return None
36
+
37
+ def load_config() -> Dict[str, Any]:
38
+ # Default settings checking env first
39
+ config = {
40
+ "base_url": os.getenv("AXON_BASE_URL", "http://localhost:8000"),
41
+ "api_key": os.getenv("AXON_API_KEY"),
42
+ "project_id": os.getenv("AXON_PROJECT_ID"),
43
+ "agent_id": os.getenv("AXON_AGENT_ID"),
44
+ "agent_token": os.getenv("AXON_AGENT_TOKEN"),
45
+ }
46
+
47
+ # Try loading from local config files
48
+ config_path = find_cwd_config() or find_upward_config() or find_home_config()
49
+ if config_path:
50
+ try:
51
+ with open(config_path, "r", encoding="utf-8") as f:
52
+ data = json.load(f)
53
+ if isinstance(data, dict):
54
+ if "base_url" in data:
55
+ config["base_url"] = data["base_url"]
56
+ if "api_key" in data:
57
+ config["api_key"] = data["api_key"]
58
+ if "project_id" in data:
59
+ config["project_id"] = data["project_id"]
60
+ if "agent_id" in data:
61
+ config["agent_id"] = data["agent_id"]
62
+ if "agent_token" in data:
63
+ config["agent_token"] = data["agent_token"]
64
+ except Exception:
65
+ pass
66
+
67
+ return config
68
+
69
+ def get_client() -> httpx.Client:
70
+ config = load_config()
71
+ headers = {
72
+ "Content-Type": "application/json"
73
+ }
74
+ # If using local mode fallback defaults, inject default project key
75
+ api_key = config.get("api_key") or "axon-local-dev-key-384729"
76
+ headers["X-API-Key"] = api_key
77
+
78
+ if config.get("agent_id"):
79
+ headers["X-Agent-ID"] = config["agent_id"]
80
+ if config.get("agent_token"):
81
+ headers["Authorization"] = f"Bearer {config['agent_token']}"
82
+
83
+ return httpx.Client(
84
+ base_url=config["base_url"],
85
+ headers=headers,
86
+ timeout=10.0
87
+ )
88
+
89
+ @mcp.tool()
90
+ def axon_register_agent(name: str, capabilities: list[str]) -> str:
91
+ """Register a new agent in Axon.
92
+
93
+ Args:
94
+ name: Name of the agent.
95
+ capabilities: List of capability strings (e.g., ["coding", "planning"]).
96
+ """
97
+ config = load_config()
98
+ project_id = config.get("project_id") or "00000000-0000-0000-0000-000000000000"
99
+
100
+ with get_client() as client:
101
+ try:
102
+ resp = client.post("/v1/agents/register", json={
103
+ "name": name,
104
+ "project_id": project_id,
105
+ "capabilities": capabilities
106
+ })
107
+ if resp.status_code != 200:
108
+ return f"Error registering agent: {resp.text}"
109
+ data = resp.json()
110
+ return f"Agent registered successfully.\nAgent ID: {data.get('agent_id')}\nToken: {data.get('token')}"
111
+ except Exception as e:
112
+ return f"Error connecting to server: {str(e)}"
113
+
114
+ @mcp.tool()
115
+ def axon_store_memory(content: str, tags: dict = None, scope: str = "project", ttl: int = None) -> str:
116
+ """Store a text memory in Axon.
117
+
118
+ Args:
119
+ content: The text content of the memory.
120
+ tags: Optional dict of key-value tags.
121
+ scope: Scope of the memory ('project', 'private', or 'org'). Defaults to 'project'.
122
+ ttl: Optional Time-to-Live in seconds.
123
+ """
124
+ with get_client() as client:
125
+ try:
126
+ resp = client.post("/v1/memory/store", json={
127
+ "content": content,
128
+ "tags": tags or {},
129
+ "scope": scope,
130
+ "ttl": ttl
131
+ })
132
+ if resp.status_code != 200:
133
+ return f"Error storing memory: {resp.text}"
134
+ data = resp.json()
135
+ return f"Memory stored successfully.\nMemory ID: {data.get('id')}\nCreated At: {data.get('created_at')}"
136
+ except Exception as e:
137
+ return f"Error connecting to server: {str(e)}"
138
+
139
+ @mcp.tool()
140
+ def axon_search_memories(query: str, limit: int = 10, min_similarity: float = 0.3, scope: str = None) -> str:
141
+ """Search stored memories in Axon.
142
+
143
+ Args:
144
+ query: The semantic search query.
145
+ limit: Max number of results. Defaults to 10.
146
+ min_similarity: Threshold for similarity [0.0 - 1.0]. Defaults to 0.3.
147
+ scope: Optional scope filter.
148
+ """
149
+ with get_client() as client:
150
+ try:
151
+ payload = {
152
+ "query": query,
153
+ "limit": limit,
154
+ "min_similarity": min_similarity
155
+ }
156
+ if scope:
157
+ payload["scope"] = scope
158
+
159
+ resp = client.post("/v1/memory/search", json=payload)
160
+ if resp.status_code != 200:
161
+ return f"Error searching memories: {resp.text}"
162
+
163
+ data = resp.json()
164
+ results = data.get("results", [])
165
+ if not results:
166
+ return "No matching memories found."
167
+
168
+ output = []
169
+ for r in results:
170
+ output.append(
171
+ f"[{r.get('similarity', 0.0):.2f}] ID: {r.get('id')}\nContent: {r.get('content')}\nTags: {r.get('tags', {})}\n"
172
+ )
173
+ return "\n".join(output)
174
+ except Exception as e:
175
+ return f"Error connecting to server: {str(e)}"
176
+
177
+ @mcp.tool()
178
+ def axon_acquire_lock(resource_id: str, timeout: int = 300) -> str:
179
+ """Acquire a distributed lock.
180
+
181
+ Args:
182
+ resource_id: The ID of the resource to lock.
183
+ timeout: Expiry time in seconds. Defaults to 300.
184
+ """
185
+ with get_client() as client:
186
+ try:
187
+ resp = client.post("/v1/lock/acquire", json={
188
+ "resource_id": resource_id,
189
+ "timeout": timeout
190
+ })
191
+ if resp.status_code == 409:
192
+ return f"Conflict: Resource '{resource_id}' is already locked."
193
+ if resp.status_code != 200:
194
+ return f"Error acquiring lock: {resp.text}"
195
+ data = resp.json()
196
+ return f"Lock acquired successfully.\nLock ID: {data.get('lock_id')}\nExpires At: {data.get('expires_at')}"
197
+ except Exception as e:
198
+ return f"Error connecting to server: {str(e)}"
199
+
200
+ @mcp.tool()
201
+ def axon_release_lock(resource_id: str) -> str:
202
+ """Release a distributed lock.
203
+
204
+ Args:
205
+ resource_id: The ID of the resource to release.
206
+ """
207
+ with get_client() as client:
208
+ try:
209
+ resp = client.post(f"/v1/lock/release?resource_id={resource_id}")
210
+ if resp.status_code == 403:
211
+ return "Error: You do not own this lock."
212
+ if resp.status_code != 200:
213
+ return f"Error releasing lock: {resp.text}"
214
+ return f"Lock on resource '{resource_id}' released successfully."
215
+ except Exception as e:
216
+ return f"Error connecting to server: {str(e)}"
217
+
218
+ @mcp.tool()
219
+ def axon_create_receipt(input_data: str, steps: list[dict], output_data: str) -> str:
220
+ """Create a cryptographic reasoning receipt in Axon.
221
+
222
+ Args:
223
+ input_data: The initial input/prompt.
224
+ steps: List of logic step dicts (e.g., [{"step": 1, "action": "parse", "log": "..."}]).
225
+ output_data: The final generated response.
226
+ """
227
+ with get_client() as client:
228
+ try:
229
+ resp = client.post("/v1/receipts/create", json={
230
+ "input": input_data,
231
+ "steps": steps,
232
+ "output": output_data
233
+ })
234
+ if resp.status_code != 200:
235
+ return f"Error creating receipt: {resp.text}"
236
+ data = resp.json()
237
+ return f"Reasoning receipt uploaded.\nReceipt ID: {data.get('id')}\nChain Signature: {data.get('chain_hash')}"
238
+ except Exception as e:
239
+ return f"Error connecting to server: {str(e)}"
240
+
241
+ def main():
242
+ mcp.run()
243
+
244
+ if __name__ == "__main__":
245
+ main()
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: axon-mcp
3
+ Version: 0.1.0
4
+ Summary: Model Context Protocol (MCP) server for Axon Protocol
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: mcp>=0.1.0
8
+ Requires-Dist: httpx>=0.27.0
9
+
10
+ # Axon Model Context Protocol (MCP) Server
11
+
12
+ Exposes Axon's core backend capabilities as tools that can be run natively by AI agents.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install -e .
18
+ ```
19
+
20
+ ## Running
21
+
22
+ ```bash
23
+ axon-mcp
24
+ ```
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ axon_mcp/__init__.py
4
+ axon_mcp/server.py
5
+ axon_mcp.egg-info/PKG-INFO
6
+ axon_mcp.egg-info/SOURCES.txt
7
+ axon_mcp.egg-info/dependency_links.txt
8
+ axon_mcp.egg-info/entry_points.txt
9
+ axon_mcp.egg-info/requires.txt
10
+ axon_mcp.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ axon-mcp = axon_mcp.server:main
@@ -0,0 +1,2 @@
1
+ mcp>=0.1.0
2
+ httpx>=0.27.0
@@ -0,0 +1 @@
1
+ axon_mcp
@@ -0,0 +1,17 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "axon-mcp"
7
+ version = "0.1.0"
8
+ description = "Model Context Protocol (MCP) server for Axon Protocol"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = [
12
+ "mcp>=0.1.0",
13
+ "httpx>=0.27.0",
14
+ ]
15
+
16
+ [project.scripts]
17
+ axon-mcp = "axon_mcp.server:main"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+