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.

Files changed (141) hide show
  1. golf_mcp-0.2.1/.docs/fastmcp-diff.md +27 -0
  2. {golf_mcp-0.1.20/src/golf_mcp.egg-info → golf_mcp-0.2.1}/PKG-INFO +51 -104
  3. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/README.md +48 -102
  4. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/pyproject.toml +13 -7
  5. golf_mcp-0.2.1/setup.py +87 -0
  6. golf_mcp-0.2.1/src/golf/__init__.py +9 -0
  7. golf_mcp-0.2.1/src/golf/_endpoints_fallback.py +10 -0
  8. golf_mcp-0.2.1/src/golf/auth/__init__.py +274 -0
  9. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/auth/api_key.py +6 -14
  10. golf_mcp-0.2.1/src/golf/auth/factory.py +358 -0
  11. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/auth/helpers.py +12 -42
  12. golf_mcp-0.2.1/src/golf/auth/providers.py +446 -0
  13. golf_mcp-0.2.1/src/golf/auth/registry.py +256 -0
  14. golf_mcp-0.2.1/src/golf/cli/branding.py +192 -0
  15. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/cli/main.py +28 -69
  16. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/commands/__init__.py +2 -0
  17. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/commands/build.py +4 -7
  18. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/commands/init.py +30 -53
  19. golf_mcp-0.2.1/src/golf/commands/run.py +125 -0
  20. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/builder.py +355 -414
  21. golf_mcp-0.2.1/src/golf/core/builder_auth.py +209 -0
  22. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/builder_telemetry.py +26 -3
  23. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/config.py +38 -59
  24. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/parser.py +132 -139
  25. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/platform.py +12 -10
  26. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/telemetry.py +11 -19
  27. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/transformer.py +38 -15
  28. golf_mcp-0.2.1/src/golf/examples/basic/.coverage +0 -0
  29. golf_mcp-0.2.1/src/golf/examples/basic/.env.example +8 -0
  30. golf_mcp-0.2.1/src/golf/examples/basic/README.md +133 -0
  31. golf_mcp-0.2.1/src/golf/examples/basic/auth.py +76 -0
  32. golf_mcp-0.2.1/src/golf/examples/basic/golf.json +5 -0
  33. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/.gitignore +2 -0
  34. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/class_index.html +547 -0
  35. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/coverage_html_cb_6fb7b396.js +733 -0
  36. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/favicon_32_cb_58284776.png +0 -0
  37. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/function_index.html +2091 -0
  38. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/index.html +349 -0
  39. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/keybd_closed_cb_ce680311.png +0 -0
  40. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/status.json +1 -0
  41. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/style_cb_8e611ae1.css +337 -0
  42. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496___init___py.html +323 -0
  43. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_api_key_py.html +170 -0
  44. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_factory_py.html +430 -0
  45. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_helpers_py.html +288 -0
  46. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_providers_py.html +493 -0
  47. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_registry_py.html +353 -0
  48. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_3ec3b3f490dc0950___init___py.html +120 -0
  49. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_3ec3b3f490dc0950_instrumentation_py.html +1535 -0
  50. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db___init___py.html +98 -0
  51. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db_branding_py.html +289 -0
  52. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db_main_py.html +476 -0
  53. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_5a6c4e6bcc86fb2f___init___py.html +97 -0
  54. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6cadab9ec0df475d___init___py.html +102 -0
  55. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6cadab9ec0df475d_build_py.html +178 -0
  56. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6cadab9ec0df475d_init_py.html +387 -0
  57. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6cadab9ec0df475d_run_py.html +222 -0
  58. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6fcdee0582ba84e4___init___py.html +106 -0
  59. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_6fcdee0582ba84e4__endpoints_fallback_py.html +107 -0
  60. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217___init___py.html +98 -0
  61. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_auth_py.html +306 -0
  62. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_metrics_py.html +329 -0
  63. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_py.html +1471 -0
  64. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_telemetry_py.html +186 -0
  65. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_config_py.html +315 -0
  66. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_parser_py.html +1149 -0
  67. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_platform_py.html +279 -0
  68. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_telemetry_py.html +589 -0
  69. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7ba499ed22986217_transformer_py.html +286 -0
  70. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7d7da37693a43688___init___py.html +107 -0
  71. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7d7da37693a43688_collector_py.html +417 -0
  72. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_7d7da37693a43688_registry_py.html +109 -0
  73. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_abe733142b40ad4e___init___py.html +109 -0
  74. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_abe733142b40ad4e_context_py.html +150 -0
  75. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_abe733142b40ad4e_elicitation_py.html +267 -0
  76. golf_mcp-0.2.1/src/golf/examples/basic/htmlcov/z_abe733142b40ad4e_sampling_py.html +318 -0
  77. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/prompts/welcome.py +3 -5
  78. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/resources/current_time.py +5 -13
  79. golf_mcp-0.2.1/src/golf/examples/basic/resources/weather/city.py +46 -0
  80. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/resources/weather/common.py +4 -11
  81. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/resources/weather/current.py +5 -5
  82. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/resources/weather/forecast.py +5 -5
  83. golf_mcp-0.2.1/src/golf/examples/basic/tools/calculator.py +94 -0
  84. golf_mcp-0.2.1/src/golf/examples/basic/tools/say/hello.py +65 -0
  85. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/metrics/collector.py +100 -19
  86. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/telemetry/__init__.py +4 -0
  87. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/telemetry/instrumentation.py +484 -178
  88. golf_mcp-0.2.1/src/golf/utilities/__init__.py +12 -0
  89. golf_mcp-0.2.1/src/golf/utilities/context.py +53 -0
  90. golf_mcp-0.2.1/src/golf/utilities/elicitation.py +170 -0
  91. golf_mcp-0.2.1/src/golf/utilities/sampling.py +221 -0
  92. {golf_mcp-0.1.20 → golf_mcp-0.2.1/src/golf_mcp.egg-info}/PKG-INFO +51 -104
  93. golf_mcp-0.2.1/src/golf_mcp.egg-info/SOURCES.txt +107 -0
  94. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf_mcp.egg-info/requires.txt +2 -1
  95. golf_mcp-0.1.20/.docs/fast-mcp.md +0 -4886
  96. golf_mcp-0.1.20/.docs/fastmcp-example-1.py +0 -30
  97. golf_mcp-0.1.20/.docs/fastmcp-example-2.py +0 -114
  98. golf_mcp-0.1.20/.docs/oauth-implementation.md +0 -316
  99. golf_mcp-0.1.20/.docs/oauth.md +0 -305
  100. golf_mcp-0.1.20/src/golf/__init__.py +0 -1
  101. golf_mcp-0.1.20/src/golf/auth/__init__.py +0 -122
  102. golf_mcp-0.1.20/src/golf/auth/oauth.py +0 -861
  103. golf_mcp-0.1.20/src/golf/auth/provider.py +0 -115
  104. golf_mcp-0.1.20/src/golf/commands/run.py +0 -95
  105. golf_mcp-0.1.20/src/golf/core/builder_auth.py +0 -290
  106. golf_mcp-0.1.20/src/golf/examples/api_key/.env +0 -2
  107. golf_mcp-0.1.20/src/golf/examples/api_key/.env.example +0 -1
  108. golf_mcp-0.1.20/src/golf/examples/api_key/README.md +0 -84
  109. golf_mcp-0.1.20/src/golf/examples/api_key/golf.json +0 -8
  110. golf_mcp-0.1.20/src/golf/examples/api_key/pre_build.py +0 -11
  111. golf_mcp-0.1.20/src/golf/examples/api_key/tools/issues/create.py +0 -93
  112. golf_mcp-0.1.20/src/golf/examples/api_key/tools/issues/list.py +0 -92
  113. golf_mcp-0.1.20/src/golf/examples/api_key/tools/repos/list.py +0 -111
  114. golf_mcp-0.1.20/src/golf/examples/api_key/tools/search/code.py +0 -106
  115. golf_mcp-0.1.20/src/golf/examples/api_key/tools/users/get.py +0 -82
  116. golf_mcp-0.1.20/src/golf/examples/basic/.env +0 -5
  117. golf_mcp-0.1.20/src/golf/examples/basic/.env.example +0 -4
  118. golf_mcp-0.1.20/src/golf/examples/basic/README.md +0 -61
  119. golf_mcp-0.1.20/src/golf/examples/basic/golf.json +0 -8
  120. golf_mcp-0.1.20/src/golf/examples/basic/pre_build.py +0 -28
  121. golf_mcp-0.1.20/src/golf/examples/basic/tools/github_user.py +0 -65
  122. golf_mcp-0.1.20/src/golf/examples/basic/tools/hello.py +0 -34
  123. golf_mcp-0.1.20/src/golf/examples/basic/tools/payments/charge.py +0 -70
  124. golf_mcp-0.1.20/src/golf/examples/basic/tools/payments/common.py +0 -36
  125. golf_mcp-0.1.20/src/golf/examples/basic/tools/payments/refund.py +0 -61
  126. golf_mcp-0.1.20/src/golf_mcp.egg-info/SOURCES.txt +0 -71
  127. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/.docs/docs.md +0 -0
  128. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/.docs/mcp.md +0 -0
  129. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/LICENSE +0 -0
  130. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/MANIFEST.in +0 -0
  131. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/setup.cfg +0 -0
  132. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/cli/__init__.py +0 -0
  133. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/__init__.py +0 -0
  134. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/core/builder_metrics.py +0 -0
  135. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/__init__.py +0 -0
  136. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/examples/basic/resources/info.py +0 -0
  137. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/metrics/__init__.py +0 -0
  138. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf/metrics/registry.py +0 -0
  139. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf_mcp.egg-info/dependency_links.txt +0 -0
  140. {golf_mcp-0.1.20 → golf_mcp-0.2.1}/src/golf_mcp.egg-info/entry_points.txt +0 -0
  141. {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.20
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<2.6.0,>=2.0.0
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 FastMCP server, minimizing boilerplate and accelerating development.
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 can focus on implementing your agent's logic rather than wrestling with server setup and integration complexities. It's built for developers who want a quick, organized way to build powerful MCP servers.
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 FastMCP server, typically on `http://127.0.0.1:3000` (configurable in `golf.json`).
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
- └─ pre_build.py # (Optional) Script for pre-build hooks (e.g., auth setup)
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
- ## Configuration (`golf.json`)
169
+ ## Authentication & Features
168
170
 
169
- The `golf.json` file is the heart of your Golf project configuration. Here's what each field controls:
171
+ Golf includes enterprise-grade authentication, built-in utilities, and automatic telemetry:
170
172
 
171
- ```jsonc
172
- {
173
- "name": "{{project_name}}", // Your MCP server name (required)
174
- "description": "A Golf project", // Brief description of your server's purpose
175
- "host": "127.0.0.1", // Server host - use "0.0.0.0" to listen on all interfaces
176
- "port": 3000, // Server port - any available port number
177
- "transport": "sse", // Communication protocol:
178
- // - "sse": Server-Sent Events (recommended for web clients)
179
- // - "streamable-http": HTTP with streaming support
180
- // - "stdio": Standard I/O (for CLI integration)
181
-
182
- // HTTP Transport Configuration (optional)
183
- "stateless_http": false, // Make streamable-http transport stateless (new session per request)
184
- // When true, server restarts won't break existing client connections
185
-
186
- // Health Check Configuration (optional)
187
- "health_check_enabled": false, // Enable health check endpoint for Kubernetes/load balancers
188
- "health_check_path": "/health", // HTTP path for health check endpoint
189
- "health_check_response": "OK", // Response text returned by health check
190
-
191
- // OpenTelemetry Configuration (optional)
192
- "opentelemetry_enabled": false, // Enable distributed tracing
193
- "opentelemetry_default_exporter": "console" // Default exporter if OTEL_TRACES_EXPORTER not set
194
- // Options: "console", "otlp_http"
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
- The generated server will include a route like:
235
- ```python
236
- @mcp.custom_route('/health', methods=["GET"])
237
- async def health_check(request: Request) -> PlainTextResponse:
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
- ### 🔍 OpenTelemetry Support
206
+ **[📚 Complete Documentation →](https://docs.golf.dev)**
243
207
 
244
- Golf includes built-in OpenTelemetry instrumentation for distributed tracing. When enabled, it automatically traces:
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
- #### Configuration
210
+ Basic configuration in `golf.json`:
251
211
 
252
- Enable OpenTelemetry in your `golf.json`:
253
212
  ```json
254
213
  {
255
- "opentelemetry_enabled": true,
256
- "opentelemetry_default_exporter": "otlp_http"
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
- Then configure via environment variables:
261
- ```bash
262
- # For OTLP HTTP exporter (e.g., Jaeger, Grafana Tempo)
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 FastMCP server, minimizing boilerplate and accelerating development.
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 can focus on implementing your agent's logic rather than wrestling with server setup and integration complexities. It's built for developers who want a quick, organized way to build powerful MCP servers.
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 FastMCP server, typically on `http://127.0.0.1:3000` (configurable in `golf.json`).
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
- └─ pre_build.py # (Optional) Script for pre-build hooks (e.g., auth setup)
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
- ## Configuration (`golf.json`)
129
+ ## Authentication & Features
129
130
 
130
- The `golf.json` file is the heart of your Golf project configuration. Here's what each field controls:
131
+ Golf includes enterprise-grade authentication, built-in utilities, and automatic telemetry:
131
132
 
132
- ```jsonc
133
- {
134
- "name": "{{project_name}}", // Your MCP server name (required)
135
- "description": "A Golf project", // Brief description of your server's purpose
136
- "host": "127.0.0.1", // Server host - use "0.0.0.0" to listen on all interfaces
137
- "port": 3000, // Server port - any available port number
138
- "transport": "sse", // Communication protocol:
139
- // - "sse": Server-Sent Events (recommended for web clients)
140
- // - "streamable-http": HTTP with streaming support
141
- // - "stdio": Standard I/O (for CLI integration)
142
-
143
- // HTTP Transport Configuration (optional)
144
- "stateless_http": false, // Make streamable-http transport stateless (new session per request)
145
- // When true, server restarts won't break existing client connections
146
-
147
- // Health Check Configuration (optional)
148
- "health_check_enabled": false, // Enable health check endpoint for Kubernetes/load balancers
149
- "health_check_path": "/health", // HTTP path for health check endpoint
150
- "health_check_response": "OK", // Response text returned by health check
151
-
152
- // OpenTelemetry Configuration (optional)
153
- "opentelemetry_enabled": false, // Enable distributed tracing
154
- "opentelemetry_default_exporter": "console" // Default exporter if OTEL_TRACES_EXPORTER not set
155
- // Options: "console", "otlp_http"
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
- The generated server will include a route like:
196
- ```python
197
- @mcp.custom_route('/health', methods=["GET"])
198
- async def health_check(request: Request) -> PlainTextResponse:
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
- ### 🔍 OpenTelemetry Support
166
+ **[📚 Complete Documentation →](https://docs.golf.dev)**
204
167
 
205
- Golf includes built-in OpenTelemetry instrumentation for distributed tracing. When enabled, it automatically traces:
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
- #### Configuration
170
+ Basic configuration in `golf.json`:
212
171
 
213
- Enable OpenTelemetry in your `golf.json`:
214
172
  ```json
215
173
  {
216
- "opentelemetry_enabled": true,
217
- "opentelemetry_default_exporter": "otlp_http"
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
- Then configure via environment variables:
222
- ```bash
223
- # For OTLP HTTP exporter (e.g., Jaeger, Grafana Tempo)
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.20"
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.0.0,<2.6.0",
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.20"
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.0.0,<2.6.0"
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 = 88
119
+ line-length = 120
118
120
 
119
121
  [tool.ruff]
120
- line-length = 88
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 = ["ANN401"]
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",
@@ -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")