agentguardproxy 0.2.0__tar.gz → 0.2.2__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.
Files changed (19) hide show
  1. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/PKG-INFO +145 -142
  2. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/README.md +5 -5
  3. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/agentguard/__init__.py +47 -18
  4. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/agentguard/adapters/browseruse.py +2 -2
  5. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/agentguard/adapters/crewai.py +2 -2
  6. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/agentguard/adapters/langchain.py +2 -2
  7. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/agentguard/adapters/mcp.py +8 -4
  8. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/agentguardproxy.egg-info/PKG-INFO +145 -142
  9. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/agentguardproxy.egg-info/SOURCES.txt +5 -1
  10. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/agentguardproxy.egg-info/requires.txt +4 -0
  11. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/pyproject.toml +5 -1
  12. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/setup.cfg +4 -4
  13. agentguardproxy-0.2.2/tests/test_adapters.py +216 -0
  14. agentguardproxy-0.2.2/tests/test_decorator.py +79 -0
  15. agentguardproxy-0.2.2/tests/test_guard.py +171 -0
  16. agentguardproxy-0.2.2/tests/test_integration.py +102 -0
  17. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/agentguard/adapters/__init__.py +0 -0
  18. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/agentguardproxy.egg-info/dependency_links.txt +0 -0
  19. {agentguardproxy-0.2.0 → agentguardproxy-0.2.2}/agentguardproxy.egg-info/top_level.txt +0 -0
