agent-interface-standard 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,6 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ *.egg-info/
5
+ dist/
6
+ build/
@@ -0,0 +1,79 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-interface-standard
3
+ Version: 0.1.0
4
+ Summary: Schema.org for AI agents — the open standard for how businesses describe their services to AI agents
5
+ Project-URL: Homepage, https://github.com/AiAgentKarl/agent-interface-standard
6
+ Project-URL: Repository, https://github.com/AiAgentKarl/agent-interface-standard
7
+ Author: AiAgentKarl
8
+ License: MIT
9
+ Keywords: agent-interface,ai-agents,business,mcp,protocol,schema,standard
10
+ Requires-Python: >=3.10
11
+ Requires-Dist: httpx>=0.27.0
12
+ Requires-Dist: mcp>=1.0.0
13
+ Requires-Dist: pydantic>=2.0.0
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Agent Interface Standard 🌐
17
+
18
+ **Schema.org for AI Agents** — the open standard for how businesses describe their services to AI agents.
19
+
20
+ ## The Vision
21
+
22
+ Schema.org made websites machine-readable for search engines. **Agent Interface Standard** makes businesses machine-readable for AI agents.
23
+
24
+ Businesses publish a simple JSON spec at `/.well-known/agent-interface.json` describing what services they offer and how agents can interact with them.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pip install agent-interface-standard
30
+ ```
31
+
32
+ ```json
33
+ {"mcpServers": {"agent-interface": {"command": "uvx", "args": ["agent-interface-standard"]}}}
34
+ ```
35
+
36
+ ## Tools
37
+
38
+ | Tool | Description |
39
+ |------|-------------|
40
+ | `get_spec_template` | Get a blank template to fill out |
41
+ | `get_example_spec` | See a complete example (restaurant) |
42
+ | `validate_interface_spec` | Check your spec for errors |
43
+ | `register_business` | Register a business in the directory |
44
+ | `search_businesses` | Find agent-accessible businesses |
45
+ | `get_business_capabilities` | See what a business offers |
46
+ | `fetch_remote_spec` | Fetch a spec from a URL |
47
+
48
+ ## The Spec Format
49
+
50
+ ```json
51
+ {
52
+ "agent_interface": "0.1.0",
53
+ "business": {
54
+ "name": "My Business",
55
+ "description": "What we do",
56
+ "category": "e_commerce"
57
+ },
58
+ "capabilities": [
59
+ {
60
+ "name": "search_products",
61
+ "description": "Search our product catalog",
62
+ "type": "search",
63
+ "endpoint": "https://api.mybusiness.com/search",
64
+ "method": "GET",
65
+ "parameters": [...]
66
+ }
67
+ ],
68
+ "auth": {"type": "api_key"},
69
+ "pricing": {"model": "freemium"}
70
+ }
71
+ ```
72
+
73
+ ## Why This Matters
74
+
75
+ When AI agents become primary customers (not just humans), businesses need a standard way to be "agent-accessible." This is that standard.
76
+
77
+ ## License
78
+
79
+ MIT
@@ -0,0 +1,64 @@
1
+ # Agent Interface Standard 🌐
2
+
3
+ **Schema.org for AI Agents** — the open standard for how businesses describe their services to AI agents.
4
+
5
+ ## The Vision
6
+
7
+ Schema.org made websites machine-readable for search engines. **Agent Interface Standard** makes businesses machine-readable for AI agents.
8
+
9
+ Businesses publish a simple JSON spec at `/.well-known/agent-interface.json` describing what services they offer and how agents can interact with them.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ pip install agent-interface-standard
15
+ ```
16
+
17
+ ```json
18
+ {"mcpServers": {"agent-interface": {"command": "uvx", "args": ["agent-interface-standard"]}}}
19
+ ```
20
+
21
+ ## Tools
22
+
23
+ | Tool | Description |
24
+ |------|-------------|
25
+ | `get_spec_template` | Get a blank template to fill out |
26
+ | `get_example_spec` | See a complete example (restaurant) |
27
+ | `validate_interface_spec` | Check your spec for errors |
28
+ | `register_business` | Register a business in the directory |
29
+ | `search_businesses` | Find agent-accessible businesses |
30
+ | `get_business_capabilities` | See what a business offers |
31
+ | `fetch_remote_spec` | Fetch a spec from a URL |
32
+
33
+ ## The Spec Format
34
+
35
+ ```json
36
+ {
37
+ "agent_interface": "0.1.0",
38
+ "business": {
39
+ "name": "My Business",
40
+ "description": "What we do",
41
+ "category": "e_commerce"
42
+ },
43
+ "capabilities": [
44
+ {
45
+ "name": "search_products",
46
+ "description": "Search our product catalog",
47
+ "type": "search",
48
+ "endpoint": "https://api.mybusiness.com/search",
49
+ "method": "GET",
50
+ "parameters": [...]
51
+ }
52
+ ],
53
+ "auth": {"type": "api_key"},
54
+ "pricing": {"model": "freemium"}
55
+ }
56
+ ```
57
+
58
+ ## Why This Matters
59
+
60
+ When AI agents become primary customers (not just humans), businesses need a standard way to be "agent-accessible." This is that standard.
61
+
62
+ ## License
63
+
64
+ MIT
@@ -0,0 +1,24 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "agent-interface-standard"
7
+ version = "0.1.0"
8
+ description = "Schema.org for AI agents — the open standard for how businesses describe their services to AI agents"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.10"
12
+ authors = [{name = "AiAgentKarl"}]
13
+ keywords = ["mcp", "agent-interface", "schema", "standard", "business", "ai-agents", "protocol"]
14
+ dependencies = ["mcp>=1.0.0", "httpx>=0.27.0", "pydantic>=2.0.0"]
15
+
16
+ [project.urls]
17
+ Homepage = "https://github.com/AiAgentKarl/agent-interface-standard"
18
+ Repository = "https://github.com/AiAgentKarl/agent-interface-standard"
19
+
20
+ [project.scripts]
21
+ agent-interface = "src.server:main"
22
+
23
+ [tool.hatch.build.targets.wheel]
24
+ packages = ["src"]
File without changes
@@ -0,0 +1,173 @@
1
+ """Agent Interface Schema — der offene Standard für agent-lesbare Business-Beschreibungen.
2
+
3
+ Definiert das JSON-Format das Unternehmen veröffentlichen können,
4
+ damit AI-Agents ihre Services automatisch verstehen und nutzen können.
5
+ Vergleichbar mit Schema.org für Suchmaschinen, aber für AI-Agents.
6
+ """
7
+
8
+ import json
9
+ import sqlite3
10
+ from pathlib import Path
11
+ from datetime import datetime
12
+
13
+ DB_PATH = Path.home() / ".agent-interface" / "registry.db"
14
+
15
+ # Die Standard-Spec Version
16
+ SPEC_VERSION = "0.1.0"
17
+
18
+ # Beispiel einer Agent Interface Spec
19
+ EXAMPLE_SPEC = {
20
+ "agent_interface": SPEC_VERSION,
21
+ "business": {
22
+ "name": "Example Restaurant",
23
+ "description": "Italian restaurant with delivery",
24
+ "category": "food_delivery",
25
+ "website": "https://example-restaurant.com",
26
+ "location": {"city": "Berlin", "country": "DE"},
27
+ },
28
+ "capabilities": [
29
+ {
30
+ "name": "view_menu",
31
+ "description": "Browse the restaurant menu",
32
+ "type": "read",
33
+ "endpoint": "https://api.example-restaurant.com/menu",
34
+ "method": "GET",
35
+ "parameters": [
36
+ {"name": "category", "type": "string", "required": False,
37
+ "description": "Filter by category (pizza, pasta, salad)"}
38
+ ],
39
+ "returns": "List of menu items with prices",
40
+ "auth_required": False,
41
+ "rate_limit": "60/min",
42
+ },
43
+ {
44
+ "name": "place_order",
45
+ "description": "Place a delivery order",
46
+ "type": "transaction",
47
+ "endpoint": "https://api.example-restaurant.com/orders",
48
+ "method": "POST",
49
+ "parameters": [
50
+ {"name": "items", "type": "array", "required": True,
51
+ "description": "List of item IDs and quantities"},
52
+ {"name": "delivery_address", "type": "string", "required": True,
53
+ "description": "Full delivery address"},
54
+ {"name": "payment_method", "type": "string", "required": True,
55
+ "description": "Payment method (card, cash, x402)"},
56
+ ],
57
+ "returns": "Order confirmation with estimated delivery time",
58
+ "auth_required": True,
59
+ "cost": {"currency": "EUR", "estimate": "10-30"},
60
+ "confirmation_required": True,
61
+ },
62
+ {
63
+ "name": "track_order",
64
+ "description": "Track an existing order status",
65
+ "type": "read",
66
+ "endpoint": "https://api.example-restaurant.com/orders/{order_id}",
67
+ "method": "GET",
68
+ "parameters": [
69
+ {"name": "order_id", "type": "string", "required": True,
70
+ "description": "The order ID from place_order"}
71
+ ],
72
+ "returns": "Order status and estimated delivery time",
73
+ "auth_required": True,
74
+ },
75
+ ],
76
+ "auth": {
77
+ "type": "api_key",
78
+ "header": "X-API-Key",
79
+ "registration_url": "https://example-restaurant.com/developers",
80
+ },
81
+ "pricing": {
82
+ "model": "per_transaction",
83
+ "details": "Menu browsing is free. Orders are charged at menu prices.",
84
+ },
85
+ "contact": {
86
+ "support_email": "api@example-restaurant.com",
87
+ "docs_url": "https://docs.example-restaurant.com",
88
+ },
89
+ }
90
+
91
+ # Template-Spezifikation die Unternehmen ausfüllen können
92
+ BUSINESS_TEMPLATE = {
93
+ "agent_interface": SPEC_VERSION,
94
+ "business": {
95
+ "name": "",
96
+ "description": "",
97
+ "category": "",
98
+ "website": "",
99
+ "location": {"city": "", "country": ""},
100
+ },
101
+ "capabilities": [],
102
+ "auth": {"type": "none"},
103
+ "pricing": {"model": "free"},
104
+ "contact": {},
105
+ }
106
+
107
+ # Bekannte Business-Kategorien
108
+ CATEGORIES = [
109
+ "e_commerce", "food_delivery", "travel_booking", "financial_services",
110
+ "healthcare", "real_estate", "transportation", "education",
111
+ "entertainment", "professional_services", "saas", "marketplace",
112
+ "government", "utilities", "insurance", "logistics",
113
+ ]
114
+
115
+ # Capability-Typen
116
+ CAPABILITY_TYPES = [
117
+ "read", # Daten lesen (GET)
118
+ "write", # Daten schreiben (POST/PUT)
119
+ "transaction", # Kostenpflichtige Aktion
120
+ "search", # Suche
121
+ "booking", # Reservierung/Buchung
122
+ "subscription", # Abo-Verwaltung
123
+ "notification", # Benachrichtigungen
124
+ ]
125
+
126
+
127
+ def _get_db():
128
+ """Datenbank für registrierte Business-Interfaces."""
129
+ DB_PATH.parent.mkdir(parents=True, exist_ok=True)
130
+ conn = sqlite3.connect(str(DB_PATH))
131
+ conn.row_factory = sqlite3.Row
132
+ conn.execute("""
133
+ CREATE TABLE IF NOT EXISTS interfaces (
134
+ id TEXT PRIMARY KEY,
135
+ business_name TEXT NOT NULL,
136
+ description TEXT DEFAULT '',
137
+ category TEXT DEFAULT '',
138
+ spec_json TEXT NOT NULL,
139
+ capabilities_count INTEGER DEFAULT 0,
140
+ website TEXT DEFAULT '',
141
+ registered_at TEXT NOT NULL
142
+ )
143
+ """)
144
+ conn.commit()
145
+ return conn
146
+
147
+
148
+ def validate_spec(spec: dict) -> list[str]:
149
+ """Agent Interface Spec validieren. Gibt Liste von Fehlern zurück."""
150
+ errors = []
151
+
152
+ if "agent_interface" not in spec:
153
+ errors.append("Missing 'agent_interface' version field")
154
+
155
+ business = spec.get("business", {})
156
+ if not business.get("name"):
157
+ errors.append("Missing 'business.name'")
158
+ if not business.get("description"):
159
+ errors.append("Missing 'business.description'")
160
+
161
+ capabilities = spec.get("capabilities", [])
162
+ if not capabilities:
163
+ errors.append("No capabilities defined — at least one required")
164
+
165
+ for i, cap in enumerate(capabilities):
166
+ if not cap.get("name"):
167
+ errors.append(f"Capability {i}: missing 'name'")
168
+ if not cap.get("description"):
169
+ errors.append(f"Capability {i}: missing 'description'")
170
+ if not cap.get("endpoint"):
171
+ errors.append(f"Capability {i}: missing 'endpoint'")
172
+
173
+ return errors
@@ -0,0 +1,24 @@
1
+ """Agent Interface Standard — Schema.org for AI Agents."""
2
+
3
+ from mcp.server.fastmcp import FastMCP
4
+ from src.tools.standard_tools import register_standard_tools
5
+
6
+ mcp = FastMCP(
7
+ "Agent Interface Standard",
8
+ instructions=(
9
+ "The open standard for how businesses describe their services to AI agents. "
10
+ "Like Schema.org made websites machine-readable for search engines, "
11
+ "Agent Interface Standard makes businesses machine-readable for AI agents. "
12
+ "Create, validate, register and discover agent-accessible business interfaces."
13
+ ),
14
+ )
15
+
16
+ register_standard_tools(mcp)
17
+
18
+
19
+ def main():
20
+ mcp.run(transport="stdio")
21
+
22
+
23
+ if __name__ == "__main__":
24
+ main()
File without changes
@@ -0,0 +1,217 @@
1
+ """Standard-Tools — Agent Interface Specs erstellen, validieren und nutzen."""
2
+
3
+ import json
4
+ import httpx
5
+ from datetime import datetime
6
+ from mcp.server.fastmcp import FastMCP
7
+
8
+ from src.schema import (
9
+ SPEC_VERSION, EXAMPLE_SPEC, BUSINESS_TEMPLATE,
10
+ CATEGORIES, CAPABILITY_TYPES, validate_spec, _get_db,
11
+ )
12
+
13
+
14
+ def register_standard_tools(mcp: FastMCP):
15
+
16
+ @mcp.tool()
17
+ async def get_spec_template(category: str = "") -> dict:
18
+ """Get a blank Agent Interface spec template for a business.
19
+
20
+ Returns a template that businesses can fill out to make
21
+ their services accessible to AI agents. Like Schema.org markup
22
+ but for AI agents.
23
+
24
+ Args:
25
+ category: Business category for relevant examples (optional)
26
+ """
27
+ return {
28
+ "spec_version": SPEC_VERSION,
29
+ "template": BUSINESS_TEMPLATE,
30
+ "available_categories": CATEGORIES,
31
+ "capability_types": CAPABILITY_TYPES,
32
+ "instructions": (
33
+ "Fill out the template with your business details and capabilities. "
34
+ "Each capability describes one action an AI agent can take. "
35
+ "Use validate_spec to check your spec before publishing."
36
+ ),
37
+ }
38
+
39
+ @mcp.tool()
40
+ async def get_example_spec() -> dict:
41
+ """Get a complete example Agent Interface spec.
42
+
43
+ Shows a fully filled-out spec for a restaurant with
44
+ menu browsing, ordering, and order tracking capabilities.
45
+ Use this as a reference when creating your own spec.
46
+ """
47
+ return {
48
+ "description": "Complete example spec for a restaurant business",
49
+ "spec": EXAMPLE_SPEC,
50
+ "note": "This shows all supported fields. Not all fields are required.",
51
+ }
52
+
53
+ @mcp.tool()
54
+ async def validate_interface_spec(spec_json: str) -> dict:
55
+ """Validate an Agent Interface spec for correctness.
56
+
57
+ Checks that all required fields are present and properly formatted.
58
+ Returns a list of errors if the spec is invalid.
59
+
60
+ Args:
61
+ spec_json: The spec as a JSON string
62
+ """
63
+ try:
64
+ spec = json.loads(spec_json)
65
+ except json.JSONDecodeError as e:
66
+ return {"valid": False, "errors": [f"Invalid JSON: {e}"]}
67
+
68
+ errors = validate_spec(spec)
69
+
70
+ if errors:
71
+ return {"valid": False, "errors": errors, "error_count": len(errors)}
72
+
73
+ caps = spec.get("capabilities", [])
74
+ return {
75
+ "valid": True,
76
+ "spec_version": spec.get("agent_interface", "unknown"),
77
+ "business": spec.get("business", {}).get("name", ""),
78
+ "capabilities_count": len(caps),
79
+ "message": "Spec is valid and ready to publish.",
80
+ }
81
+
82
+ @mcp.tool()
83
+ async def register_business(spec_json: str, business_id: str = "") -> dict:
84
+ """Register a business interface spec in the local directory.
85
+
86
+ Makes the business discoverable by agents through search_businesses.
87
+ The spec is stored locally and persists between sessions.
88
+
89
+ Args:
90
+ spec_json: The complete Agent Interface spec as JSON
91
+ business_id: Custom ID (auto-generated from business name if empty)
92
+ """
93
+ try:
94
+ spec = json.loads(spec_json)
95
+ except json.JSONDecodeError as e:
96
+ return {"error": f"Invalid JSON: {e}"}
97
+
98
+ errors = validate_spec(spec)
99
+ if errors:
100
+ return {"error": "Invalid spec", "errors": errors}
101
+
102
+ business = spec.get("business", {})
103
+ name = business.get("name", "Unknown")
104
+
105
+ if not business_id:
106
+ business_id = name.lower().replace(" ", "-").replace(".", "-")[:50]
107
+
108
+ conn = _get_db()
109
+ conn.execute("""
110
+ INSERT OR REPLACE INTO interfaces
111
+ (id, business_name, description, category, spec_json,
112
+ capabilities_count, website, registered_at)
113
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
114
+ """, (
115
+ business_id, name, business.get("description", ""),
116
+ business.get("category", ""),
117
+ json.dumps(spec), len(spec.get("capabilities", [])),
118
+ business.get("website", ""), datetime.utcnow().isoformat(),
119
+ ))
120
+ conn.commit()
121
+
122
+ return {
123
+ "status": "registered",
124
+ "business_id": business_id,
125
+ "name": name,
126
+ "capabilities": len(spec.get("capabilities", [])),
127
+ }
128
+
129
+ @mcp.tool()
130
+ async def search_businesses(query: str, category: str = "") -> dict:
131
+ """Search for agent-accessible businesses.
132
+
133
+ Find businesses that have published Agent Interface specs,
134
+ making their services available to AI agents.
135
+
136
+ Args:
137
+ query: Search term (e.g. "restaurant", "booking", "delivery")
138
+ category: Filter by category (optional)
139
+ """
140
+ conn = _get_db()
141
+ q = f"%{query.lower()}%"
142
+
143
+ if category:
144
+ rows = conn.execute("""
145
+ SELECT id, business_name, description, category, capabilities_count, website
146
+ FROM interfaces
147
+ WHERE (LOWER(business_name) LIKE ? OR LOWER(description) LIKE ?)
148
+ AND LOWER(category) LIKE ?
149
+ ORDER BY business_name LIMIT 20
150
+ """, (q, q, f"%{category.lower()}%")).fetchall()
151
+ else:
152
+ rows = conn.execute("""
153
+ SELECT id, business_name, description, category, capabilities_count, website
154
+ FROM interfaces
155
+ WHERE LOWER(business_name) LIKE ? OR LOWER(description) LIKE ?
156
+ ORDER BY business_name LIMIT 20
157
+ """, (q, q)).fetchall()
158
+
159
+ results = [dict(r) for r in rows]
160
+ return {"query": query, "results_count": len(results), "businesses": results}
161
+
162
+ @mcp.tool()
163
+ async def get_business_capabilities(business_id: str) -> dict:
164
+ """Get all capabilities of a registered business.
165
+
166
+ Returns the full spec including all available actions
167
+ an agent can take with this business.
168
+
169
+ Args:
170
+ business_id: Business ID (from search_businesses)
171
+ """
172
+ conn = _get_db()
173
+ row = conn.execute(
174
+ "SELECT * FROM interfaces WHERE id = ?", (business_id,)
175
+ ).fetchone()
176
+
177
+ if not row:
178
+ return {"error": f"Business '{business_id}' not found"}
179
+
180
+ spec = json.loads(row["spec_json"])
181
+ return {
182
+ "business_id": business_id,
183
+ "business": spec.get("business", {}),
184
+ "capabilities": spec.get("capabilities", []),
185
+ "auth": spec.get("auth", {}),
186
+ "pricing": spec.get("pricing", {}),
187
+ "contact": spec.get("contact", {}),
188
+ }
189
+
190
+ @mcp.tool()
191
+ async def fetch_remote_spec(url: str) -> dict:
192
+ """Fetch an Agent Interface spec from a remote URL.
193
+
194
+ Businesses can host their spec at a well-known URL
195
+ (e.g. example.com/.well-known/agent-interface.json).
196
+ This tool fetches and validates it.
197
+
198
+ Args:
199
+ url: URL to the Agent Interface spec JSON
200
+ """
201
+ async with httpx.AsyncClient(timeout=15) as client:
202
+ resp = await client.get(url)
203
+ resp.raise_for_status()
204
+ spec = resp.json()
205
+
206
+ errors = validate_spec(spec)
207
+ business = spec.get("business", {})
208
+
209
+ return {
210
+ "url": url,
211
+ "valid": len(errors) == 0,
212
+ "errors": errors if errors else None,
213
+ "business_name": business.get("name", "Unknown"),
214
+ "capabilities_count": len(spec.get("capabilities", [])),
215
+ "spec": spec if len(errors) == 0 else None,
216
+ "hint": "Use register_business to add this to your local directory." if not errors else None,
217
+ }