golf-mcp 0.1.20__tar.gz → 0.2.1__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.
Potentially problematic release.
This version of golf-mcp might be problematic. Click here for more details.
- golf_mcp-0.2.1/.docs/fastmcp-diff.md +27 -0
- {golf_mcp-0.1.20/src/golf_mcp.egg-info → golf_mcp-0.2.1}/PKG-INFO +51 -104
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/README.md +48 -102
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/pyproject.toml +13 -7
- golf_mcp-0.2.1/setup.py +87 -0
- golf_mcp-0.2.1/src/golf/__init__.py +9 -0
- golf_mcp-0.2.1/src/golf/_endpoints_fallback.py +10 -0
- golf_mcp-0.2.1/src/golf/auth/__init__.py +274 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/auth/api_key.py +6 -14
- golf_mcp-0.2.1/src/golf/auth/factory.py +358 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/auth/helpers.py +12 -42
- golf_mcp-0.2.1/src/golf/auth/providers.py +446 -0
- golf_mcp-0.2.1/src/golf/auth/registry.py +256 -0
- golf_mcp-0.2.1/src/golf/cli/branding.py +192 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/cli/main.py +28 -69
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/commands/__init__.py +2 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/commands/build.py +4 -7
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/commands/init.py +30 -53
- golf_mcp-0.2.1/src/golf/commands/run.py +125 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/builder.py +355 -414
- golf_mcp-0.2.1/src/golf/core/builder_auth.py +209 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/builder_telemetry.py +26 -3
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/config.py +38 -59
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/parser.py +132 -139
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/platform.py +12 -10
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/telemetry.py +11 -19
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/transformer.py +38 -15
- golf_mcp-0.2.1/src/golf/examples/basic/.coverage +0 -0
- golf_mcp-0.2.1/src/golf/examples/basic/.env.example +8 -0
- golf_mcp-0.2.1/src/golf/examples/basic/README.md +133 -0
- golf_mcp-0.2.1/src/golf/examples/basic/auth.py +76 -0
- golf_mcp-0.2.1/src/golf/examples/basic/golf.json +5 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/.gitignore +2 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/class_index.html +547 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/coverage_html_cb_6fb7b396.js +733 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/favicon_32_cb_58284776.png +0 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/function_index.html +2091 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/index.html +349 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/keybd_closed_cb_ce680311.png +0 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/status.json +1 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/style_cb_8e611ae1.css +337 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496___init___py.html +323 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_api_key_py.html +170 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_factory_py.html +430 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_helpers_py.html +288 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_providers_py.html +493 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_registry_py.html +353 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_3ec3b3f490dc0950___init___py.html +120 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_3ec3b3f490dc0950_instrumentation_py.html +1535 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db___init___py.html +98 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db_branding_py.html +289 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db_main_py.html +476 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_5a6c4e6bcc86fb2f___init___py.html +97 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6cadab9ec0df475d___init___py.html +102 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6cadab9ec0df475d_build_py.html +178 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6cadab9ec0df475d_init_py.html +387 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6cadab9ec0df475d_run_py.html +222 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6fcdee0582ba84e4___init___py.html +106 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6fcdee0582ba84e4__endpoints_fallback_py.html +107 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217___init___py.html +98 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_auth_py.html +306 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_metrics_py.html +329 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_py.html +1471 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_telemetry_py.html +186 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_config_py.html +315 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_parser_py.html +1149 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_platform_py.html +279 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_telemetry_py.html +589 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_transformer_py.html +286 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7d7da37693a43688___init___py.html +107 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7d7da37693a43688_collector_py.html +417 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7d7da37693a43688_registry_py.html +109 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_abe733142b40ad4e___init___py.html +109 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_abe733142b40ad4e_context_py.html +150 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_abe733142b40ad4e_elicitation_py.html +267 -0
- golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_abe733142b40ad4e_sampling_py.html +318 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/prompts/welcome.py +3 -5
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/resources/current_time.py +5 -13
- golf_mcp-0.2.1/src/golf/examples/basic/resources/weather/city.py +46 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/resources/weather/common.py +4 -11
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/resources/weather/current.py +5 -5
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/resources/weather/forecast.py +5 -5
- golf_mcp-0.2.1/src/golf/examples/basic/tools/calculator.py +94 -0
- golf_mcp-0.2.1/src/golf/examples/basic/tools/say/hello.py +65 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/metrics/collector.py +100 -19
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/telemetry/__init__.py +4 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/telemetry/instrumentation.py +484 -178
- golf_mcp-0.2.1/src/golf/utilities/__init__.py +12 -0
- golf_mcp-0.2.1/src/golf/utilities/context.py +53 -0
- golf_mcp-0.2.1/src/golf/utilities/elicitation.py +170 -0
- golf_mcp-0.2.1/src/golf/utilities/sampling.py +221 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1/src/golf_mcp.egg-info}/PKG-INFO +51 -104
- golf_mcp-0.2.1/src/golf_mcp.egg-info/SOURCES.txt +107 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf_mcp.egg-info/requires.txt +2 -1
- golf_mcp-0.1.20/.docs/fast-mcp.md +0 -4886
- golf_mcp-0.1.20/.docs/fastmcp-example-1.py +0 -30
- golf_mcp-0.1.20/.docs/fastmcp-example-2.py +0 -114
- golf_mcp-0.1.20/.docs/oauth-implementation.md +0 -316
- golf_mcp-0.1.20/.docs/oauth.md +0 -305
- golf_mcp-0.1.20/src/golf/__init__.py +0 -1
- golf_mcp-0.1.20/src/golf/auth/__init__.py +0 -122
- golf_mcp-0.1.20/src/golf/auth/oauth.py +0 -861
- golf_mcp-0.1.20/src/golf/auth/provider.py +0 -115
- golf_mcp-0.1.20/src/golf/commands/run.py +0 -95
- golf_mcp-0.1.20/src/golf/core/builder_auth.py +0 -290
- golf_mcp-0.1.20/src/golf/examples/api_key/.env +0 -2
- golf_mcp-0.1.20/src/golf/examples/api_key/.env.example +0 -1
- golf_mcp-0.1.20/src/golf/examples/api_key/README.md +0 -84
- golf_mcp-0.1.20/src/golf/examples/api_key/golf.json +0 -8
- golf_mcp-0.1.20/src/golf/examples/api_key/pre_build.py +0 -11
- golf_mcp-0.1.20/src/golf/examples/api_key/tools/issues/create.py +0 -93
- golf_mcp-0.1.20/src/golf/examples/api_key/tools/issues/list.py +0 -92
- golf_mcp-0.1.20/src/golf/examples/api_key/tools/repos/list.py +0 -111
- golf_mcp-0.1.20/src/golf/examples/api_key/tools/search/code.py +0 -106
- golf_mcp-0.1.20/src/golf/examples/api_key/tools/users/get.py +0 -82
- golf_mcp-0.1.20/src/golf/examples/basic/.env +0 -5
- golf_mcp-0.1.20/src/golf/examples/basic/.env.example +0 -4
- golf_mcp-0.1.20/src/golf/examples/basic/README.md +0 -61
- golf_mcp-0.1.20/src/golf/examples/basic/golf.json +0 -8
- golf_mcp-0.1.20/src/golf/examples/basic/pre_build.py +0 -28
- golf_mcp-0.1.20/src/golf/examples/basic/tools/github_user.py +0 -65
- golf_mcp-0.1.20/src/golf/examples/basic/tools/hello.py +0 -34
- golf_mcp-0.1.20/src/golf/examples/basic/tools/payments/charge.py +0 -70
- golf_mcp-0.1.20/src/golf/examples/basic/tools/payments/common.py +0 -36
- golf_mcp-0.1.20/src/golf/examples/basic/tools/payments/refund.py +0 -61
- golf_mcp-0.1.20/src/golf_mcp.egg-info/SOURCES.txt +0 -71
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/.docs/docs.md +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/.docs/mcp.md +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/LICENSE +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/MANIFEST.in +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/setup.cfg +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/cli/__init__.py +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/__init__.py +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/builder_metrics.py +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/__init__.py +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/resources/info.py +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/metrics/__init__.py +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/metrics/registry.py +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf_mcp.egg-info/dependency_links.txt +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf_mcp.egg-info/entry_points.txt +0 -0
- {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf_mcp.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
**FastMCP Changes Since v2.5.1**
|
|
2
|
+
|
|
3
|
+
**Breaking Changes**
|
|
4
|
+
|
|
5
|
+
* **Decorator & API Refactor**: Decorators now return their created Tool/Resource object; old auto-conversion methods are deprecated.
|
|
6
|
+
* **OpenAPI Routes as Tools**: All OpenAPI endpoints are treated as Tools by default, changing prior behavior.
|
|
7
|
+
* **MCP Spec 1.10 (v2.10.0)**: `client.call_tool()` now returns a `CallToolResult` (with `result` property) instead of raw JSON. Requires MCP Python SDK ≥1.10.
|
|
8
|
+
* **CLI Flag Rename**: `fastmcp run --server` is replaced by `--name`.
|
|
9
|
+
* **Removed Custom Separators**: Support for custom nested-resource separators was dropped.
|
|
10
|
+
|
|
11
|
+
**Non-Breaking Improvements & New Features**
|
|
12
|
+
|
|
13
|
+
* **Built-In Authentication**
|
|
14
|
+
|
|
15
|
+
* Bearer-token support (v2.6.0)
|
|
16
|
+
* OAuth2 & WorkOS AuthProvider integration (v2.11.0)
|
|
17
|
+
* Enhanced JWT handling, scopes, and debug logging
|
|
18
|
+
* **Session & State Management**
|
|
19
|
+
|
|
20
|
+
* `ctx.session_id` property for each request (v2.9.0)
|
|
21
|
+
* Persistent session-state dict via `ctx.state` (v2.11.0)
|
|
22
|
+
* **Middleware System** (v2.9.0): Plug in logging, auth checks, rate limiting, etc.
|
|
23
|
+
* **Tool Transforms & Tagging** (v2.8.0): Wrap, rename, enable/disable tools at runtime; filter by tags.
|
|
24
|
+
* **Structured Outputs & Elicitation** (v2.10.0): JSON schemas for tool outputs; interactive parameter prompting.
|
|
25
|
+
* **Hot-Reload Notifications** (v2.9.1): Clients are notified when tools/resources change at runtime.
|
|
26
|
+
* **Audio Content Support** (v2.8.1): Tools can handle audio inputs/outputs.
|
|
27
|
+
* **Performance & Stability**: Optimized OpenAPI parsing, concurrency fixes, standardized logging.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: golf-mcp
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Framework for building MCP servers
|
|
5
5
|
Author-email: Antoni Gmitruk <antoni@golf.dev>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -21,8 +21,9 @@ Description-Content-Type: text/markdown
|
|
|
21
21
|
License-File: LICENSE
|
|
22
22
|
Requires-Dist: typer>=0.15.4
|
|
23
23
|
Requires-Dist: rich>=14.0.0
|
|
24
|
-
Requires-Dist: fastmcp<
|
|
24
|
+
Requires-Dist: fastmcp<3.0.0,>=2.11.0
|
|
25
25
|
Requires-Dist: pydantic>=2.11.0
|
|
26
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
26
27
|
Requires-Dist: python-dotenv>=1.1.0
|
|
27
28
|
Requires-Dist: black>=24.10.0
|
|
28
29
|
Requires-Dist: pyjwt>=2.0.0
|
|
@@ -67,9 +68,9 @@ Dynamic: license-file
|
|
|
67
68
|
|
|
68
69
|
## Overview
|
|
69
70
|
|
|
70
|
-
Golf is a **framework** designed to streamline the creation of MCP server applications. It allows developers to define server's capabilities—*tools*, *prompts*, and *resources*—as simple Python files within a conventional directory structure. Golf then automatically discovers, parses, and compiles these components into a runnable
|
|
71
|
+
Golf is a **framework** designed to streamline the creation of MCP server applications. It allows developers to define server's capabilities—*tools*, *prompts*, and *resources*—as simple Python files within a conventional directory structure. Golf then automatically discovers, parses, and compiles these components into a runnable MCP server, minimizing boilerplate and accelerating development.
|
|
71
72
|
|
|
72
|
-
With Golf, you
|
|
73
|
+
With Golf v0.2.0, you get **enterprise-grade authentication** (JWT, OAuth Server, API key, development tokens), **built-in utilities** for LLM interactions, and **automatic telemetry** integration. Focus on implementing your agent's logic while Golf handles authentication, monitoring, and server infrastructure.
|
|
73
74
|
|
|
74
75
|
## Quick Start
|
|
75
76
|
|
|
@@ -101,7 +102,7 @@ cd your-project-name
|
|
|
101
102
|
golf build dev
|
|
102
103
|
golf run
|
|
103
104
|
```
|
|
104
|
-
This will start the
|
|
105
|
+
This will start the MCP server, typically on `http://localhost:3000` (configurable in `golf.json`).
|
|
105
106
|
|
|
106
107
|
That's it! Your Golf server is running and ready for integration.
|
|
107
108
|
|
|
@@ -124,10 +125,11 @@ A Golf project initialized with `golf init` will have a structure similar to thi
|
|
|
124
125
|
│ └─ welcome.py # Example prompt
|
|
125
126
|
│
|
|
126
127
|
├─ .env # Environment variables (e.g., API keys, server port)
|
|
127
|
-
└─
|
|
128
|
+
└─ auth.py # Authentication configuration (JWT, OAuth Server, API key, dev tokens)
|
|
128
129
|
```
|
|
129
130
|
|
|
130
131
|
- **`golf.json`**: Configures server name, port, transport, telemetry, and other build settings.
|
|
132
|
+
- **`auth.py`**: Dedicated authentication configuration file (new in v0.2.0, breaking change from v0.1.x authentication API) for JWT, OAuth Server, API key, or development authentication.
|
|
131
133
|
- **`tools/`**, **`resources/`**, **`prompts/`**: Contain your Python files, each defining a single component. These directories can also contain nested subdirectories to further organize your components (e.g., `tools/payments/charge.py`). The module docstring of each file serves as the component's description.
|
|
132
134
|
- Component IDs are automatically derived from their file path. For example, `tools/hello.py` becomes `hello`, and a nested file like `tools/payments/submit.py` would become `submit_payments` (filename, followed by reversed parent directories under the main category, joined by underscores).
|
|
133
135
|
- **`common.py`** (not shown, but can be placed in subdirectories like `tools/payments/common.py`): Used to share code (clients, models, etc.) among components in the same subdirectory.
|
|
@@ -164,118 +166,63 @@ export = hello
|
|
|
164
166
|
```
|
|
165
167
|
Golf will automatically discover this file. The module docstring `"""Hello World tool {{project_name}}."""` is used as the tool's description. It infers parameters from the `hello` function's signature and uses the `Output` Pydantic model for the output schema. The tool will be registered with the ID `hello`.
|
|
166
168
|
|
|
167
|
-
##
|
|
169
|
+
## Authentication & Features
|
|
168
170
|
|
|
169
|
-
|
|
171
|
+
Golf includes enterprise-grade authentication, built-in utilities, and automatic telemetry:
|
|
170
172
|
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### Key Configuration Options:
|
|
199
|
-
|
|
200
|
-
- **`name`**: The identifier for your MCP server. This will be shown to clients connecting to your server.
|
|
201
|
-
- **`transport`**: Choose based on your client needs:
|
|
202
|
-
- `"sse"` is ideal for web-based clients and real-time communication
|
|
203
|
-
- `"streamable-http"` provides HTTP streaming for traditional API clients
|
|
204
|
-
- `"stdio"` enables integration with command-line tools and scripts
|
|
205
|
-
- **`host` & `port`**: Control where your server listens. Use `"127.0.0.1"` for local development or `"0.0.0.0"` to accept external connections.
|
|
206
|
-
- **`stateless_http`**: When true, makes the streamable-http transport stateless by creating a new session for each request. This ensures that server restarts don't break existing client connections, making the server truly stateless.
|
|
207
|
-
- **`health_check_enabled`**: When true, enables a health check endpoint for Kubernetes readiness/liveness probes and load balancers
|
|
208
|
-
- **`health_check_path`**: Customizable path for the health check endpoint (defaults to "/health")
|
|
209
|
-
- **`health_check_response`**: Customizable response text for successful health checks (defaults to "OK")
|
|
210
|
-
- **`opentelemetry_enabled`**: When true, enables distributed tracing for debugging and monitoring your MCP server
|
|
211
|
-
- **`opentelemetry_default_exporter`**: Sets the default trace exporter. Can be overridden by the `OTEL_TRACES_EXPORTER` environment variable
|
|
212
|
-
|
|
213
|
-
## Features
|
|
214
|
-
|
|
215
|
-
### 🏥 Health Check Support
|
|
216
|
-
|
|
217
|
-
Golf includes built-in health check endpoint support for production deployments. When enabled, it automatically adds a custom HTTP route that can be used by:
|
|
218
|
-
- Kubernetes readiness and liveness probes
|
|
219
|
-
- Load balancers and reverse proxies
|
|
220
|
-
- Monitoring systems
|
|
221
|
-
- Container orchestration platforms
|
|
222
|
-
|
|
223
|
-
#### Configuration
|
|
224
|
-
|
|
225
|
-
Enable health checks in your `golf.json`:
|
|
226
|
-
```json
|
|
227
|
-
{
|
|
228
|
-
"health_check_enabled": true,
|
|
229
|
-
"health_check_path": "/health",
|
|
230
|
-
"health_check_response": "Service is healthy"
|
|
231
|
-
}
|
|
173
|
+
```python
|
|
174
|
+
# auth.py - Configure authentication
|
|
175
|
+
from golf.auth import configure_auth, JWTAuthConfig, StaticTokenConfig, OAuthServerConfig
|
|
176
|
+
|
|
177
|
+
# JWT authentication (production)
|
|
178
|
+
configure_auth(JWTAuthConfig(
|
|
179
|
+
jwks_uri_env_var="JWKS_URI",
|
|
180
|
+
issuer_env_var="JWT_ISSUER",
|
|
181
|
+
audience_env_var="JWT_AUDIENCE",
|
|
182
|
+
required_scopes=["read", "write"]
|
|
183
|
+
))
|
|
184
|
+
|
|
185
|
+
# OAuth Server mode (Golf acts as OAuth 2.0 server)
|
|
186
|
+
# configure_auth(OAuthServerConfig(
|
|
187
|
+
# base_url="https://your-golf-server.com",
|
|
188
|
+
# valid_scopes=["read", "write", "admin"]
|
|
189
|
+
# ))
|
|
190
|
+
|
|
191
|
+
# Static tokens (development only)
|
|
192
|
+
# configure_auth(StaticTokenConfig(
|
|
193
|
+
# tokens={"dev-token": {"client_id": "dev", "scopes": ["read"]}}
|
|
194
|
+
# ))
|
|
195
|
+
|
|
196
|
+
# Built-in utilities available in all tools
|
|
197
|
+
from golf.utils import elicit, sample, get_context
|
|
232
198
|
```
|
|
233
199
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
"""Health check endpoint for Kubernetes and load balancers."""
|
|
239
|
-
return PlainTextResponse("Service is healthy")
|
|
200
|
+
```bash
|
|
201
|
+
# Automatic telemetry with Golf Platform
|
|
202
|
+
export GOLF_API_KEY="your-key"
|
|
203
|
+
golf run # ✅ Telemetry enabled automatically
|
|
240
204
|
```
|
|
241
205
|
|
|
242
|
-
|
|
206
|
+
**[📚 Complete Documentation →](https://docs.golf.dev)**
|
|
243
207
|
|
|
244
|
-
|
|
245
|
-
- Tool executions with arguments and results
|
|
246
|
-
- Resource reads and template expansions
|
|
247
|
-
- Prompt generations
|
|
248
|
-
- HTTP requests and sessions
|
|
208
|
+
## Configuration
|
|
249
209
|
|
|
250
|
-
|
|
210
|
+
Basic configuration in `golf.json`:
|
|
251
211
|
|
|
252
|
-
Enable OpenTelemetry in your `golf.json`:
|
|
253
212
|
```json
|
|
254
213
|
{
|
|
255
|
-
"
|
|
256
|
-
"
|
|
214
|
+
"name": "My Golf Server",
|
|
215
|
+
"host": "localhost",
|
|
216
|
+
"port": 3000,
|
|
217
|
+
"transport": "sse",
|
|
218
|
+
"opentelemetry_enabled": false,
|
|
219
|
+
"detailed_tracing": false
|
|
257
220
|
}
|
|
258
221
|
```
|
|
259
222
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
OTEL_TRACES_EXPORTER=otlp_http
|
|
264
|
-
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces
|
|
265
|
-
OTEL_SERVICE_NAME=my-golf-server # Optional, defaults to project name
|
|
266
|
-
|
|
267
|
-
# For console exporter (debugging)
|
|
268
|
-
OTEL_TRACES_EXPORTER=console
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
**Note**: When using the OTLP HTTP exporter, you must set `OTEL_EXPORTER_OTLP_ENDPOINT`. If not configured, Golf will display a warning and disable tracing to avoid errors.
|
|
272
|
-
|
|
273
|
-
## Roadmap
|
|
274
|
-
|
|
275
|
-
Here are the things we are working hard on:
|
|
276
|
-
|
|
277
|
-
* **`golf deploy` command for one click deployments to Vercel, Blaxel and other providers**
|
|
278
|
-
* **Production-ready OAuth token management, to allow for persistent, encrypted token storage and client mapping**
|
|
223
|
+
- **`transport`**: Choose `"sse"`, `"streamable-http"`, or `"stdio"`
|
|
224
|
+
- **`opentelemetry_enabled`**: Auto-enabled with `GOLF_API_KEY`
|
|
225
|
+
- **`detailed_tracing`**: Capture input/output (use carefully with sensitive data)
|
|
279
226
|
|
|
280
227
|
|
|
281
228
|
## Privacy & Telemetry
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
|
|
29
29
|
## Overview
|
|
30
30
|
|
|
31
|
-
Golf is a **framework** designed to streamline the creation of MCP server applications. It allows developers to define server's capabilities—*tools*, *prompts*, and *resources*—as simple Python files within a conventional directory structure. Golf then automatically discovers, parses, and compiles these components into a runnable
|
|
31
|
+
Golf is a **framework** designed to streamline the creation of MCP server applications. It allows developers to define server's capabilities—*tools*, *prompts*, and *resources*—as simple Python files within a conventional directory structure. Golf then automatically discovers, parses, and compiles these components into a runnable MCP server, minimizing boilerplate and accelerating development.
|
|
32
32
|
|
|
33
|
-
With Golf, you
|
|
33
|
+
With Golf v0.2.0, you get **enterprise-grade authentication** (JWT, OAuth Server, API key, development tokens), **built-in utilities** for LLM interactions, and **automatic telemetry** integration. Focus on implementing your agent's logic while Golf handles authentication, monitoring, and server infrastructure.
|
|
34
34
|
|
|
35
35
|
## Quick Start
|
|
36
36
|
|
|
@@ -62,7 +62,7 @@ cd your-project-name
|
|
|
62
62
|
golf build dev
|
|
63
63
|
golf run
|
|
64
64
|
```
|
|
65
|
-
This will start the
|
|
65
|
+
This will start the MCP server, typically on `http://localhost:3000` (configurable in `golf.json`).
|
|
66
66
|
|
|
67
67
|
That's it! Your Golf server is running and ready for integration.
|
|
68
68
|
|
|
@@ -85,10 +85,11 @@ A Golf project initialized with `golf init` will have a structure similar to thi
|
|
|
85
85
|
│ └─ welcome.py # Example prompt
|
|
86
86
|
│
|
|
87
87
|
├─ .env # Environment variables (e.g., API keys, server port)
|
|
88
|
-
└─
|
|
88
|
+
└─ auth.py # Authentication configuration (JWT, OAuth Server, API key, dev tokens)
|
|
89
89
|
```
|
|
90
90
|
|
|
91
91
|
- **`golf.json`**: Configures server name, port, transport, telemetry, and other build settings.
|
|
92
|
+
- **`auth.py`**: Dedicated authentication configuration file (new in v0.2.0, breaking change from v0.1.x authentication API) for JWT, OAuth Server, API key, or development authentication.
|
|
92
93
|
- **`tools/`**, **`resources/`**, **`prompts/`**: Contain your Python files, each defining a single component. These directories can also contain nested subdirectories to further organize your components (e.g., `tools/payments/charge.py`). The module docstring of each file serves as the component's description.
|
|
93
94
|
- Component IDs are automatically derived from their file path. For example, `tools/hello.py` becomes `hello`, and a nested file like `tools/payments/submit.py` would become `submit_payments` (filename, followed by reversed parent directories under the main category, joined by underscores).
|
|
94
95
|
- **`common.py`** (not shown, but can be placed in subdirectories like `tools/payments/common.py`): Used to share code (clients, models, etc.) among components in the same subdirectory.
|
|
@@ -125,118 +126,63 @@ export = hello
|
|
|
125
126
|
```
|
|
126
127
|
Golf will automatically discover this file. The module docstring `"""Hello World tool {{project_name}}."""` is used as the tool's description. It infers parameters from the `hello` function's signature and uses the `Output` Pydantic model for the output schema. The tool will be registered with the ID `hello`.
|
|
127
128
|
|
|
128
|
-
##
|
|
129
|
+
## Authentication & Features
|
|
129
130
|
|
|
130
|
-
|
|
131
|
+
Golf includes enterprise-grade authentication, built-in utilities, and automatic telemetry:
|
|
131
132
|
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### Key Configuration Options:
|
|
160
|
-
|
|
161
|
-
- **`name`**: The identifier for your MCP server. This will be shown to clients connecting to your server.
|
|
162
|
-
- **`transport`**: Choose based on your client needs:
|
|
163
|
-
- `"sse"` is ideal for web-based clients and real-time communication
|
|
164
|
-
- `"streamable-http"` provides HTTP streaming for traditional API clients
|
|
165
|
-
- `"stdio"` enables integration with command-line tools and scripts
|
|
166
|
-
- **`host` & `port`**: Control where your server listens. Use `"127.0.0.1"` for local development or `"0.0.0.0"` to accept external connections.
|
|
167
|
-
- **`stateless_http`**: When true, makes the streamable-http transport stateless by creating a new session for each request. This ensures that server restarts don't break existing client connections, making the server truly stateless.
|
|
168
|
-
- **`health_check_enabled`**: When true, enables a health check endpoint for Kubernetes readiness/liveness probes and load balancers
|
|
169
|
-
- **`health_check_path`**: Customizable path for the health check endpoint (defaults to "/health")
|
|
170
|
-
- **`health_check_response`**: Customizable response text for successful health checks (defaults to "OK")
|
|
171
|
-
- **`opentelemetry_enabled`**: When true, enables distributed tracing for debugging and monitoring your MCP server
|
|
172
|
-
- **`opentelemetry_default_exporter`**: Sets the default trace exporter. Can be overridden by the `OTEL_TRACES_EXPORTER` environment variable
|
|
173
|
-
|
|
174
|
-
## Features
|
|
175
|
-
|
|
176
|
-
### 🏥 Health Check Support
|
|
177
|
-
|
|
178
|
-
Golf includes built-in health check endpoint support for production deployments. When enabled, it automatically adds a custom HTTP route that can be used by:
|
|
179
|
-
- Kubernetes readiness and liveness probes
|
|
180
|
-
- Load balancers and reverse proxies
|
|
181
|
-
- Monitoring systems
|
|
182
|
-
- Container orchestration platforms
|
|
183
|
-
|
|
184
|
-
#### Configuration
|
|
185
|
-
|
|
186
|
-
Enable health checks in your `golf.json`:
|
|
187
|
-
```json
|
|
188
|
-
{
|
|
189
|
-
"health_check_enabled": true,
|
|
190
|
-
"health_check_path": "/health",
|
|
191
|
-
"health_check_response": "Service is healthy"
|
|
192
|
-
}
|
|
133
|
+
```python
|
|
134
|
+
# auth.py - Configure authentication
|
|
135
|
+
from golf.auth import configure_auth, JWTAuthConfig, StaticTokenConfig, OAuthServerConfig
|
|
136
|
+
|
|
137
|
+
# JWT authentication (production)
|
|
138
|
+
configure_auth(JWTAuthConfig(
|
|
139
|
+
jwks_uri_env_var="JWKS_URI",
|
|
140
|
+
issuer_env_var="JWT_ISSUER",
|
|
141
|
+
audience_env_var="JWT_AUDIENCE",
|
|
142
|
+
required_scopes=["read", "write"]
|
|
143
|
+
))
|
|
144
|
+
|
|
145
|
+
# OAuth Server mode (Golf acts as OAuth 2.0 server)
|
|
146
|
+
# configure_auth(OAuthServerConfig(
|
|
147
|
+
# base_url="https://your-golf-server.com",
|
|
148
|
+
# valid_scopes=["read", "write", "admin"]
|
|
149
|
+
# ))
|
|
150
|
+
|
|
151
|
+
# Static tokens (development only)
|
|
152
|
+
# configure_auth(StaticTokenConfig(
|
|
153
|
+
# tokens={"dev-token": {"client_id": "dev", "scopes": ["read"]}}
|
|
154
|
+
# ))
|
|
155
|
+
|
|
156
|
+
# Built-in utilities available in all tools
|
|
157
|
+
from golf.utils import elicit, sample, get_context
|
|
193
158
|
```
|
|
194
159
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
"""Health check endpoint for Kubernetes and load balancers."""
|
|
200
|
-
return PlainTextResponse("Service is healthy")
|
|
160
|
+
```bash
|
|
161
|
+
# Automatic telemetry with Golf Platform
|
|
162
|
+
export GOLF_API_KEY="your-key"
|
|
163
|
+
golf run # ✅ Telemetry enabled automatically
|
|
201
164
|
```
|
|
202
165
|
|
|
203
|
-
|
|
166
|
+
**[📚 Complete Documentation →](https://docs.golf.dev)**
|
|
204
167
|
|
|
205
|
-
|
|
206
|
-
- Tool executions with arguments and results
|
|
207
|
-
- Resource reads and template expansions
|
|
208
|
-
- Prompt generations
|
|
209
|
-
- HTTP requests and sessions
|
|
168
|
+
## Configuration
|
|
210
169
|
|
|
211
|
-
|
|
170
|
+
Basic configuration in `golf.json`:
|
|
212
171
|
|
|
213
|
-
Enable OpenTelemetry in your `golf.json`:
|
|
214
172
|
```json
|
|
215
173
|
{
|
|
216
|
-
"
|
|
217
|
-
"
|
|
174
|
+
"name": "My Golf Server",
|
|
175
|
+
"host": "localhost",
|
|
176
|
+
"port": 3000,
|
|
177
|
+
"transport": "sse",
|
|
178
|
+
"opentelemetry_enabled": false,
|
|
179
|
+
"detailed_tracing": false
|
|
218
180
|
}
|
|
219
181
|
```
|
|
220
182
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
OTEL_TRACES_EXPORTER=otlp_http
|
|
225
|
-
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces
|
|
226
|
-
OTEL_SERVICE_NAME=my-golf-server # Optional, defaults to project name
|
|
227
|
-
|
|
228
|
-
# For console exporter (debugging)
|
|
229
|
-
OTEL_TRACES_EXPORTER=console
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
**Note**: When using the OTLP HTTP exporter, you must set `OTEL_EXPORTER_OTLP_ENDPOINT`. If not configured, Golf will display a warning and disable tracing to avoid errors.
|
|
233
|
-
|
|
234
|
-
## Roadmap
|
|
235
|
-
|
|
236
|
-
Here are the things we are working hard on:
|
|
237
|
-
|
|
238
|
-
* **`golf deploy` command for one click deployments to Vercel, Blaxel and other providers**
|
|
239
|
-
* **Production-ready OAuth token management, to allow for persistent, encrypted token storage and client mapping**
|
|
183
|
+
- **`transport`**: Choose `"sse"`, `"streamable-http"`, or `"stdio"`
|
|
184
|
+
- **`opentelemetry_enabled`**: Auto-enabled with `GOLF_API_KEY`
|
|
185
|
+
- **`detailed_tracing`**: Capture input/output (use carefully with sensitive data)
|
|
240
186
|
|
|
241
187
|
|
|
242
188
|
## Privacy & Telemetry
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "golf-mcp"
|
|
7
|
-
version = "0.1
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "Framework for building MCP servers"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "Antoni Gmitruk", email = "antoni@golf.dev"}
|
|
@@ -28,8 +28,9 @@ classifiers = [
|
|
|
28
28
|
dependencies = [
|
|
29
29
|
"typer>=0.15.4",
|
|
30
30
|
"rich>=14.0.0",
|
|
31
|
-
"fastmcp>=2.
|
|
31
|
+
"fastmcp>=2.11.0,<3.0.0",
|
|
32
32
|
"pydantic>=2.11.0",
|
|
33
|
+
"pydantic-settings>=2.0.0",
|
|
33
34
|
"python-dotenv>=1.1.0",
|
|
34
35
|
"black>=24.10.0",
|
|
35
36
|
"pyjwt>=2.0.0",
|
|
@@ -65,7 +66,7 @@ golf = ["examples/**/*"]
|
|
|
65
66
|
|
|
66
67
|
[tool.poetry]
|
|
67
68
|
name = "golf-mcp"
|
|
68
|
-
version = "0.1
|
|
69
|
+
version = "0.2.1"
|
|
69
70
|
description = "Framework for building MCP servers with zero boilerplate"
|
|
70
71
|
authors = ["Antoni Gmitruk <antoni@golf.dev>"]
|
|
71
72
|
license = "Apache-2.0"
|
|
@@ -87,9 +88,10 @@ classifiers = [
|
|
|
87
88
|
|
|
88
89
|
[tool.poetry.dependencies]
|
|
89
90
|
python = ">=3.8" # Match requires-python
|
|
90
|
-
fastmcp = ">=2.
|
|
91
|
+
fastmcp = ">=2.11.0,<3.0.0"
|
|
91
92
|
typer = {extras = ["all"], version = ">=0.15.4"}
|
|
92
93
|
pydantic = ">=2.11.0"
|
|
94
|
+
pydantic-settings = ">=2.0.0"
|
|
93
95
|
rich = ">=14.0.0"
|
|
94
96
|
python-dotenv = ">=1.1.0"
|
|
95
97
|
black = ">=24.10.0"
|
|
@@ -114,15 +116,18 @@ mypy = "^1.6.0"
|
|
|
114
116
|
pytest-cov = "^4.1.0"
|
|
115
117
|
|
|
116
118
|
[tool.black]
|
|
117
|
-
line-length =
|
|
119
|
+
line-length = 120
|
|
118
120
|
|
|
119
121
|
[tool.ruff]
|
|
120
|
-
line-length =
|
|
122
|
+
line-length = 120
|
|
121
123
|
target-version = "py311"
|
|
122
124
|
|
|
123
125
|
[tool.ruff.lint]
|
|
124
126
|
select = ["E", "F", "B", "C4", "C90", "UP", "N", "ANN", "SIM", "TID"]
|
|
125
|
-
ignore = [
|
|
127
|
+
ignore = [
|
|
128
|
+
"ANN401", # Disallow Any (too strict for dynamic code)
|
|
129
|
+
"B008", # Function call in defaults (common in CLI frameworks like Typer)
|
|
130
|
+
]
|
|
126
131
|
|
|
127
132
|
[tool.ruff.format]
|
|
128
133
|
# Use Black-compatible formatting
|
|
@@ -150,6 +155,7 @@ python_files = ["test_*.py", "*_test.py"]
|
|
|
150
155
|
python_classes = ["Test*"]
|
|
151
156
|
python_functions = ["test_*"]
|
|
152
157
|
asyncio_mode = "auto"
|
|
158
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
153
159
|
addopts = [
|
|
154
160
|
"-v",
|
|
155
161
|
"--strict-markers",
|
golf_mcp-0.2.1/setup.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Custom setup.py for golf-mcp with URL injection."""
|
|
2
|
+
|
|
3
|
+
from setuptools import setup
|
|
4
|
+
from setuptools.command.build_py import build_py as _build_py
|
|
5
|
+
from setuptools.command.develop import develop as _develop
|
|
6
|
+
import os
|
|
7
|
+
import pathlib
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
TEMPLATE_REL = "src/golf/_endpoints.py.in"
|
|
11
|
+
PACKAGE_OUT_REL = "golf/_endpoints.py"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def render_endpoints(require_env_vars: bool = True):
|
|
15
|
+
"""Render the endpoints template with environment variables."""
|
|
16
|
+
tpl_path = pathlib.Path(TEMPLATE_REL)
|
|
17
|
+
if not tpl_path.exists():
|
|
18
|
+
raise FileNotFoundError(f"Template not found: {tpl_path}")
|
|
19
|
+
|
|
20
|
+
# Get environment variables
|
|
21
|
+
platform_url = os.environ.get("GOLF_PLATFORM_API_URL")
|
|
22
|
+
otel_url = os.environ.get("GOLF_OTEL_ENDPOINT")
|
|
23
|
+
|
|
24
|
+
# For production builds, require environment variables
|
|
25
|
+
# For development/editable installs, use fallback values
|
|
26
|
+
if require_env_vars and (not platform_url or not otel_url):
|
|
27
|
+
raise SystemExit(
|
|
28
|
+
"Missing required environment variables for URL injection:\n"
|
|
29
|
+
" GOLF_PLATFORM_API_URL\n"
|
|
30
|
+
" GOLF_OTEL_ENDPOINT\n"
|
|
31
|
+
"Set these before building the package."
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# Use environment variables if available, otherwise fallback to development URLs
|
|
35
|
+
values = {
|
|
36
|
+
"PLATFORM_API_URL": platform_url or "http://localhost:8000/api/resources",
|
|
37
|
+
"OTEL_ENDPOINT": otel_url or "http://localhost:4318/v1/traces",
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
rendered = tpl_path.read_text(encoding="utf-8").format(**values)
|
|
42
|
+
except KeyError as e:
|
|
43
|
+
raise SystemExit(f"Missing template key: {e}") from e
|
|
44
|
+
|
|
45
|
+
return rendered
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class build_py(_build_py):
|
|
49
|
+
"""Custom build_py that renders endpoints into the build_lib (wheel contents)."""
|
|
50
|
+
|
|
51
|
+
def run(self):
|
|
52
|
+
# First run the normal build
|
|
53
|
+
super().run()
|
|
54
|
+
|
|
55
|
+
# Then render endpoints into the build_lib
|
|
56
|
+
# Skip env var requirement if in CI environment or if this looks like a test install
|
|
57
|
+
is_ci = os.environ.get("CI") or os.environ.get("GITHUB_ACTIONS")
|
|
58
|
+
rendered = render_endpoints(require_env_vars=not is_ci)
|
|
59
|
+
out_file = pathlib.Path(self.build_lib) / PACKAGE_OUT_REL
|
|
60
|
+
out_file.parent.mkdir(parents=True, exist_ok=True)
|
|
61
|
+
out_file.write_text(rendered, encoding="utf-8")
|
|
62
|
+
print(f"Generated {PACKAGE_OUT_REL} with injected URLs", file=sys.stderr)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class develop(_develop):
|
|
66
|
+
"""Custom develop for editable installs - generates endpoints file in source tree."""
|
|
67
|
+
|
|
68
|
+
def run(self):
|
|
69
|
+
# Run normal develop command first
|
|
70
|
+
super().run()
|
|
71
|
+
|
|
72
|
+
# Generate a working copy file for editable installs (use fallback URLs if env vars missing)
|
|
73
|
+
rendered = render_endpoints(require_env_vars=False)
|
|
74
|
+
# For editable installs, write into the source tree so imports work
|
|
75
|
+
src_file = pathlib.Path("src") / PACKAGE_OUT_REL
|
|
76
|
+
src_file.parent.mkdir(parents=True, exist_ok=True)
|
|
77
|
+
src_file.write_text(rendered, encoding="utf-8")
|
|
78
|
+
print(f"Generated dev-time {PACKAGE_OUT_REL} in source tree", file=sys.stderr)
|
|
79
|
+
print(f"Note: {src_file} is gitignored and should not be committed", file=sys.stderr)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
setup(
|
|
83
|
+
cmdclass={
|
|
84
|
+
"build_py": build_py,
|
|
85
|
+
"develop": develop,
|
|
86
|
+
}
|
|
87
|
+
)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
__version__ = "0.2.1"
|
|
2
|
+
|
|
3
|
+
# Import endpoints with fallback for dev mode
|
|
4
|
+
try:
|
|
5
|
+
# In built wheels, this exists (generated from _endpoints.py.in)
|
|
6
|
+
from . import _endpoints
|
|
7
|
+
except ImportError:
|
|
8
|
+
# In editable/dev installs, fall back to env-based values
|
|
9
|
+
from . import _endpoints_fallback as _endpoints
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Fallback endpoints for development/editable installs."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
# These are used when the generated _endpoints.py doesn't exist (dev mode)
|
|
6
|
+
# or when environment variables override the built-in values
|
|
7
|
+
|
|
8
|
+
PLATFORM_API_URL = os.getenv("GOLF_PLATFORM_API_URL", "http://localhost:8000/api/resources")
|
|
9
|
+
|
|
10
|
+
OTEL_ENDPOINT = os.getenv("GOLF_OTEL_ENDPOINT", "http://localhost:4318/v1/traces")
|