gopher-mcp-python 0.1.30__tar.gz → 0.1.38__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 (86) hide show
  1. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/PKG-INFO +44 -1
  2. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/README.md +43 -0
  3. gopher_mcp_python-0.1.38/gopher_mcp_python/__init__.py +209 -0
  4. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/agent.py +232 -76
  5. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/config.py +50 -90
  6. gopher_mcp_python-0.1.38/gopher_mcp_python/elicitation.py +120 -0
  7. gopher_mcp_python-0.1.38/gopher_mcp_python/elicitation_runtime.py +229 -0
  8. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/ffi/auth/loader.py +9 -9
  9. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/ffi/library.py +420 -111
  10. gopher_mcp_python-0.1.38/gopher_mcp_python/gateway_elicitation_preflight.py +316 -0
  11. gopher_mcp_python-0.1.38/gopher_mcp_python/oauth_authorization_url.py +49 -0
  12. gopher_mcp_python-0.1.38/gopher_mcp_python/oauth_browser.py +33 -0
  13. gopher_mcp_python-0.1.38/gopher_mcp_python/oauth_discovery.py +341 -0
  14. gopher_mcp_python-0.1.38/gopher_mcp_python/oauth_loopback.py +148 -0
  15. gopher_mcp_python-0.1.38/gopher_mcp_python/oauth_pkce.py +21 -0
  16. gopher_mcp_python-0.1.38/gopher_mcp_python/oauth_registration.py +89 -0
  17. gopher_mcp_python-0.1.38/gopher_mcp_python/oauth_resolver.py +363 -0
  18. gopher_mcp_python-0.1.38/gopher_mcp_python/oauth_runtime_options.py +30 -0
  19. gopher_mcp_python-0.1.38/gopher_mcp_python/oauth_server_targets.py +76 -0
  20. gopher_mcp_python-0.1.38/gopher_mcp_python/oauth_token_exchange.py +104 -0
  21. gopher_mcp_python-0.1.38/gopher_mcp_python/oauth_token_store.py +75 -0
  22. gopher_mcp_python-0.1.38/gopher_mcp_python/runtime_options.py +333 -0
  23. gopher_mcp_python-0.1.38/gopher_mcp_python/server_config.py +112 -0
  24. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python.egg-info/PKG-INFO +44 -1
  25. gopher_mcp_python-0.1.38/gopher_mcp_python.egg-info/SOURCES.txt +80 -0
  26. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/pyproject.toml +1 -1
  27. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/tests/test_agent_create_by.py +31 -8
  28. gopher_mcp_python-0.1.38/tests/test_agent_create_with_oauth.py +434 -0
  29. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/tests/test_agent_error_message.py +9 -3
  30. gopher_mcp_python-0.1.38/tests/test_agent_lifecycle.py +77 -0
  31. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/tests/test_agent_runtime_options.py +38 -2
  32. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/tests/test_auth_exports.py +9 -6
  33. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/tests/test_config.py +130 -1
  34. gopher_mcp_python-0.1.38/tests/test_custom_oauth_test_idp.py +186 -0
  35. gopher_mcp_python-0.1.38/tests/test_custom_protected_mcp_endpoints.py +173 -0
  36. gopher_mcp_python-0.1.38/tests/test_dump_version.py +28 -0
  37. gopher_mcp_python-0.1.38/tests/test_elicitation_runtime.py +157 -0
  38. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/tests/test_ffi.py +175 -0
  39. gopher_mcp_python-0.1.38/tests/test_ffi_runtime_options.py +251 -0
  40. gopher_mcp_python-0.1.38/tests/test_gateway_elicitation_preflight.py +117 -0
  41. gopher_mcp_python-0.1.38/tests/test_header_create_by_url_example.py +54 -0
  42. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/tests/test_library_search_paths.py +54 -4
  43. gopher_mcp_python-0.1.38/tests/test_linux_native_packaging.py +218 -0
  44. gopher_mcp_python-0.1.38/tests/test_oauth_authorization_url.py +112 -0
  45. gopher_mcp_python-0.1.38/tests/test_oauth_auto_custom_idp.py +155 -0
  46. gopher_mcp_python-0.1.38/tests/test_oauth_auto_custom_idp_failures.py +285 -0
  47. gopher_mcp_python-0.1.38/tests/test_oauth_browser.py +53 -0
  48. gopher_mcp_python-0.1.38/tests/test_oauth_create_with_url_integration.py +210 -0
  49. gopher_mcp_python-0.1.38/tests/test_oauth_discovery.py +240 -0
  50. gopher_mcp_python-0.1.38/tests/test_oauth_loopback.py +80 -0
  51. gopher_mcp_python-0.1.38/tests/test_oauth_pkce.py +23 -0
  52. gopher_mcp_python-0.1.38/tests/test_oauth_registration.py +56 -0
  53. gopher_mcp_python-0.1.38/tests/test_oauth_resolver.py +141 -0
  54. gopher_mcp_python-0.1.38/tests/test_oauth_runtime_options.py +53 -0
  55. gopher_mcp_python-0.1.38/tests/test_oauth_server_targets.py +58 -0
  56. gopher_mcp_python-0.1.38/tests/test_oauth_test_token_helper.py +184 -0
  57. gopher_mcp_python-0.1.38/tests/test_oauth_token_exchange.py +91 -0
  58. gopher_mcp_python-0.1.38/tests/test_oauth_token_store.py +74 -0
  59. gopher_mcp_python-0.1.38/tests/test_server_config.py +74 -0
  60. gopher_mcp_python-0.1.30/gopher_mcp_python/__init__.py +0 -165
  61. gopher_mcp_python-0.1.30/gopher_mcp_python/server_config.py +0 -47
  62. gopher_mcp_python-0.1.30/gopher_mcp_python.egg-info/SOURCES.txt +0 -40
  63. gopher_mcp_python-0.1.30/tests/test_ffi_runtime_options.py +0 -119
  64. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/LICENSE +0 -0
  65. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/auth/__init__.py +0 -0
  66. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/auth/errors.py +0 -0
  67. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/auth/gopher_auth.py +0 -0
  68. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/auth/scope_helpers.py +0 -0
  69. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/errors.py +0 -0
  70. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/ffi/__init__.py +0 -0
  71. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/ffi/auth/__init__.py +0 -0
  72. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/ffi/auth/auth_client.py +0 -0
  73. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/ffi/auth/auto_refresh.py +0 -0
  74. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/ffi/auth/config_loader.py +0 -0
  75. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/ffi/auth/oauth_client.py +0 -0
  76. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/ffi/auth/session_manager.py +0 -0
  77. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/ffi/auth/types.py +0 -0
  78. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/ffi/auth/validation_options.py +0 -0
  79. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python/result.py +0 -0
  80. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python.egg-info/dependency_links.txt +0 -0
  81. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python.egg-info/requires.txt +0 -0
  82. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/gopher_mcp_python.egg-info/top_level.txt +0 -0
  83. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/setup.cfg +0 -0
  84. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/setup.py +0 -0
  85. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/tests/test_gopher_auth.py +0 -0
  86. {gopher_mcp_python-0.1.30 → gopher_mcp_python-0.1.38}/tests/test_result.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gopher-mcp-python