@@ -1,142 +1,145 @@
1
- Metadata-Version: 2.4
2
- Name: agentguardproxy
3
- Version: 0.2.0
4
- Summary: Python SDK for AgentGuard — the firewall for AI agents
5
- Author: AgentGuard Contributors
6
- License-Expression: Apache-2.0
7
- Project-URL: Homepage, https://github.com/Caua-ferraz/AgentGuard
8
- Project-URL: Repository, https://github.com/Caua-ferraz/AgentGuard
9
- Project-URL: Documentation, https://github.com/Caua-ferraz/AgentGuard/blob/master/docs/SETUP.md
10
- Project-URL: Issues, https://github.com/Caua-ferraz/AgentGuard/issues
11
- Keywords: ai,agents,firewall,policy,guardrails,safety
12
- Classifier: Development Status :: 3 - Alpha
13
- Classifier: Intended Audience :: Developers
14
- Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.8
16
- Classifier: Programming Language :: Python :: 3.9
17
- Classifier: Programming Language :: Python :: 3.10
18
- Classifier: Programming Language :: Python :: 3.11
19
- Classifier: Programming Language :: Python :: 3.12
20
- Classifier: Programming Language :: Python :: 3.13
21
- Classifier: Topic :: Security
22
- Classifier: Topic :: Software Development :: Libraries
23
- Requires-Python: >=3.8
24
- Description-Content-Type: text/markdown
25
- Provides-Extra: langchain
26
- Requires-Dist: langchain>=0.1.0; extra == "langchain"
27
- Provides-Extra: crewai
28
- Requires-Dist: crewai>=0.1.0; extra == "crewai"
29
- Provides-Extra: browser-use
30
- Requires-Dist: browser-use>=0.1.0; extra == "browser-use"
31
- Provides-Extra: mcp
32
- Provides-Extra: all
33
- Requires-Dist: langchain>=0.1.0; extra == "all"
34
- Requires-Dist: crewai>=0.1.0; extra == "all"
35
- Requires-Dist: browser-use>=0.1.0; extra == "all"
36
-
37
- # AgentGuard Python SDK
38
-
39
- Lightweight Python client for [AgentGuard](https://github.com/Caua-ferraz/AgentGuard) — the firewall for AI agents.
40
-
41
- ## Install
42
-
43
- ```bash
44
- pip install agentguard
45
-
46
- # With framework adapters
47
- pip install agentguard[langchain]
48
- pip install agentguard[crewai]
49
- pip install agentguard[browser-use]
50
- pip install agentguard[all]
51
- ```
52
-
53
- ## Quick Start
54
-
55
- ```python
56
- from agentguard import Guard
57
-
58
- guard = Guard("http://localhost:8080", agent_id="my-agent")
59
-
60
- # Check before executing
61
- result = guard.check("shell", command="rm -rf ./old_data")
62
-
63
- if result.allowed:
64
- execute(command)
65
- elif result.needs_approval:
66
- print(f"Approve at: {result.approval_url}")
67
- else:
68
- print(f"Blocked: {result.reason}")
69
- ```
70
-
71
- ## Framework Adapters
72
-
73
- ### LangChain
74
-
75
- ```python
76
- from agentguard.adapters.langchain import GuardedToolkit
77
-
78
- toolkit = GuardedToolkit(
79
- tools=my_tools,
80
- guard_url="http://localhost:8080",
81
- agent_id="langchain-agent",
82
- )
83
-
84
- agent = create_react_agent(llm, toolkit.tools, prompt)
85
- ```
86
-
87
- ### CrewAI
88
-
89
- ```python
90
- from agentguard.adapters.crewai import guard_crew_tools
91
-
92
- guarded_tools = guard_crew_tools(
93
- tools=my_crew_tools,
94
- guard_url="http://localhost:8080",
95
- agent_id="crew-agent",
96
- )
97
- ```
98
-
99
- ### browser-use
100
-
101
- ```python
102
- from agentguard.adapters.browseruse import GuardedBrowser
103
-
104
- browser = GuardedBrowser(guard_url="http://localhost:8080")
105
-
106
- result = browser.check_navigation("https://example.com")
107
- if result.allowed:
108
- await page.goto("https://example.com")
109
- ```
110
-
111
- ### MCP
112
-
113
- ```python
114
- from agentguard.adapters.mcp import GuardedMCPServer
115
-
116
- server = GuardedMCPServer(guard_url="http://localhost:8080")
117
- server.add_tool("my_tool", "Description", handler=my_handler)
118
- server.run() # Starts stdio MCP server
119
- ```
120
-
121
- ## API Reference
122
-
123
- ### `Guard(base_url, agent_id="")`
124
- - `check(scope, *, action, command, path, domain, url, meta)` — Check an action against policy
125
- - `approve(approval_id)` — Approve a pending action
126
- - `deny(approval_id)` — Deny a pending action
127
- - `wait_for_approval(approval_id, timeout=300)` — Block until resolved
128
-
129
- ### `CheckResult`
130
- - `.allowed` — True if action is permitted
131
- - `.denied` — True if action is blocked
132
- - `.needs_approval` — True if human approval required
133
- - `.decision` — Raw decision string
134
- - `.reason` — Explanation
135
- - `.approval_url` — URL to approve (when applicable)
136
-
137
- ### `@guarded(scope, guard=None)` decorator
138
- Wraps a function so it's checked before execution.
139
-
140
- ## License
141
-
142
- Apache 2.0
1
+ Metadata-Version: 2.4
2
+ Name: agentguardproxy
3
+ Version: 0.2.2
4
+ Summary: Python SDK for AgentGuard — the firewall for AI agents
5
+ Author: AgentGuard Contributors
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/Caua-ferraz/AgentGuard
8
+ Project-URL: Repository, https://github.com/Caua-ferraz/AgentGuard
9
+ Project-URL: Documentation, https://github.com/Caua-ferraz/AgentGuard/blob/master/docs/SETUP.md
10
+ Project-URL: Issues, https://github.com/Caua-ferraz/AgentGuard/issues
11
+ Keywords: ai,agents,firewall,policy,guardrails,safety
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Security
22
+ Classifier: Topic :: Software Development :: Libraries
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ Provides-Extra: langchain
26
+ Requires-Dist: langchain>=0.1.0; extra == "langchain"
27
+ Provides-Extra: crewai
28
+ Requires-Dist: crewai>=0.1.0; extra == "crewai"
29
+ Provides-Extra: browser-use
30
+ Requires-Dist: browser-use>=0.1.0; extra == "browser-use"
31
+ Provides-Extra: mcp
32
+ Provides-Extra: all
33
+ Requires-Dist: langchain>=0.1.0; extra == "all"
34
+ Requires-Dist: crewai>=0.1.0; extra == "all"
35
+ Requires-Dist: browser-use>=0.1.0; extra == "all"
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=7.0; extra == "dev"
38
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
39
+
40
+ # AgentGuard Python SDK
41
+
42
+ Lightweight Python client for [AgentGuard](https://github.com/Caua-ferraz/AgentGuard) — the firewall for AI agents.
43
+
44
+ ## Install
45
+
46
+ ```bash
47
+ pip install agentguardproxy
48
+
49
+ # With framework adapters
50
+ pip install agentguardproxy[langchain]
51
+ pip install agentguardproxy[crewai]
52
+ pip install agentguardproxy[browser-use]
53
+ pip install agentguardproxy[all]
54
+ ```
55
+
56
+ ## Quick Start
57
+
58
+ ```python
59
+ from agentguard import Guard
60
+
61
+ guard = Guard("http://localhost:8080", agent_id="my-agent")
62
+
63
+ # Check before executing
64
+ result = guard.check("shell", command="rm -rf ./old_data")
65
+
66
+ if result.allowed:
67
+ execute(command)
68
+ elif result.needs_approval:
69
+ print(f"Approve at: {result.approval_url}")
70
+ else:
71
+ print(f"Blocked: {result.reason}")
72
+ ```
73
+
74
+ ## Framework Adapters
75
+
76
+ ### LangChain
77
+
78
+ ```python
79
+ from agentguard.adapters.langchain import GuardedToolkit
80
+
81
+ toolkit = GuardedToolkit(
82
+ tools=my_tools,
83
+ guard_url="http://localhost:8080",
84
+ agent_id="langchain-agent",
85
+ )
86
+
87
+ agent = create_react_agent(llm, toolkit.tools, prompt)
88
+ ```
89
+
90
+ ### CrewAI
91
+
92
+ ```python
93
+ from agentguard.adapters.crewai import guard_crew_tools
94
+
95
+ guarded_tools = guard_crew_tools(
96
+ tools=my_crew_tools,
97
+ guard_url="http://localhost:8080",
98
+ agent_id="crew-agent",
99
+ )
100
+ ```
101
+
102
+ ### browser-use
103
+
104
+ ```python
105
+ from agentguard.adapters.browseruse import GuardedBrowser
106
+
107
+ browser = GuardedBrowser(guard_url="http://localhost:8080")
108
+
109
+ result = browser.check_navigation("https://example.com")
110
+ if result.allowed:
111
+ await page.goto("https://example.com")
112
+ ```
113
+
114
+ ### MCP
115
+
116
+ ```python
117
+ from agentguard.adapters.mcp import GuardedMCPServer
118
+
119
+ server = GuardedMCPServer(guard_url="http://localhost:8080")
120
+ server.add_tool("my_tool", "Description", handler=my_handler)
121
+ server.run() # Starts stdio MCP server
122
+ ```
123
+
124
+ ## API Reference
125
+
126
+ ### `Guard(base_url, agent_id="")`
127
+ - `check(scope, *, action, command, path, domain, url, meta)` — Check an action against policy
128
+ - `approve(approval_id)` — Approve a pending action
129
+ - `deny(approval_id)` — Deny a pending action
130
+ - `wait_for_approval(approval_id, timeout=300)` Block until resolved
131
+
132
+ ### `CheckResult`
133
+ - `.allowed` — True if action is permitted
134
+ - `.denied` — True if action is blocked
135
+ - `.needs_approval` — True if human approval required
136
+ - `.decision` — Raw decision string
137
+ - `.reason` — Explanation
138
+ - `.approval_url` URL to approve (when applicable)
139
+
140
+ ### `@guarded(scope, guard=None)` decorator
141
+ Wraps a function so it's checked before execution.
142
+
143
+ ## License
144
+
145
+ Apache 2.0
@@ -5,13 +5,13 @@ Lightweight Python client for [AgentGuard](https://github.com/Caua-ferraz/AgentG
5
5
  ## Install
6
6
 
7
7
  ```bash
8
- pip install agentguard
8
+ pip install agentguardproxy
9
9
 
10
10
  # With framework adapters
11
- pip install agentguard[langchain]
12
- pip install agentguard[crewai]
13
- pip install agentguard[browser-use]
14
- pip install agentguard[all]
11
+ pip install agentguardproxy[langchain]
12
+ pip install agentguardproxy[crewai]
13
+ pip install agentguardproxy[browser-use]
14
+ pip install agentguardproxy[all]
15
15
  ```
16
16
 
17
17
  ## Quick Start
@@ -17,12 +17,31 @@ Usage:
17
17
  print(f"Blocked: {result.reason}")
18
18
  """
19
19
 
20
+ import functools
20
21
  import json
22
+ import os
21
23
  import time
22
24
  from dataclasses import dataclass, field
23
25
  from typing import Optional
24
26
  from urllib import request, error
25
27
 
28
+ # --- Defaults and constants ---
29
+ DEFAULT_BASE_URL = "http://localhost:8080"
30
+ DEFAULT_TIMEOUT = 5 # seconds, for individual HTTP calls
31
+ DEFAULT_APPROVAL_TIMEOUT = 300 # seconds, for wait_for_approval
32
+ DEFAULT_POLL_INTERVAL = 2 # seconds
33
+
34
+ # Decision values (must match the Go backend)
35
+ DECISION_ALLOW = "ALLOW"
36
+ DECISION_DENY = "DENY"
37
+ DECISION_REQUIRE_APPROVAL = "REQUIRE_APPROVAL"
38
+
39
+ # API endpoint paths
40
+ ENDPOINT_CHECK = "/v1/check"
41
+ ENDPOINT_APPROVE = "/v1/approve/"
42
+ ENDPOINT_DENY = "/v1/deny/"
43
+ ENDPOINT_STATUS = "/v1/status/"
44
+
26
45
 
27
46
  @dataclass
28
47
  class CheckResult:
@@ -35,23 +54,24 @@ class CheckResult:
35
54
 
36
55
  @property
37
56
  def allowed(self) -> bool:
38
- return self.decision == "ALLOW"
57
+ return self.decision == DECISION_ALLOW
39
58
 
40
59
  @property
41
60
  def denied(self) -> bool:
42
- return self.decision == "DENY"
61
+ return self.decision == DECISION_DENY
43
62
 
44
63
  @property
45
64
  def needs_approval(self) -> bool:
46
- return self.decision == "REQUIRE_APPROVAL"
65
+ return self.decision == DECISION_REQUIRE_APPROVAL
47
66
 
48
67
 
49
68
  class Guard:
50
69
  """Client for the AgentGuard proxy."""
51
70
 
52
- def __init__(self, base_url: str = "http://localhost:8080", agent_id: str = ""):
53
- self.base_url = base_url.rstrip("/")
71
+ def __init__(self, base_url: str = "", agent_id: str = "", timeout: int = DEFAULT_TIMEOUT):
72
+ self.base_url = (base_url or os.environ.get("AGENTGUARD_URL", DEFAULT_BASE_URL)).rstrip("/")
54
73
  self.agent_id = agent_id
74
+ self.timeout = timeout
55
75
 
56
76
  def check(
57
77
  self,
@@ -97,17 +117,17 @@ class Guard:
97
117
 
98
118
  data = json.dumps(payload).encode("utf-8")
99
119
  req = request.Request(
100
- f"{self.base_url}/v1/check",
120
+ f"{self.base_url}{ENDPOINT_CHECK}",
101
121
  data=data,
102
122
  headers={"Content-Type": "application/json"},
103
123
  method="POST",
104
124
  )
105
125
 
106
126
  try:
107
- with request.urlopen(req, timeout=5) as resp:
127
+ with request.urlopen(req, timeout=self.timeout) as resp:
108
128
  body = json.loads(resp.read())
109
129
  return CheckResult(
110
- decision=body.get("decision", "DENY"),
130
+ decision=body.get("decision", DECISION_DENY),
111
131
  reason=body.get("reason", ""),
112
132
  matched_rule=body.get("matched_rule", ""),
113
133
  approval_id=body.get("approval_id", ""),
@@ -116,18 +136,18 @@ class Guard:
116
136
  except error.URLError as e:
117
137
  # If AgentGuard is unreachable, default to deny (fail closed)
118
138
  return CheckResult(
119
- decision="DENY",
139
+ decision=DECISION_DENY,
120
140
  reason=f"AgentGuard unreachable: {e}",
121
141
  )
122
142
 
123
143
  def approve(self, approval_id: str) -> bool:
124
144
  """Approve a pending action."""
125
145
  req = request.Request(
126
- f"{self.base_url}/v1/approve/{approval_id}",
146
+ f"{self.base_url}{ENDPOINT_APPROVE}{approval_id}",
127
147
  method="POST",
128
148
  )
129
149
  try:
130
- with request.urlopen(req, timeout=5):
150
+ with request.urlopen(req, timeout=self.timeout):
131
151
  return True
132
152
  except error.URLError:
133
153
  return False
@@ -135,28 +155,36 @@ class Guard:
135
155
  def deny(self, approval_id: str) -> bool:
136
156
  """Deny a pending action."""
137
157
  req = request.Request(
138
- f"{self.base_url}/v1/deny/{approval_id}",
158
+ f"{self.base_url}{ENDPOINT_DENY}{approval_id}",
139
159
  method="POST",
140
160
  )
141
161
  try:
142
- with request.urlopen(req, timeout=5):
162
+ with request.urlopen(req, timeout=self.timeout):
143
163
  return True
144
164
  except error.URLError:
145
165
  return False
146
166
 
147
- def wait_for_approval(self, approval_id: str, timeout: int = 300, poll_interval: int = 2) -> CheckResult:
167
+ def wait_for_approval(
168
+ self,
169
+ approval_id: str,
170
+ timeout: int = DEFAULT_APPROVAL_TIMEOUT,
171
+ poll_interval: int = DEFAULT_POLL_INTERVAL,
172
+ ) -> CheckResult:
148
173
  """Block until a pending action is approved or denied (or timeout)."""
149
174
  deadline = time.time() + timeout
150
175
  while time.time() < deadline:
151
176
  # Poll the status endpoint for resolution
152
177
  req = request.Request(
153
- f"{self.base_url}/v1/status/{approval_id}",
178
+ f"{self.base_url}{ENDPOINT_STATUS}{approval_id}",
154
179
  method="GET",
155
180
  )
156
181
  try:
157
- with request.urlopen(req, timeout=5) as resp:
182
+ with request.urlopen(req, timeout=self.timeout) as resp:
158
183
  body = json.loads(resp.read())
159
- if body.get("status") == "resolved" and body.get("decision") in ("ALLOW", "DENY"):
184
+ if body.get("status") == "resolved" and body.get("decision") in (
185
+ DECISION_ALLOW,
186
+ DECISION_DENY,
187
+ ):
160
188
  return CheckResult(
161
189
  decision=body["decision"],
162
190
  reason=body.get("reason", "resolved"),
@@ -165,7 +193,7 @@ class Guard:
165
193
  pass
166
194
  time.sleep(poll_interval)
167
195
 
168
- return CheckResult(decision="DENY", reason="Approval timed out")
196
+ return CheckResult(decision=DECISION_DENY, reason="Approval timed out")
169
197
 
170
198
 
171
199
  # Convenience decorator for guarding functions
@@ -180,6 +208,7 @@ def guarded(scope: str, guard: Optional[Guard] = None, **check_kwargs):
180
208
  os.system(cmd)
181
209
  """
182
210
  def decorator(func):
211
+ @functools.wraps(func)
183
212
  def wrapper(*args, **kwargs):
184
213
  g = guard or Guard()
185
214
  # Try to extract meaningful info from args
@@ -20,7 +20,7 @@ Usage:
20
20
 
21
21
  from typing import Any, Optional
22
22
  from urllib.parse import urlparse
23
- from agentguard import Guard, CheckResult
23
+ from agentguard import Guard, CheckResult, DEFAULT_BASE_URL
24
24
 
25
25
 
26
26
  class GuardedBrowser:
@@ -34,7 +34,7 @@ class GuardedBrowser:
34
34
  def __init__(
35
35
  self,
36
36
  guard: Optional[Guard] = None,
37
- guard_url: str = "http://localhost:8080",
37
+ guard_url: str = DEFAULT_BASE_URL,
38
38
  agent_id: str = "",
39
39
  browser: Any = None,
40
40
  ):
@@ -18,7 +18,7 @@ Usage:
18
18
  """
19
19
 
20
20
  from typing import Any, List, Optional
21
- from agentguard import Guard
21
+ from agentguard import Guard, DEFAULT_BASE_URL
22
22
 
23
23
 
24
24
  class GuardedCrewTool:
@@ -32,7 +32,7 @@ class GuardedCrewTool:
32
32
  self,
33
33
  tool: Any,
34
34
  guard: Optional[Guard] = None,
35
- guard_url: str = "http://localhost:8080",
35
+ guard_url: str = DEFAULT_BASE_URL,
36
36
  agent_id: str = "",
37
37
  scope: str = "shell",
38
38
  ):
@@ -16,7 +16,7 @@ Usage:
16
16
  """
17
17
 
18
18
  from typing import Any, List, Optional
19
- from agentguard import Guard, CheckResult
19
+ from agentguard import Guard, CheckResult, DEFAULT_BASE_URL
20
20
 
21
21
 
22
22
  class GuardedTool:
@@ -133,7 +133,7 @@ class GuardedToolkit:
133
133
  def __init__(
134
134
  self,
135
135
  tools: List[Any],
136
- guard_url: str = "http://localhost:8080",
136
+ guard_url: str = DEFAULT_BASE_URL,
137
137
  agent_id: str = "",
138
138
  default_scope: str = "shell",
139
139
  ):
@@ -35,7 +35,11 @@ MCP config (claude_desktop_config.json / .cursor/mcp.json):
35
35
  import json
36
36
  import sys
37
37
  from typing import Any, Callable, Dict, List, Optional
38
- from agentguard import Guard, CheckResult
38
+ from agentguard import Guard, CheckResult, DEFAULT_BASE_URL
39
+
40
+ # MCP protocol constants
41
+ MCP_PROTOCOL_VERSION = "2024-11-05"
42
+ SDK_VERSION = "0.2.2"
39
43
 
40
44
 
41
45
  class ToolDefinition:
@@ -64,10 +68,10 @@ class GuardedMCPServer:
64
68
  def __init__(
65
69
  self,
66
70
  guard: Optional[Guard] = None,
67
- guard_url: str = "http://localhost:8080",
71
+ guard_url: str = DEFAULT_BASE_URL,
68
72
  agent_id: str = "mcp-agent",
69
73
  server_name: str = "agentguard",
70
- server_version: str = "0.2.0",
74
+ server_version: str = SDK_VERSION,
71
75
  ):
72
76
  self._guard = guard or Guard(guard_url, agent_id=agent_id)
73
77
  self._tools: Dict[str, ToolDefinition] = {}
@@ -141,7 +145,7 @@ class GuardedMCPServer:
141
145
  "jsonrpc": "2.0",
142
146
  "id": req_id,
143
147
  "result": {
144
- "protocolVersion": "2024-11-05",
148
+ "protocolVersion": MCP_PROTOCOL_VERSION,
145
149
  "serverInfo": {
146
150
  "name": self._server_name,
147
151
  "version": self._server_version,