agent-negotiation-mcp 1.0.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,26 @@
1
+ name: Publish to Smithery
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ name: Publish MCP Server to Smithery
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: read
13
+ steps:
14
+ - name: Checkout repository
15
+ uses: actions/checkout@v4
16
+
17
+ - name: Setup Node.js
18
+ uses: actions/setup-node@v4
19
+ with:
20
+ node-version: '20'
21
+
22
+ - name: Publish to Smithery
23
+ env:
24
+ SMITHERY_API_KEY: ${{ secrets.SMITHERY_API_KEY }}
25
+ run: |
26
+ npx @smithery/cli mcp publish "https://github.com/${{ github.repository }}" -n nicholastempleman/${{ github.event.repository.name }}
@@ -0,0 +1,3 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .env
@@ -0,0 +1,126 @@
1
+ {
2
+ "name": "agent-negotiation-mcp",
3
+ "description": "> **By [MEOK AI Labs](https://meok.ai)** \u2014 Multi-agent negotiation framework. Propose deals, evaluate offers, run auctions, and optimize outcom",
4
+ "version": "1.0.0",
5
+ "tools": [
6
+ {
7
+ "name": "propose_deal",
8
+ "description": "Propose a deal between two agents with terms and pricing.",
9
+ "parameters": {
10
+ "type": "object",
11
+ "properties": {
12
+ "proposer": {
13
+ "type": "string"
14
+ },
15
+ "receiver": {
16
+ "type": "string"
17
+ },
18
+ "terms": {
19
+ "type": "string"
20
+ },
21
+ "price": {
22
+ "type": "number"
23
+ },
24
+ "deadline_hours": {
25
+ "type": "integer"
26
+ }
27
+ },
28
+ "required": [
29
+ "proposer",
30
+ "receiver",
31
+ "terms"
32
+ ]
33
+ }
34
+ },
35
+ {
36
+ "name": "evaluate_offer",
37
+ "description": "Evaluate an offer using negotiation theory (BATNA, ZOPA, Nash).",
38
+ "parameters": {
39
+ "type": "object",
40
+ "properties": {
41
+ "price": {
42
+ "type": "number"
43
+ },
44
+ "reservation_price": {
45
+ "type": "number"
46
+ },
47
+ "best_alternative": {
48
+ "type": "number"
49
+ },
50
+ "urgency": {
51
+ "type": "number"
52
+ }
53
+ },
54
+ "required": [
55
+ "price",
56
+ "reservation_price"
57
+ ]
58
+ }
59
+ },
60
+ {
61
+ "name": "counter_offer",
62
+ "description": "Submit a counter-offer on an existing negotiation.",
63
+ "parameters": {
64
+ "type": "object",
65
+ "properties": {
66
+ "deal_id": {
67
+ "type": "string"
68
+ },
69
+ "agent": {
70
+ "type": "string"
71
+ },
72
+ "new_price": {
73
+ "type": "number"
74
+ },
75
+ "new_terms": {
76
+ "type": "string"
77
+ }
78
+ },
79
+ "required": [
80
+ "deal_id",
81
+ "agent",
82
+ "new_price"
83
+ ]
84
+ }
85
+ },
86
+ {
87
+ "name": "run_auction",
88
+ "description": "Run a simulated auction. Bids as JSON: [{\"bidder\": \"A\", \"amount\": 100}, ...]",
89
+ "parameters": {
90
+ "type": "object",
91
+ "properties": {
92
+ "item": {
93
+ "type": "string"
94
+ },
95
+ "starting_price": {
96
+ "type": "number"
97
+ },
98
+ "bids": {
99
+ "type": "string"
100
+ },
101
+ "auction_type": {
102
+ "type": "string"
103
+ }
104
+ },
105
+ "required": [
106
+ "item",
107
+ "starting_price",
108
+ "bids"
109
+ ]
110
+ }
111
+ },
112
+ {
113
+ "name": "negotiation_status",
114
+ "description": "Get status of a negotiation or list all active negotiations.",
115
+ "parameters": {
116
+ "type": "object",
117
+ "properties": {
118
+ "deal_id": {
119
+ "type": "string"
120
+ }
121
+ },
122
+ "required": []
123
+ }
124
+ }
125
+ ]
126
+ }
@@ -0,0 +1,2 @@
1
+ MIT License
2
+ Copyright (c) 2026 MEOK AI Labs
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-negotiation-mcp
3
+ Version: 1.0.0
4
+ Summary: MEOK AI Labs — agent-negotiation-mcp
5
+ Project-URL: Homepage, https://meok.ai
6
+ Project-URL: Repository, https://github.com/CSOAI-ORG/agent-negotiation-mcp
7
+ Author-email: MEOK AI Labs <nicholas@meok.ai>
8
+ License: MIT License
9
+ Copyright (c) 2026 MEOK AI Labs
10
+ License-File: LICENSE
11
+ Keywords: agent,ai,mcp,meok,negotiation
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Software Development :: Libraries
16
+ Requires-Python: >=3.10
17
+ Requires-Dist: mcp>=1.0.0
@@ -0,0 +1,6 @@
1
+ # Uagent negotiation MCP Server
2
+
3
+ MEOK AI Labs - AI Governance & Compliance
4
+
5
+ Install: pip install agent-negotiation-mcp
6
+ Contact: nick@meok.ai
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "agent-negotiation-mcp",
3
+ "version": "1.0.0",
4
+ "author": "MEOK AI Labs",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/CSOAI-ORG/agent-negotiation-mcp"
9
+ },
10
+ "dependencies": {
11
+ "mcp": "^1.0.0"
12
+ }
13
+ }
@@ -0,0 +1,24 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+ [project]
5
+ name = "agent-negotiation-mcp"
6
+ version = "1.0.0"
7
+ description = "MEOK AI Labs — agent-negotiation-mcp"
8
+ license = {file = "LICENSE"}
9
+ requires-python = ">=3.10"
10
+ authors = [{name = "MEOK AI Labs", email = "nicholas@meok.ai"}]
11
+ dependencies = ["mcp>=1.0.0"]
12
+ keywords = ["mcp", "ai", "meok", "agent", "negotiation"]
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Operating System :: OS Independent",
17
+ "Topic :: Software Development :: Libraries",
18
+ ]
19
+ [project.urls]
20
+ Homepage = "https://meok.ai"
21
+ Repository = "https://github.com/CSOAI-ORG/agent-negotiation-mcp"
22
+ [tool.hatch.build.targets.wheel]
23
+ packages = ["."]
24
+ only-include = ["server.py"]
@@ -0,0 +1,221 @@
1
+ #!/usr/bin/env python3
2
+ """Agent Negotiation MCP — MEOK AI Labs. Multi-agent negotiation protocols, deal evaluation, and strategy."""
3
+
4
+ import sys, os
5
+ sys.path.insert(0, os.path.expanduser('~/clawd/meok-labs-engine/shared'))
6
+ from auth_middleware import check_access
7
+
8
+ import json, hashlib, time, math
9
+ from datetime import datetime, timezone
10
+ from collections import defaultdict
11
+ from mcp.server.fastmcp import FastMCP
12
+
13
+ FREE_DAILY_LIMIT = 15
14
+ _usage = defaultdict(list)
15
+ def _rl(c="anon"):
16
+ now = datetime.now(timezone.utc)
17
+ _usage[c] = [t for t in _usage[c] if (now-t).total_seconds() < 86400]
18
+ if len(_usage[c]) >= FREE_DAILY_LIMIT: return json.dumps({"error": f"Limit {FREE_DAILY_LIMIT}/day"})
19
+ _usage[c].append(now); return None
20
+
21
+ mcp = FastMCP("agent-negotiation", instructions="Multi-agent negotiation framework. Propose deals, evaluate offers, run auctions, and optimize outcomes. By MEOK AI Labs.")
22
+
23
+ _NEGOTIATIONS: dict[str, dict] = {}
24
+ _OFFERS: list[dict] = []
25
+
26
+
27
+ @mcp.tool()
28
+ def propose_deal(proposer: str, receiver: str, terms: str, price: float = 0, deadline_hours: int = 24, api_key: str = "") -> str:
29
+ """Propose a deal between two agents with terms and pricing."""
30
+ allowed, msg, tier = check_access(api_key)
31
+ if not allowed:
32
+ return {"error": msg, "upgrade_url": "https://meok.ai/pricing"}
33
+ if err := _rl(): return err
34
+
35
+ deal_id = f"deal-{hashlib.sha256(f'{proposer}{receiver}{time.time_ns()}'.encode()).hexdigest()[:12]}"
36
+ now = datetime.now(timezone.utc)
37
+
38
+ deal = {
39
+ "deal_id": deal_id,
40
+ "proposer": proposer,
41
+ "receiver": receiver,
42
+ "terms": terms,
43
+ "price": price,
44
+ "status": "proposed",
45
+ "created_at": now.isoformat(),
46
+ "deadline": (now.replace(hour=now.hour + deadline_hours) if deadline_hours < 24 else now).isoformat(),
47
+ "rounds": 1,
48
+ "history": [{"round": 1, "action": "propose", "agent": proposer, "price": price, "terms": terms}],
49
+ }
50
+ _NEGOTIATIONS[deal_id] = deal
51
+
52
+ return {
53
+ "deal_id": deal_id,
54
+ "status": "proposed",
55
+ "from": proposer,
56
+ "to": receiver,
57
+ "price": price,
58
+ "suggested_counter": round(price * 0.85, 2),
59
+ "fair_range": {"low": round(price * 0.75, 2), "high": round(price * 1.1, 2)},
60
+ }
61
+
62
+
63
+ @mcp.tool()
64
+ def evaluate_offer(price: float, reservation_price: float, best_alternative: float = 0, urgency: float = 0.5, api_key: str = "") -> str:
65
+ """Evaluate an offer using negotiation theory (BATNA, ZOPA, Nash)."""
66
+ allowed, msg, tier = check_access(api_key)
67
+ if not allowed:
68
+ return {"error": msg, "upgrade_url": "https://meok.ai/pricing"}
69
+ if err := _rl(): return err
70
+
71
+ batna = best_alternative if best_alternative > 0 else reservation_price * 0.7
72
+ zopa_exists = price <= reservation_price
73
+ surplus = reservation_price - price if zopa_exists else 0
74
+
75
+ # Nash bargaining solution
76
+ nash_price = (price + reservation_price) / 2
77
+
78
+ # Urgency-adjusted recommendation
79
+ urgency = max(0, min(1, urgency))
80
+ accept_threshold = reservation_price * (1 - 0.15 * (1 - urgency))
81
+
82
+ if price <= accept_threshold:
83
+ recommendation = "ACCEPT"
84
+ confidence = min(100, round((1 - price / reservation_price) * 200))
85
+ elif price <= reservation_price:
86
+ recommendation = "COUNTER"
87
+ counter_price = round(nash_price * (1 - 0.05 * urgency), 2)
88
+ confidence = 60
89
+ else:
90
+ recommendation = "REJECT"
91
+ confidence = min(100, round((price / reservation_price - 1) * 200))
92
+
93
+ return {
94
+ "offer_price": price,
95
+ "reservation_price": reservation_price,
96
+ "batna": round(batna, 2),
97
+ "zopa_exists": zopa_exists,
98
+ "surplus": round(surplus, 2),
99
+ "nash_solution": round(nash_price, 2),
100
+ "recommendation": recommendation,
101
+ "confidence": confidence,
102
+ "suggested_counter": round(nash_price, 2) if recommendation == "COUNTER" else None,
103
+ "urgency_factor": urgency,
104
+ }
105
+
106
+
107
+ @mcp.tool()
108
+ def counter_offer(deal_id: str, agent: str, new_price: float, new_terms: str = "", api_key: str = "") -> str:
109
+ """Submit a counter-offer on an existing negotiation."""
110
+ allowed, msg, tier = check_access(api_key)
111
+ if not allowed:
112
+ return {"error": msg, "upgrade_url": "https://meok.ai/pricing"}
113
+ if err := _rl(): return err
114
+
115
+ if deal_id not in _NEGOTIATIONS:
116
+ return {"error": "Deal not found"}
117
+
118
+ deal = _NEGOTIATIONS[deal_id]
119
+ deal["rounds"] += 1
120
+ deal["price"] = new_price
121
+ if new_terms:
122
+ deal["terms"] = new_terms
123
+ deal["status"] = "counter-offered"
124
+ deal["history"].append({
125
+ "round": deal["rounds"],
126
+ "action": "counter",
127
+ "agent": agent,
128
+ "price": new_price,
129
+ "terms": new_terms or deal["terms"],
130
+ })
131
+
132
+ # Calculate convergence
133
+ prices = [h["price"] for h in deal["history"]]
134
+ if len(prices) >= 2:
135
+ convergence = round(abs(prices[-1] - prices[-2]) / max(prices) * 100, 1)
136
+ else:
137
+ convergence = 100
138
+
139
+ return {
140
+ "deal_id": deal_id,
141
+ "round": deal["rounds"],
142
+ "new_price": new_price,
143
+ "convergence_pct": convergence,
144
+ "likely_settlement": round(sum(prices[-2:]) / 2, 2) if len(prices) >= 2 else new_price,
145
+ "status": "counter-offered",
146
+ }
147
+
148
+
149
+ @mcp.tool()
150
+ def run_auction(item: str, starting_price: float, bids: str, auction_type: str = "english", api_key: str = "") -> str:
151
+ """Run a simulated auction. Bids as JSON: [{"bidder": "A", "amount": 100}, ...]"""
152
+ allowed, msg, tier = check_access(api_key)
153
+ if not allowed:
154
+ return {"error": msg, "upgrade_url": "https://meok.ai/pricing"}
155
+ if err := _rl(): return err
156
+
157
+ try:
158
+ bid_list = json.loads(bids)
159
+ except json.JSONDecodeError:
160
+ return {"error": "Invalid bids JSON. Format: [{\"bidder\": \"A\", \"amount\": 100}]"}
161
+
162
+ if not bid_list:
163
+ return {"error": "No bids provided"}
164
+
165
+ auction_type = auction_type.lower()
166
+
167
+ if auction_type == "english":
168
+ # Highest bid wins
169
+ sorted_bids = sorted(bid_list, key=lambda b: b["amount"], reverse=True)
170
+ winner = sorted_bids[0]
171
+ price = winner["amount"]
172
+ elif auction_type == "vickrey":
173
+ # Highest bid wins, pays second-highest price
174
+ sorted_bids = sorted(bid_list, key=lambda b: b["amount"], reverse=True)
175
+ winner = sorted_bids[0]
176
+ price = sorted_bids[1]["amount"] if len(sorted_bids) > 1 else winner["amount"]
177
+ elif auction_type == "dutch":
178
+ # First bid at or above starting price wins
179
+ winner = None
180
+ price = starting_price
181
+ for bid in bid_list:
182
+ if bid["amount"] >= starting_price:
183
+ winner = bid
184
+ price = bid["amount"]
185
+ break
186
+ if not winner:
187
+ return {"item": item, "status": "no_sale", "reason": "No bid met the starting price"}
188
+ else:
189
+ return {"error": f"Unknown auction type. Supported: english, vickrey, dutch"}
190
+
191
+ return {
192
+ "item": item,
193
+ "auction_type": auction_type,
194
+ "winner": winner["bidder"],
195
+ "winning_bid": winner["amount"],
196
+ "price_paid": price,
197
+ "starting_price": starting_price,
198
+ "total_bids": len(bid_list),
199
+ "bid_spread": round(max(b["amount"] for b in bid_list) - min(b["amount"] for b in bid_list), 2),
200
+ }
201
+
202
+
203
+ @mcp.tool()
204
+ def negotiation_status(deal_id: str = "", api_key: str = "") -> str:
205
+ """Get status of a negotiation or list all active negotiations."""
206
+ allowed, msg, tier = check_access(api_key)
207
+ if not allowed:
208
+ return {"error": msg, "upgrade_url": "https://meok.ai/pricing"}
209
+ if err := _rl(): return err
210
+
211
+ if deal_id:
212
+ if deal_id not in _NEGOTIATIONS:
213
+ return {"error": "Deal not found"}
214
+ return _NEGOTIATIONS[deal_id]
215
+
216
+ active = [{"deal_id": did, "parties": f"{d['proposer']} ↔ {d['receiver']}", "price": d["price"], "rounds": d["rounds"], "status": d["status"]} for did, d in _NEGOTIATIONS.items()]
217
+ return {"active_negotiations": active, "total": len(active)}
218
+
219
+
220
+ if __name__ == "__main__":
221
+ mcp.run()
@@ -0,0 +1,75 @@
1
+ name: agent-negotiation-mcp
2
+ description: Multi-agent negotiation framework. Propose deals, evaluate offers, run
3
+ auctions, and optimize outcom
4
+ version: 1.0.0
5
+ tools:
6
+ - name: propose_deal
7
+ description: Propose a deal between two agents with terms and pricing.
8
+ parameters:
9
+ - name: proposer
10
+ type: string
11
+ required: true
12
+ - name: receiver
13
+ type: string
14
+ required: true
15
+ - name: terms
16
+ type: string
17
+ required: true
18
+ - name: price
19
+ type: number
20
+ required: false
21
+ - name: deadline_hours
22
+ type: integer
23
+ required: false
24
+ - name: evaluate_offer
25
+ description: Evaluate an offer using negotiation theory (BATNA, ZOPA, Nash).
26
+ parameters:
27
+ - name: price
28
+ type: number
29
+ required: true
30
+ - name: reservation_price
31
+ type: number
32
+ required: true
33
+ - name: best_alternative
34
+ type: number
35
+ required: false
36
+ - name: urgency
37
+ type: number
38
+ required: false
39
+ - name: counter_offer
40
+ description: Submit a counter-offer on an existing negotiation.
41
+ parameters:
42
+ - name: deal_id
43
+ type: string
44
+ required: true
45
+ - name: agent
46
+ type: string
47
+ required: true
48
+ - name: new_price
49
+ type: number
50
+ required: true
51
+ - name: new_terms
52
+ type: string
53
+ required: false
54
+ - name: run_auction
55
+ description: 'Run a simulated auction. Bids as JSON: [{"bidder": "A", "amount":
56
+ 100}, ...]'
57
+ parameters:
58
+ - name: item
59
+ type: string
60
+ required: true
61
+ - name: starting_price
62
+ type: number
63
+ required: true
64
+ - name: bids
65
+ type: string
66
+ required: true
67
+ - name: auction_type
68
+ type: string
69
+ required: false
70
+ - name: negotiation_status
71
+ description: Get status of a negotiation or list all active negotiations.
72
+ parameters:
73
+ - name: deal_id
74
+ type: string
75
+ required: false