3
- Version: 0.1.30
3
+ Version: 0.1.38
4
4
  Summary: Python SDK for Gopher MCP - AI Agent orchestration framework with native performance
5
5
  Author-email: Gopher Security <dev@gophersecurity.com>
6
6
  License: Apache-2.0
@@ -61,6 +61,9 @@ Python SDK for gopher-mcp-python, providing AI agent orchestration with native C
61
61
  - Python 3.8 or higher
62
62
  - `venv` and `pip` for PyPI installation, examples, and development workflows
63
63
  - Native gopher-mcp-python library (built from source)
64
+ - On Linux, system OpenSSL runtime libraries (`libssl` / `libcrypto`) from
65
+ your distribution. Native wheels do not bundle OpenSSL, so OS security
66
+ updates remain effective.
64
67
 
65
68
  On Debian/Ubuntu, install the Python venv and pip packages before using the
66
69
  PyPI install path, running examples, or setting up development dependencies:
@@ -216,6 +219,42 @@ Result class with status and metadata.
216
219
  - `result.is_error()` - Check if error
217
220
  - `result.is_timeout()` - Check if timeout
218
221
 
222
+ ### Provider OAuth Elicitation
223
+
224
+ Provider OAuth requested during a tool call is handled automatically by default.
225
+ For URL-mode elicitation, the SDK opens the authorization URL when possible,
226
+ prints it as a fallback, waits for the user to finish the browser flow, and then
227
+ lets the native agent retry the tool call.
228
+
229
+ No example-level elicitation configuration is required:
230
+
231
+ ```python
232
+ agent = GopherAgent.create_with_url(provider, model, mcp_url)
233
+ ```
234
+
235
+ Use `GopherAgentCreateOptions` only when you need a custom synchronous handler
236
+ or want to disable browser opening while still printing the URL:
237
+
238
+ ```python
239
+ from gopher_mcp_python import GopherAgentCreateOptions
240
+
241
+ agent = GopherAgent.create_with_url(
242
+ provider,
243
+ model,
244
+ mcp_url,
245
+ GopherAgentCreateOptions(
246
+ elicitation={
247
+ "open_browser": False,
248
+ "handler": lambda request: "accept",
249
+ },
250
+ ),
251
+ )
252
+ ```
253
+
254
+ First-step MCP server OAuth is controlled separately by the `oauth` create
255
+ option. Setting `oauth={"mode": "disabled"}` skips SDK OAuth discovery for the
256
+ MCP endpoint but still leaves provider elicitation enabled.
257
+
219
258
  ### Exceptions
