gopher-mcp-python 0.1.23__tar.gz → 0.1.30__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.
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/PKG-INFO +10 -2
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/README.md +9 -1
- gopher_mcp_python-0.1.30/gopher_mcp_python/__init__.py +165 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/agent.py +98 -26
- gopher_mcp_python-0.1.30/gopher_mcp_python/auth/__init__.py +83 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/config.py +141 -1
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/ffi/auth/__init__.py +38 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/ffi/auth/auth_client.py +0 -1
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/ffi/auth/loader.py +43 -11
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/ffi/library.py +381 -23
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python.egg-info/PKG-INFO +10 -2
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python.egg-info/SOURCES.txt +5 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/pyproject.toml +1 -1
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/setup.py +1 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/tests/test_agent_create_by.py +2 -6
- gopher_mcp_python-0.1.30/tests/test_agent_error_message.py +124 -0
- gopher_mcp_python-0.1.30/tests/test_agent_runtime_options.py +200 -0
- gopher_mcp_python-0.1.30/tests/test_auth_exports.py +88 -0
- gopher_mcp_python-0.1.30/tests/test_config.py +173 -0
- gopher_mcp_python-0.1.30/tests/test_ffi_runtime_options.py +119 -0
- gopher_mcp_python-0.1.30/tests/test_library_search_paths.py +77 -0
- gopher_mcp_python-0.1.23/gopher_mcp_python/__init__.py +0 -84
- gopher_mcp_python-0.1.23/gopher_mcp_python/auth/__init__.py +0 -31
- gopher_mcp_python-0.1.23/tests/test_config.py +0 -79
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/LICENSE +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/auth/errors.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/auth/gopher_auth.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/auth/scope_helpers.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/errors.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/ffi/__init__.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/ffi/auth/auto_refresh.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/ffi/auth/config_loader.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/ffi/auth/oauth_client.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/ffi/auth/session_manager.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/ffi/auth/types.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/ffi/auth/validation_options.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/result.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python/server_config.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python.egg-info/dependency_links.txt +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python.egg-info/requires.txt +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/gopher_mcp_python.egg-info/top_level.txt +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/setup.cfg +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/tests/test_ffi.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/tests/test_gopher_auth.py +0 -0
- {gopher_mcp_python-0.1.23 → gopher_mcp_python-0.1.30}/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.
|
|
3
|
+
Version: 0.1.30
|
|
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
|
|
@@ -59,8 +59,16 @@ Python SDK for gopher-mcp-python, providing AI agent orchestration with native C
|
|
|
59
59
|
## Requirements
|
|
60
60
|
|
|
61
61
|
- Python 3.8 or higher
|
|
62
|
+
- `venv` and `pip` for PyPI installation, examples, and development workflows
|
|
62
63
|
- Native gopher-mcp-python library (built from source)
|
|
63
64
|
|
|
65
|
+
On Debian/Ubuntu, install the Python venv and pip packages before using the
|
|
66
|
+
PyPI install path, running examples, or setting up development dependencies:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
sudo apt-get install python3 python3-venv python3-pip
|
|
70
|
+
```
|
|
71
|
+
|
|
64
72
|
## Installation
|
|
65
73
|
|
|
66
74
|
### From Source
|
|
@@ -78,7 +86,7 @@ cd gopher-mcp-python
|
|
|
78
86
|
|
|
79
87
|
3. Install the Python package:
|
|
80
88
|
```bash
|
|
81
|
-
pip install -e .
|
|
89
|
+
python3 -m pip install -e .
|
|
82
90
|
```
|
|
83
91
|
|
|
84
92
|
## Quick Start
|
|
@@ -15,8 +15,16 @@ Python SDK for gopher-mcp-python, providing AI agent orchestration with native C
|
|
|
15
15
|
## Requirements
|
|
16
16
|
|
|
17
17
|
- Python 3.8 or higher
|
|
18
|
+
- `venv` and `pip` for PyPI installation, examples, and development workflows
|
|
18
19
|
- Native gopher-mcp-python library (built from source)
|
|
19
20
|
|
|
21
|
+
On Debian/Ubuntu, install the Python venv and pip packages before using the
|
|
22
|
+
PyPI install path, running examples, or setting up development dependencies:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
sudo apt-get install python3 python3-venv python3-pip
|
|
26
|
+
```
|
|
27
|
+
|
|
20
28
|
## Installation
|
|
21
29
|
|
|
22
30
|
### From Source
|
|
@@ -34,7 +42,7 @@ cd gopher-mcp-python
|
|
|
34
42
|
|
|
35
43
|
3. Install the Python package:
|
|
36
44
|
```bash
|
|
37
|
-
pip install -e .
|
|
45
|
+
python3 -m pip install -e .
|
|
38
46
|
```
|
|
39
47
|
|
|
40
48
|
## Quick Start
|
|
@@ -0,0 +1,165 @@
|
|
|
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 gopher_mcp_python.agent import GopherAgent
|
|
26
|
+
from gopher_mcp_python.config import (
|
|
27
|
+
GopherAgentConfig,
|
|
28
|
+
GopherAgentConfigBuilder,
|
|
29
|
+
GopherAgentRuntimeOptions,
|
|
30
|
+
)
|
|
31
|
+
from gopher_mcp_python.result import AgentResult, AgentResultStatus, AgentResultBuilder
|
|
32
|
+
from gopher_mcp_python.errors import (
|
|
33
|
+
AgentError,
|
|
34
|
+
ApiKeyError,
|
|
35
|
+
ConnectionError,
|
|
36
|
+
TimeoutError,
|
|
37
|
+
)
|
|
38
|
+
from gopher_mcp_python.server_config import ServerConfig
|
|
39
|
+
from gopher_mcp_python.ffi import GopherOrchLibrary, GopherOrchHandle
|
|
40
|
+
|
|
41
|
+
# Auth module re-exports
|
|
42
|
+
from gopher_mcp_python.ffi.auth import (
|
|
43
|
+
# Types
|
|
44
|
+
GopherAuthError,
|
|
45
|
+
AutoRefreshResult,
|
|
46
|
+
RegistrationResponse,
|
|
47
|
+
TokenResponse,
|
|
48
|
+
ValidationResult,
|
|
49
|
+
TokenPayload,
|
|
50
|
+
GopherAuthContext,
|
|
51
|
+
ERROR_DESCRIPTIONS,
|
|
52
|
+
get_error_description,
|
|
53
|
+
gopher_create_empty_auth_context,
|
|
54
|
+
is_gopher_auth_error,
|
|
55
|
+
# Classes
|
|
56
|
+
GopherAuthClient,
|
|
57
|
+
GopherAuthConfig,
|
|
58
|
+
GopherOAuthClient,
|
|
59
|
+
GopherSessionManager,
|
|
60
|
+
GopherValidationOptions,
|
|
61
|
+
# Functions
|
|
62
|
+
gopher_auth_auto_refresh,
|
|
63
|
+
gopher_auth_build_oidc_discovery_metadata,
|
|
64
|
+
gopher_auth_build_oauth_server_metadata,
|
|
65
|
+
gopher_auth_build_protected_resource_metadata,
|
|
66
|
+
gopher_auth_extract_bearer_token,
|
|
67
|
+
gopher_auth_extract_method,
|
|
68
|
+
gopher_auth_extract_path,
|
|
69
|
+
gopher_auth_url_decode,
|
|
70
|
+
gopher_auth_url_encode,
|
|
71
|
+
gopher_auth_validate_all_scopes,
|
|
72
|
+
gopher_auth_validate_any_scopes,
|
|
73
|
+
gopher_auth_validate_idp,
|
|
74
|
+
gopher_create_validation_options,
|
|
75
|
+
gopher_generate_www_authenticate_header,
|
|
76
|
+
gopher_generate_www_authenticate_header_v2,
|
|
77
|
+
gopher_get_auth_library_version,
|
|
78
|
+
gopher_init_auth_library,
|
|
79
|
+
gopher_is_auth_library_initialized,
|
|
80
|
+
gopher_shutdown_auth_library,
|
|
81
|
+
is_auth_available,
|
|
82
|
+
)
|
|
83
|
+
from gopher_mcp_python.auth import (
|
|
84
|
+
GopherAuth,
|
|
85
|
+
GopherAuthError as GopherAuthBaseError,
|
|
86
|
+
ConfigurationError,
|
|
87
|
+
InsufficientScopesError,
|
|
88
|
+
JwksError,
|
|
89
|
+
TokenExchangeError,
|
|
90
|
+
TokenValidationError,
|
|
91
|
+
has_all_scopes,
|
|
92
|
+
has_any_scope,
|
|
93
|
+
has_scope,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
__version__ = "0.1.30"
|
|
97
|
+
|
|
98
|
+
__all__ = [
|
|
99
|
+
# Main classes
|
|
100
|
+
"GopherAgent",
|
|
101
|
+
"GopherAgentConfig",
|
|
102
|
+
"GopherAgentConfigBuilder",
|
|
103
|
+
"GopherAgentRuntimeOptions",
|
|
104
|
+
"AgentResult",
|
|
105
|
+
"AgentResultStatus",
|
|
106
|
+
"AgentResultBuilder",
|
|
107
|
+
"ServerConfig",
|
|
108
|
+
# Errors
|
|
109
|
+
"AgentError",
|
|
110
|
+
"ApiKeyError",
|
|
111
|
+
"ConnectionError",
|
|
112
|
+
"TimeoutError",
|
|
113
|
+
# FFI
|
|
114
|
+
"GopherOrchLibrary",
|
|
115
|
+
"GopherOrchHandle",
|
|
116
|
+
# Auth
|
|
117
|
+
"GopherAuthError",
|
|
118
|
+
"AutoRefreshResult",
|
|
119
|
+
"RegistrationResponse",
|
|
120
|
+
"TokenResponse",
|
|
121
|
+
"ValidationResult",
|
|
122
|
+
"TokenPayload",
|
|
123
|
+
"GopherAuthContext",
|
|
124
|
+
"ERROR_DESCRIPTIONS",
|
|
125
|
+
"get_error_description",
|
|
126
|
+
"gopher_create_empty_auth_context",
|
|
127
|
+
"is_gopher_auth_error",
|
|
128
|
+
"GopherAuthClient",
|
|
129
|
+
"GopherAuthConfig",
|
|
130
|
+
"GopherOAuthClient",
|
|
131
|
+
"GopherSessionManager",
|
|
132
|
+
"GopherValidationOptions",
|
|
133
|
+
"gopher_auth_auto_refresh",
|
|
134
|
+
"gopher_auth_build_oidc_discovery_metadata",
|
|
135
|
+
"gopher_auth_build_oauth_server_metadata",
|
|
136
|
+
"gopher_auth_build_protected_resource_metadata",
|
|
137
|
+
"gopher_auth_extract_bearer_token",
|
|
138
|
+
"gopher_auth_extract_method",
|
|
139
|
+
"gopher_auth_extract_path",
|
|
140
|
+
"gopher_auth_url_decode",
|
|
141
|
+
"gopher_auth_url_encode",
|
|
142
|
+
"gopher_auth_validate_all_scopes",
|
|
143
|
+
"gopher_auth_validate_any_scopes",
|
|
144
|
+
"gopher_auth_validate_idp",
|
|
145
|
+
"gopher_create_validation_options",
|
|
146
|
+
"gopher_generate_www_authenticate_header",
|
|
147
|
+
"gopher_generate_www_authenticate_header_v2",
|
|
148
|
+
"gopher_get_auth_library_version",
|
|
149
|
+
"gopher_init_auth_library",
|
|
150
|
+
"gopher_is_auth_library_initialized",
|
|
151
|
+
"gopher_shutdown_auth_library",
|
|
152
|
+
"is_auth_available",
|
|
153
|
+
"GopherAuth",
|
|
154
|
+
"GopherAuthBaseError",
|
|
155
|
+
"ConfigurationError",
|
|
156
|
+
"InsufficientScopesError",
|
|
157
|
+
"JwksError",
|
|
158
|
+
"TokenExchangeError",
|
|
159
|
+
"TokenValidationError",
|
|
160
|
+
"has_all_scopes",
|
|
161
|
+
"has_any_scope",
|
|
162
|
+
"has_scope",
|
|
163
|
+
# Version
|
|
164
|
+
"__version__",
|
|
165
|
+
]
|
|
@@ -34,7 +34,6 @@ from gopher_mcp_python.result import AgentResult, AgentResultStatus
|
|
|
34
34
|
from gopher_mcp_python.errors import AgentError, TimeoutError
|
|
35
35
|
from gopher_mcp_python.ffi import GopherOrchLibrary, GopherOrchHandle
|
|
36
36
|
|
|
37
|
-
|
|
38
37
|
_initialized = False
|
|
39
38
|
_cleanup_handler_registered = False
|
|
40
39
|
|
|
@@ -78,7 +77,10 @@ class GopherAgent:
|
|
|
78
77
|
|
|
79
78
|
lib = GopherOrchLibrary.get_instance()
|
|
80
79
|
if lib is None:
|
|
81
|
-
|
|
80
|
+
load_error = GopherOrchLibrary.get_load_error_message()
|
|
81
|
+
raise AgentError(
|
|
82
|
+
f"Failed to load gopher-mcp-python native library.\n{load_error}"
|
|
83
|
+
)
|
|
82
84
|
|
|
83
85
|
_initialized = True
|
|
84
86
|
_setup_cleanup_handler()
|
|
@@ -117,17 +119,24 @@ class GopherAgent:
|
|
|
117
119
|
|
|
118
120
|
lib = GopherOrchLibrary.get_instance()
|
|
119
121
|
if lib is None:
|
|
120
|
-
|
|
122
|
+
load_error = GopherOrchLibrary.get_load_error_message()
|
|
123
|
+
raise AgentError(f"Native library not available.\n{load_error}")
|
|
121
124
|
|
|
122
125
|
handle: Optional[GopherOrchHandle] = None
|
|
123
126
|
try:
|
|
124
127
|
if config.has_api_key():
|
|
125
128
|
handle = lib.agent_create_by_api_key(
|
|
126
|
-
config.provider,
|
|
129
|
+
config.provider,
|
|
130
|
+
config.model,
|
|
131
|
+
config.api_key,
|
|
132
|
+
config.runtime_options,
|
|
127
133
|
)
|
|
128
134
|
else:
|
|
129
135
|
handle = lib.agent_create_by_json(
|
|
130
|
-
config.provider,
|
|
136
|
+
config.provider,
|
|
137
|
+
config.model,
|
|
138
|
+
config.server_config,
|
|
139
|
+
config.runtime_options,
|
|
131
140
|
)
|
|
132
141
|
except Exception as e:
|
|
133
142
|
raise AgentError(f"Failed to create agent: {e}")
|
|
@@ -135,12 +144,17 @@ class GopherAgent:
|
|
|
135
144
|
if handle is None:
|
|
136
145
|
error = lib.get_last_error_message()
|
|
137
146
|
lib.clear_error()
|
|
138
|
-
raise AgentError(error or
|
|
147
|
+
raise AgentError(error or _build_create_error_message())
|
|
139
148
|
|
|
140
149
|
return GopherAgent(handle)
|
|
141
150
|
|
|
142
151
|
@staticmethod
|
|
143
|
-
def create_with_api_key(
|
|
152
|
+
def create_with_api_key(
|
|
153
|
+
provider: str,
|
|
154
|
+
model: str,
|
|
155
|
+
api_key: str,
|
|
156
|
+
runtime_options: Optional[object] = None,
|
|
157
|
+
) -> "GopherAgent":
|
|
144
158
|
"""
|
|
145
159
|
Create a new GopherAgent with API key.
|
|
146
160
|
|
|
@@ -148,21 +162,27 @@ class GopherAgent:
|
|
|
148
162
|
provider: Provider name (e.g., "AnthropicProvider")
|
|
149
163
|
model: Model name (e.g., "claude-3-haiku-20240307")
|
|
150
164
|
api_key: API key for fetching remote server config
|
|
165
|
+
runtime_options: Dynamic MCP runtime headers/access token
|
|
151
166
|
|
|
152
167
|
Returns:
|
|
153
168
|
GopherAgent instance
|
|
154
169
|
"""
|
|
155
|
-
|
|
170
|
+
builder = (
|
|
156
171
|
GopherAgentConfig.builder()
|
|
157
172
|
.provider(provider)
|
|
158
173
|
.model(model)
|
|
159
174
|
.api_key(api_key)
|
|
160
|
-
.build()
|
|
161
175
|
)
|
|
176
|
+
if runtime_options is not None:
|
|
177
|
+
builder.runtime_options(runtime_options)
|
|
178
|
+
return GopherAgent.create(builder.build())
|
|
162
179
|
|
|
163
180
|
@staticmethod
|
|
164
181
|
def create_with_server_config(
|
|
165
|
-
provider: str,
|
|
182
|
+
provider: str,
|
|
183
|
+
model: str,
|
|
184
|
+
server_config: str,
|
|
185
|
+
runtime_options: Optional[object] = None,
|
|
166
186
|
) -> "GopherAgent":
|
|
167
187
|
"""
|
|
168
188
|
Create a new GopherAgent with JSON server config.
|
|
@@ -171,21 +191,28 @@ class GopherAgent:
|
|
|
171
191
|
provider: Provider name (e.g., "AnthropicProvider")
|
|
172
192
|
model: Model name (e.g., "claude-3-haiku-20240307")
|
|
173
193
|
server_config: JSON server configuration
|
|
194
|
+
runtime_options: Dynamic MCP runtime headers/access token
|
|
174
195
|
|
|
175
196
|
Returns:
|
|
176
197
|
GopherAgent instance
|
|
177
198
|
"""
|
|
178
|
-
|
|
199
|
+
builder = (
|
|
179
200
|
GopherAgentConfig.builder()
|
|
180
201
|
.provider(provider)
|
|
181
202
|
.model(model)
|
|
182
203
|
.server_config(server_config)
|
|
183
|
-
.build()
|
|
184
204
|
)
|
|
205
|
+
if runtime_options is not None:
|
|
206
|
+
builder.runtime_options(runtime_options)
|
|
207
|
+
return GopherAgent.create(builder.build())
|
|
185
208
|
|
|
186
209
|
@staticmethod
|
|
187
210
|
def create_with_server_id(
|
|
188
|
-
provider: str,
|
|
211
|
+
provider: str,
|
|
212
|
+
model: str,
|
|
213
|
+
api_key: str,
|
|
214
|
+
server_id: str,
|
|
215
|
+
runtime_options: Optional[object] = None,
|
|
189
216
|
) -> "GopherAgent":
|
|
190
217
|
"""
|
|
191
218
|
Create a new GopherAgent scoped to a single MCP server by id.
|
|
@@ -199,19 +226,24 @@ class GopherAgent:
|
|
|
199
226
|
model: Model identifier accepted by the chosen provider
|
|
200
227
|
api_key: Gopher API key
|
|
201
228
|
server_id: MCP server id to scope the agent to
|
|
229
|
+
runtime_options: Dynamic MCP runtime headers/access token
|
|
202
230
|
|
|
203
231
|
Returns:
|
|
204
232
|
GopherAgent instance
|
|
205
233
|
"""
|
|
206
234
|
return GopherAgent._create_from_ffi(
|
|
207
235
|
lambda lib: lib.agent_create_by_server_id(
|
|
208
|
-
provider, model, api_key, server_id
|
|
236
|
+
provider, model, api_key, server_id, runtime_options
|
|
209
237
|
)
|
|
210
238
|
)
|
|
211
239
|
|
|
212
240
|
@staticmethod
|
|
213
241
|
def create_with_server_name(
|
|
214
|
-
provider: str,
|
|
242
|
+
provider: str,
|
|
243
|
+
model: str,
|
|
244
|
+
api_key: str,
|
|
245
|
+
server_name: str,
|
|
246
|
+
runtime_options: Optional[object] = None,
|
|
215
247
|
) -> "GopherAgent":
|
|
216
248
|
"""
|
|
217
249
|
Create a new GopherAgent scoped to a single MCP server by name.
|
|
@@ -225,19 +257,24 @@ class GopherAgent:
|
|
|
225
257
|
model: Model identifier accepted by the chosen provider
|
|
226
258
|
api_key: Gopher API key
|
|
227
259
|
server_name: MCP server name to scope the agent to
|
|
260
|
+
runtime_options: Dynamic MCP runtime headers/access token
|
|
228
261
|
|
|
229
262
|
Returns:
|
|
230
263
|
GopherAgent instance
|
|
231
264
|
"""
|
|
232
265
|
return GopherAgent._create_from_ffi(
|
|
233
266
|
lambda lib: lib.agent_create_by_server_name(
|
|
234
|
-
provider, model, api_key, server_name
|
|
267
|
+
provider, model, api_key, server_name, runtime_options
|
|
235
268
|
)
|
|
236
269
|
)
|
|
237
270
|
|
|
238
271
|
@staticmethod
|
|
239
272
|
def create_with_gateway_id(
|
|
240
|
-
provider: str,
|
|
273
|
+
provider: str,
|
|
274
|
+
model: str,
|
|
275
|
+
api_key: str,
|
|
276
|
+
gateway_id: str,
|
|
277
|
+
runtime_options: Optional[object] = None,
|
|
241
278
|
) -> "GopherAgent":
|
|
242
279
|
"""
|
|
243
280
|
Create a new GopherAgent scoped to a single MCP gateway by id.
|
|
@@ -251,19 +288,24 @@ class GopherAgent:
|
|
|
251
288
|
model: Model identifier accepted by the chosen provider
|
|
252
289
|
api_key: Gopher API key
|
|
253
290
|
gateway_id: MCP gateway id to scope the agent to
|
|
291
|
+
runtime_options: Dynamic MCP runtime headers/access token
|
|
254
292
|
|
|
255
293
|
Returns:
|
|
256
294
|
GopherAgent instance
|
|
257
295
|
"""
|
|
258
296
|
return GopherAgent._create_from_ffi(
|
|
259
297
|
lambda lib: lib.agent_create_by_gateway_id(
|
|
260
|
-
provider, model, api_key, gateway_id
|
|
298
|
+
provider, model, api_key, gateway_id, runtime_options
|
|
261
299
|
)
|
|
262
300
|
)
|
|
263
301
|
|
|
264
302
|
@staticmethod
|
|
265
303
|
def create_with_gateway_name(
|
|
266
|
-
provider: str,
|
|
304
|
+
provider: str,
|
|
305
|
+
model: str,
|
|
306
|
+
api_key: str,
|
|
307
|
+
gateway_name: str,
|
|
308
|
+
runtime_options: Optional[object] = None,
|
|
267
309
|
) -> "GopherAgent":
|
|
268
310
|
"""
|
|
269
311
|
Create a new GopherAgent scoped to a single MCP gateway by name.
|
|
@@ -277,18 +319,24 @@ class GopherAgent:
|
|
|
277
319
|
model: Model identifier accepted by the chosen provider
|
|
278
320
|
api_key: Gopher API key
|
|
279
321
|
gateway_name: MCP gateway name to scope the agent to
|
|
322
|
+
runtime_options: Dynamic MCP runtime headers/access token
|
|
280
323
|
|
|
281
324
|
Returns:
|
|
282
325
|
GopherAgent instance
|
|
283
326
|
"""
|
|
284
327
|
return GopherAgent._create_from_ffi(
|
|
285
328
|
lambda lib: lib.agent_create_by_gateway_name(
|
|
286
|
-
provider, model, api_key, gateway_name
|
|
329
|
+
provider, model, api_key, gateway_name, runtime_options
|
|
287
330
|
)
|
|
288
331
|
)
|
|
289
332
|
|
|
290
333
|
@staticmethod
|
|
291
|
-
def create_with_url(
|
|
334
|
+
def create_with_url(
|
|
335
|
+
provider: str,
|
|
336
|
+
model: str,
|
|
337
|
+
url: str,
|
|
338
|
+
runtime_options: Optional[object] = None,
|
|
339
|
+
) -> "GopherAgent":
|
|
292
340
|
"""
|
|
293
341
|
Create a new GopherAgent for a single MCP server reachable at a URL.
|
|
294
342
|
|
|
@@ -301,12 +349,13 @@ class GopherAgent:
|
|
|
301
349
|
provider: Provider name (e.g., "AnthropicProvider")
|
|
302
350
|
model: Model identifier accepted by the chosen provider
|
|
303
351
|
url: Full URL of the MCP server (e.g., "http://127.0.0.1:8080/mcp")
|
|
352
|
+
runtime_options: Dynamic MCP runtime headers/access token
|
|
304
353
|
|
|
305
354
|
Returns:
|
|
306
355
|
GopherAgent instance
|
|
307
356
|
"""
|
|
308
357
|
return GopherAgent._create_from_ffi(
|
|
309
|
-
lambda lib: lib.agent_create_by_url(provider, model, url)
|
|
358
|
+
lambda lib: lib.agent_create_by_url(provider, model, url, runtime_options)
|
|
310
359
|
)
|
|
311
360
|
|
|
312
361
|
@staticmethod
|
|
@@ -325,7 +374,8 @@ class GopherAgent:
|
|
|
325
374
|
|
|
326
375
|
lib = GopherOrchLibrary.get_instance()
|
|
327
376
|
if lib is None:
|
|
328
|
-
|
|
377
|
+
load_error = GopherOrchLibrary.get_load_error_message()
|
|
378
|
+
raise AgentError(f"Native library not available.\n{load_error}")
|
|
329
379
|
|
|
330
380
|
try:
|
|
331
381
|
handle = create_handle(lib)
|
|
@@ -335,7 +385,7 @@ class GopherAgent:
|
|
|
335
385
|
if handle is None:
|
|
336
386
|
error = lib.get_last_error_message()
|
|
337
387
|
lib.clear_error()
|
|
338
|
-
raise AgentError(error or
|
|
388
|
+
raise AgentError(error or _build_create_error_message())
|
|
339
389
|
|
|
340
390
|
return GopherAgent(handle)
|
|
341
391
|
|
|
@@ -357,13 +407,18 @@ class GopherAgent:
|
|
|
357
407
|
|
|
358
408
|
lib = GopherOrchLibrary.get_instance()
|
|
359
409
|
if lib is None:
|
|
360
|
-
|
|
410
|
+
load_error = GopherOrchLibrary.get_load_error_message()
|
|
411
|
+
raise AgentError(f"Native library not available.\n{load_error}")
|
|
361
412
|
|
|
362
413
|
try:
|
|
363
414
|
response = lib.agent_run(self._handle, query, timeout_ms)
|
|
364
415
|
if response is None:
|
|
365
|
-
|
|
416
|
+
error = lib.get_last_error_message()
|
|
417
|
+
lib.clear_error()
|
|
418
|
+
raise AgentError(error or f'No response for query: "{query}"')
|
|
366
419
|
return response
|
|
420
|
+
except AgentError:
|
|
421
|
+
raise
|
|
367
422
|
except Exception as e:
|
|
368
423
|
raise AgentError(f"Query execution failed: {e}")
|
|
369
424
|
|
|
@@ -421,3 +476,20 @@ def _setup_cleanup_handler() -> None:
|
|
|
421
476
|
|
|
422
477
|
_cleanup_handler_registered = True
|
|
423
478
|
atexit.register(GopherAgent.shutdown)
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
def _build_create_error_message() -> str:
|
|
482
|
+
"""
|
|
483
|
+
Build the AgentError message for a null native create*() result.
|
|
484
|
+
|
|
485
|
+
Native should usually populate gopher_orch_last_error, but a few
|
|
486
|
+
defensive paths can still return null without details. Keep that
|
|
487
|
+
fallback actionable instead of raising only "Failed to create agent".
|
|
488
|
+
"""
|
|
489
|
+
return (
|
|
490
|
+
"Failed to create agent: native library returned null without a "
|
|
491
|
+
"specific error. Most often this means every configured MCP server "
|
|
492
|
+
"failed to connect or returned no tools (TLS / network / bad URL), "
|
|
493
|
+
"or the LLM provider could not be initialized. Set GOPHER_DEBUG=1 to "
|
|
494
|
+
"see native-side logs."
|
|
495
|
+
)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Auth Module - Reusable OAuth/JWT authentication for Python MCP servers.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from gopher_mcp_python.auth.gopher_auth import GopherAuth
|
|
6
|
+
from gopher_mcp_python.auth.errors import (
|
|
7
|
+
GopherAuthError,
|
|
8
|
+
TokenValidationError,
|
|
9
|
+
InsufficientScopesError,
|
|
10
|
+
JwksError,
|
|
11
|
+
ConfigurationError,
|
|
12
|
+
TokenExchangeError,
|
|
13
|
+
)
|
|
14
|
+
from gopher_mcp_python.auth.scope_helpers import (
|
|
15
|
+
has_scope,
|
|
16
|
+
has_all_scopes,
|
|
17
|
+
has_any_scope,
|
|
18
|
+
)
|
|
19
|
+
from gopher_mcp_python.ffi.auth import (
|
|
20
|
+
AutoRefreshResult,
|
|
21
|
+
GopherAuthClient,
|
|
22
|
+
GopherAuthConfig,
|
|
23
|
+
GopherOAuthClient,
|
|
24
|
+
GopherSessionManager,
|
|
25
|
+
GopherValidationOptions,
|
|
26
|
+
RegistrationResponse,
|
|
27
|
+
TokenPayload,
|
|
28
|
+
TokenResponse,
|
|
29
|
+
ValidationResult,
|
|
30
|
+
gopher_auth_auto_refresh,
|
|
31
|
+
gopher_auth_build_oidc_discovery_metadata,
|
|
32
|
+
gopher_auth_build_oauth_server_metadata,
|
|
33
|
+
gopher_auth_build_protected_resource_metadata,
|
|
34
|
+
gopher_auth_extract_bearer_token,
|
|
35
|
+
gopher_auth_extract_method,
|
|
36
|
+
gopher_auth_extract_path,
|
|
37
|
+
gopher_auth_url_decode,
|
|
38
|
+
gopher_auth_url_encode,
|
|
39
|
+
gopher_auth_validate_all_scopes,
|
|
40
|
+
gopher_auth_validate_any_scopes,
|
|
41
|
+
gopher_auth_validate_idp,
|
|
42
|
+
gopher_create_validation_options,
|
|
43
|
+
gopher_generate_www_authenticate_header,
|
|
44
|
+
gopher_generate_www_authenticate_header_v2,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
__all__ = [
|
|
48
|
+
"GopherAuth",
|
|
49
|
+
"GopherAuthError",
|
|
50
|
+
"TokenValidationError",
|
|
51
|
+
"InsufficientScopesError",
|
|
52
|
+
"JwksError",
|
|
53
|
+
"ConfigurationError",
|
|
54
|
+
"TokenExchangeError",
|
|
55
|
+
"has_scope",
|
|
56
|
+
"has_all_scopes",
|
|
57
|
+
"has_any_scope",
|
|
58
|
+
"AutoRefreshResult",
|
|
59
|
+
"GopherAuthClient",
|
|
60
|
+
"GopherAuthConfig",
|
|
61
|
+
"GopherOAuthClient",
|
|
62
|
+
"GopherSessionManager",
|
|
63
|
+
"GopherValidationOptions",
|
|
64
|
+
"RegistrationResponse",
|
|
65
|
+
"TokenPayload",
|
|
66
|
+
"TokenResponse",
|
|
67
|
+
"ValidationResult",
|
|
68
|
+
"gopher_auth_auto_refresh",
|
|
69
|
+
"gopher_auth_build_oidc_discovery_metadata",
|
|
70
|
+
"gopher_auth_build_oauth_server_metadata",
|
|
71
|
+
"gopher_auth_build_protected_resource_metadata",
|
|
72
|
+
"gopher_auth_extract_bearer_token",
|
|
73
|
+
"gopher_auth_extract_method",
|
|
74
|
+
"gopher_auth_extract_path",
|
|
75
|
+
"gopher_auth_url_decode",
|
|
76
|
+
"gopher_auth_url_encode",
|
|
77
|
+
"gopher_auth_validate_all_scopes",
|
|
78
|
+
"gopher_auth_validate_any_scopes",
|
|
79
|
+
"gopher_auth_validate_idp",
|
|
80
|
+
"gopher_create_validation_options",
|
|
81
|
+
"gopher_generate_www_authenticate_header",
|
|
82
|
+
"gopher_generate_www_authenticate_header_v2",
|
|
83
|
+
]
|