220
259
 
221
260
  - `AgentError` - Base exception for agent errors
@@ -231,6 +270,10 @@ Result class with status and metadata.
231
270
  pytest
232
271
  ```
233
272
 
273
+ For deterministic OAuth auto verification with a local custom IdP and local MCP
274
+ server/gateway endpoints, see
275
+ [`docs/oauth-auto-custom-idp.md`](docs/oauth-auto-custom-idp.md).
276
+
234
277
  ### Code Formatting
235
278
 
236
279
  This project uses Black for code formatting and Ruff for linting.
@@ -17,6 +17,9 @@ Python SDK for gopher-mcp-python, providing AI agent orchestration with native C
17
17
  - Python 3.8 or higher
18
18
  - `venv` and `pip` for PyPI installation, examples, and development workflows
19
19
  - Native gopher-mcp-python library (built from source)
20
+ - On Linux, system OpenSSL runtime libraries (`libssl` / `libcrypto`) from
21
+ your distribution. Native wheels do not bundle OpenSSL, so OS security
22
+ updates remain effective.
20
23
 
21
24
  On Debian/Ubuntu, install the Python venv and pip packages before using the
22
25
  PyPI install path, running examples, or setting up development dependencies:
@@ -172,6 +175,42 @@ Result class with status and metadata.
172
175
  - `result.is_error()` - Check if error
173
176
  - `result.is_timeout()` - Check if timeout
174
177
 
178
+ ### Provider OAuth Elicitation
179
+
180
+ Provider OAuth requested during a tool call is handled automatically by default.
181
+ For URL-mode elicitation, the SDK opens the authorization URL when possible,
182
+ prints it as a fallback, waits for the user to finish the browser flow, and then
183
+ lets the native agent retry the tool call.
184
+
185
+ No example-level elicitation configuration is required:
186
+
187
+ ```python
188
+ agent = GopherAgent.create_with_url(provider, model, mcp_url)
189
+ ```
190
+
191
+ Use `GopherAgentCreateOptions` only when you need a custom synchronous handler
192
+ or want to disable browser opening while still printing the URL:
193
+
194
+ ```python
195
+ from gopher_mcp_python import GopherAgentCreateOptions
196
+
197
+ agent = GopherAgent.create_with_url(
198
+ provider,
199
+ model,
200
+ mcp_url,
201
+ GopherAgentCreateOptions(
202
+ elicitation={
203
+ "open_browser": False,
204
+ "handler": lambda request: "accept",
205
+ },
206
+ ),
207
+ )
208
+ ```
209
+
210
+ First-step MCP server OAuth is controlled separately by the `oauth` create
211
+ option. Setting `oauth={"mode": "disabled"}` skips SDK OAuth discovery for the
212
+ MCP endpoint but still leaves provider elicitation enabled.
213
+
175
214
  ### Exceptions
176
215
 
177
216
  - `AgentError` - Base exception for agent errors
@@ -187,6 +226,10 @@ Result class with status and metadata.
187
226
  pytest
188
227
  ```
189
228
 
229
+ For deterministic OAuth auto verification with a local custom IdP and local MCP
230
+ server/gateway endpoints, see
231
+ [`docs/oauth-auto-custom-idp.md`](docs/oauth-auto-custom-idp.md).
232
+
190
233
  ### Code Formatting
191
234
 
192
235
  This project uses Black for code formatting and Ruff for linting.
@@ -0,0 +1,209 @@
1
+ """
2
+ Gopher Orch Python SDK - AI Agent orchestration framework with native performance.
3
+
4
+ This module provides Python bindings to the gopher-mcp-python native library through ctypes FFI.
5
+
6
+ Example:
7
+ >>> from gopher_mcp_python import GopherAgent, GopherAgentConfig
8
+ >>>
9
+ >>> # Create an agent with API key
10
+ >>> config = (GopherAgentConfig.builder()
11
+ ... .provider("AnthropicProvider")
12
+ ... .model("claude-3-haiku-20240307")
13
+ ... .api_key("your-api-key")
14
+ ... .build())
15
+ >>> agent = GopherAgent.create(config)
16
+ >>>
17
+ >>> # Run a query
18
+ >>> answer = agent.run("What time is it in Tokyo?")
19
+ >>> print(answer)
20
+ >>>
21
+ >>> # Cleanup
22
+ >>> agent.dispose()
23
+ """
24
+
25
+ from importlib import import_module
26
+
27
+ from gopher_mcp_python.agent import GopherAgent
28
+ from gopher_mcp_python.config import (
29
+ GopherAgentConfig,
30
+ GopherAgentConfigBuilder,
31
+ )
32
+ from gopher_mcp_python.elicitation import (
33
+ GopherAgentElicitationAction,
34
+ GopherAgentElicitationHandler,
35
+ GopherAgentElicitationOptions,
36
+ GopherAgentElicitationRequest,
37
+ GopherAgentElicitationResponse,
38
+ )
39
+ from gopher_mcp_python.runtime_options import (
40
+ GopherAgentCreateOptions,
41
+ GopherAgentOAuthOptions,
42
+ GopherAgentRuntimeOptions,
43
+ GopherAgentTokenRecord,
44
+ GopherAgentTokenStore,
45
+ )
46
+ from gopher_mcp_python.result import AgentResult, AgentResultStatus, AgentResultBuilder
47
+ from gopher_mcp_python.errors import (
48
+ AgentError,
49
+ ApiKeyError,
50
+ ConnectionError,
51
+ TimeoutError,
52
+ )
53
+ from gopher_mcp_python.server_config import ServerConfig, ServerConfigRoute
54
+ from gopher_mcp_python.ffi import GopherOrchLibrary, GopherOrchHandle
55
+
56
+ __version__ = "0.1.38"
57
+
58
+ _AUTH_EXPORTS = {
59
+ "GopherAuth",
60
+ "GopherAuthError",
61
+ "ConfigurationError",
62
+ "InsufficientScopesError",
63
+ "JwksError",
64
+ "TokenExchangeError",
65
+ "TokenValidationError",
66
+ "has_all_scopes",
67
+ "has_any_scope",
68
+ "has_scope",
69
+ }
70
+
71
+ _AUTH_FFI_EXPORTS = {
72
+ "AutoRefreshResult",
73
+ "RegistrationResponse",
74
+ "TokenResponse",
75
+ "ValidationResult",
76
+ "TokenPayload",
77
+ "GopherAuthContext",
78
+ "ERROR_DESCRIPTIONS",
79
+ "get_error_description",
80
+ "gopher_create_empty_auth_context",
81
+ "is_gopher_auth_error",
82
+ "GopherAuthClient",
83
+ "GopherAuthConfig",
84
+ "GopherOAuthClient",
85
+ "GopherSessionManager",
86
+ "GopherValidationOptions",
87
+ "gopher_auth_auto_refresh",
88
+ "gopher_auth_build_oidc_discovery_metadata",
89
+ "gopher_auth_build_oauth_server_metadata",
90
+ "gopher_auth_build_protected_resource_metadata",
91
+ "gopher_auth_extract_bearer_token",
92
+ "gopher_auth_extract_method",
93
+ "gopher_auth_extract_path",
94
+ "gopher_auth_url_decode",
95
+ "gopher_auth_url_encode",
96
+ "gopher_auth_validate_all_scopes",
97
+ "gopher_auth_validate_any_scopes",
98
+ "gopher_auth_validate_idp",
99
+ "gopher_create_validation_options",
100
+ "gopher_generate_www_authenticate_header",
101
+ "gopher_generate_www_authenticate_header_v2",
102
+ "gopher_get_auth_library_version",
103
+ "gopher_init_auth_library",
104
+ "gopher_is_auth_library_initialized",
105
+ "gopher_shutdown_auth_library",
106
+ "is_auth_available",
107
+ }
108
+
109
+
110
+ def __getattr__(name: str):
111
+ if name in _AUTH_EXPORTS:
112
+ auth = import_module("gopher_mcp_python.auth")
113
+ value = getattr(auth, name)
114
+ globals()[name] = value
115
+ return value
116
+
117
+ if name == "GopherAuthFfiError":
118
+ from gopher_mcp_python.ffi.auth import GopherAuthError as GopherAuthFfiError
119
+
120
+ globals()[name] = GopherAuthFfiError
121
+ return GopherAuthFfiError
122
+
123
+ if name in _AUTH_FFI_EXPORTS:
124
+ ffi_auth = import_module("gopher_mcp_python.ffi.auth")
125
+ value = getattr(ffi_auth, name)
126
+ globals()[name] = value
127
+ return value
128
+
129
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
130
+
131
+
132
+ __all__ = [
133
+ # Main classes
134
+ "GopherAgent",
135
+ "GopherAgentConfig",
136
+ "GopherAgentConfigBuilder",
137
+ "GopherAgentCreateOptions",
138
+ "GopherAgentElicitationAction",
139
+ "GopherAgentElicitationHandler",
140
+ "GopherAgentElicitationOptions",
141
+ "GopherAgentElicitationRequest",
142
+ "GopherAgentElicitationResponse",
143
+ "GopherAgentOAuthOptions",
144
+ "GopherAgentRuntimeOptions",
145
+ "GopherAgentTokenRecord",
146
+ "GopherAgentTokenStore",
147
+ "AgentResult",
148
+ "AgentResultStatus",
149
+ "AgentResultBuilder",
150
+ "ServerConfig",
151
+ "ServerConfigRoute",
152
+ # Errors
153
+ "AgentError",
154
+ "ApiKeyError",
155
+ "ConnectionError",
156
+ "TimeoutError",
157
+ # FFI
158
+ "GopherOrchLibrary",
159
+ "GopherOrchHandle",
160
+ # Auth
161
+ "GopherAuth",
162
+ "GopherAuthError",
163
+ "GopherAuthFfiError",
164
+ "AutoRefreshResult",
165
+ "RegistrationResponse",
166
+ "TokenResponse",
167
+ "ValidationResult",
168
+ "TokenPayload",
169
+ "GopherAuthContext",
170
+ "ERROR_DESCRIPTIONS",
171
+ "get_error_description",
172
+ "gopher_create_empty_auth_context",
173
+ "is_gopher_auth_error",
174
+ "GopherAuthClient",
175
+ "GopherAuthConfig",
176
+ "GopherOAuthClient",
177
+ "GopherSessionManager",
178
+ "GopherValidationOptions",
179
+ "gopher_auth_auto_refresh",
180
+ "gopher_auth_build_oidc_discovery_metadata",
181
+ "gopher_auth_build_oauth_server_metadata",
182
+ "gopher_auth_build_protected_resource_metadata",
183
+ "gopher_auth_extract_bearer_token",
184
+ "gopher_auth_extract_method",
185
+ "gopher_auth_extract_path",
186
+ "gopher_auth_url_decode",
187
+ "gopher_auth_url_encode",
188
+ "gopher_auth_validate_all_scopes",
189
+ "gopher_auth_validate_any_scopes",
190
+ "gopher_auth_validate_idp",
191
+ "gopher_create_validation_options",
192
+ "gopher_generate_www_authenticate_header",
193
+ "gopher_generate_www_authenticate_header_v2",
194
+ "gopher_get_auth_library_version",
195
+ "gopher_init_auth_library",
196
+ "gopher_is_auth_library_initialized",
197
+ "gopher_shutdown_auth_library",
198
+ "is_auth_available",
199
+ "ConfigurationError",
200
+ "InsufficientScopesError",
201
+ "JwksError",
202
+ "TokenExchangeError",
203
+ "TokenValidationError",
204
+ "has_all_scopes",
205
+ "has_any_scope",
206
+ "has_scope",
207
+ # Version
208
+ "__version__",
209
+ ]