golf-mcp 0.1.16__py3-none-any.whl → 0.1.17__py3-none-any.whl
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/__init__.py +1 -1
- golf/cli/main.py +13 -2
- golf/commands/init.py +63 -1
- golf/core/builder.py +139 -60
- golf/core/config.py +6 -0
- golf/core/parser.py +531 -32
- golf/core/platform.py +180 -0
- golf/core/telemetry.py +28 -8
- golf/examples/api_key/.env.example +1 -5
- golf/examples/api_key/README.md +10 -10
- golf/examples/api_key/golf.json +1 -5
- golf/examples/basic/.env.example +3 -4
- golf/examples/basic/golf.json +1 -5
- golf/telemetry/instrumentation.py +26 -48
- {golf_mcp-0.1.16.dist-info → golf_mcp-0.1.17.dist-info}/METADATA +8 -3
- {golf_mcp-0.1.16.dist-info → golf_mcp-0.1.17.dist-info}/RECORD +20 -19
- {golf_mcp-0.1.16.dist-info → golf_mcp-0.1.17.dist-info}/WHEEL +0 -0
- {golf_mcp-0.1.16.dist-info → golf_mcp-0.1.17.dist-info}/entry_points.txt +0 -0
- {golf_mcp-0.1.16.dist-info → golf_mcp-0.1.17.dist-info}/licenses/LICENSE +0 -0
- {golf_mcp-0.1.16.dist-info → golf_mcp-0.1.17.dist-info}/top_level.txt +0 -0
golf/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.17"
|
golf/cli/main.py
CHANGED
|
@@ -121,7 +121,11 @@ def build_dev(
|
|
|
121
121
|
None, "--output-dir", "-o", help="Directory to output the built project"
|
|
122
122
|
),
|
|
123
123
|
) -> None:
|
|
124
|
-
"""Build a development version with environment variables copied.
|
|
124
|
+
"""Build a development version with app environment variables copied.
|
|
125
|
+
|
|
126
|
+
Golf credentials (GOLF_*) are always loaded from .env for build operations.
|
|
127
|
+
All environment variables are copied to the built project for development.
|
|
128
|
+
"""
|
|
125
129
|
# Find project root directory
|
|
126
130
|
project_root, config_path = find_project_root()
|
|
127
131
|
|
|
@@ -173,7 +177,14 @@ def build_prod(
|
|
|
173
177
|
None, "--output-dir", "-o", help="Directory to output the built project"
|
|
174
178
|
),
|
|
175
179
|
) -> None:
|
|
176
|
-
"""Build a production version
|
|
180
|
+
"""Build a production version for deployment.
|
|
181
|
+
|
|
182
|
+
Golf credentials (GOLF_*) are always loaded from .env for build operations
|
|
183
|
+
(platform registration, resource updates). App environment variables are
|
|
184
|
+
NOT copied for security - provide them in your deployment environment.
|
|
185
|
+
|
|
186
|
+
Your production deployment must include GOLF_* vars for runtime telemetry.
|
|
187
|
+
"""
|
|
177
188
|
# Find project root directory
|
|
178
189
|
project_root, config_path = find_project_root()
|
|
179
190
|
|
golf/commands/init.py
CHANGED
|
@@ -7,7 +7,12 @@ from rich.console import Console
|
|
|
7
7
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
8
8
|
from rich.prompt import Confirm
|
|
9
9
|
|
|
10
|
-
from golf.core.telemetry import
|
|
10
|
+
from golf.core.telemetry import (
|
|
11
|
+
track_command,
|
|
12
|
+
track_event,
|
|
13
|
+
set_telemetry_enabled,
|
|
14
|
+
load_telemetry_preference,
|
|
15
|
+
)
|
|
11
16
|
|
|
12
17
|
console = Console()
|
|
13
18
|
|
|
@@ -95,6 +100,9 @@ def initialize_project(
|
|
|
95
100
|
# Copy directory structure
|
|
96
101
|
_copy_template(template_dir, output_dir, project_name)
|
|
97
102
|
|
|
103
|
+
# Ask for telemetry consent
|
|
104
|
+
_prompt_for_telemetry_consent()
|
|
105
|
+
|
|
98
106
|
# Create virtual environment
|
|
99
107
|
console.print("[bold green]Project initialized successfully![/bold green]")
|
|
100
108
|
console.print("\nTo get started, run:")
|
|
@@ -207,6 +215,60 @@ def _copy_template(source_dir: Path, target_dir: Path, project_name: str) -> Non
|
|
|
207
215
|
f.write("dist/\n")
|
|
208
216
|
|
|
209
217
|
|
|
218
|
+
def _prompt_for_telemetry_consent() -> None:
|
|
219
|
+
"""Prompt user for telemetry consent and save their preference."""
|
|
220
|
+
import os
|
|
221
|
+
|
|
222
|
+
# Skip prompt in test mode, when telemetry is explicitly disabled, or if preference already exists
|
|
223
|
+
if os.environ.get("GOLF_TEST_MODE", "").lower() in ("1", "true", "yes", "on"):
|
|
224
|
+
return
|
|
225
|
+
|
|
226
|
+
# Skip if telemetry is explicitly disabled in environment
|
|
227
|
+
if os.environ.get("GOLF_TELEMETRY", "").lower() in ("0", "false", "no", "off"):
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
# Check if user already has a saved preference
|
|
231
|
+
existing_preference = load_telemetry_preference()
|
|
232
|
+
if existing_preference is not None:
|
|
233
|
+
return # User already made a choice
|
|
234
|
+
|
|
235
|
+
console.print()
|
|
236
|
+
console.rule("[bold blue]Anonymous usage analytics[/bold blue]", style="blue")
|
|
237
|
+
console.print()
|
|
238
|
+
console.print(
|
|
239
|
+
"Golf can collect [bold]anonymous usage analytics[/bold] to help improve the tool."
|
|
240
|
+
)
|
|
241
|
+
console.print()
|
|
242
|
+
console.print("[dim]What we collect:[/dim]")
|
|
243
|
+
console.print(" • Command usage (init, build, run)")
|
|
244
|
+
console.print(" • Error types (to fix bugs)")
|
|
245
|
+
console.print(" • Golf version and Python version")
|
|
246
|
+
console.print(" • Operating system type")
|
|
247
|
+
console.print()
|
|
248
|
+
console.print("[dim]What we DON'T collect:[/dim]")
|
|
249
|
+
console.print(" • Your code or project content")
|
|
250
|
+
console.print(" • File paths or project names")
|
|
251
|
+
console.print(" • Personal information")
|
|
252
|
+
console.print(" • IP addresses")
|
|
253
|
+
console.print()
|
|
254
|
+
console.print(
|
|
255
|
+
"You can change this anytime by setting GOLF_TELEMETRY=0 in your environment."
|
|
256
|
+
)
|
|
257
|
+
console.print()
|
|
258
|
+
|
|
259
|
+
enable_telemetry = Confirm.ask(
|
|
260
|
+
"[bold]Enable anonymous usage analytics?[/bold]", default=False
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
set_telemetry_enabled(enable_telemetry, persist=True)
|
|
264
|
+
|
|
265
|
+
if enable_telemetry:
|
|
266
|
+
console.print("[green]✓[/green] Anonymous analytics enabled")
|
|
267
|
+
else:
|
|
268
|
+
console.print("[yellow]○[/yellow] Anonymous analytics disabled")
|
|
269
|
+
console.print()
|
|
270
|
+
|
|
271
|
+
|
|
210
272
|
def _is_text_file(path: Path) -> bool:
|
|
211
273
|
"""Check if a file is a text file that needs variable substitution.
|
|
212
274
|
|
golf/core/builder.py
CHANGED
|
@@ -561,14 +561,6 @@ class CodeGenerator:
|
|
|
561
561
|
# Add OpenTelemetry imports if enabled
|
|
562
562
|
if self.settings.opentelemetry_enabled:
|
|
563
563
|
imports.extend(generate_telemetry_imports())
|
|
564
|
-
imports.append("")
|
|
565
|
-
|
|
566
|
-
# Add imports section for different transport methods
|
|
567
|
-
if self.settings.transport == "sse" or self.settings.transport in [
|
|
568
|
-
"streamable-http",
|
|
569
|
-
"http",
|
|
570
|
-
]:
|
|
571
|
-
imports.append("import uvicorn")
|
|
572
564
|
|
|
573
565
|
# Add health check imports if enabled
|
|
574
566
|
if self.settings.health_check_enabled:
|
|
@@ -664,7 +656,10 @@ class CodeGenerator:
|
|
|
664
656
|
# Add code to register this component
|
|
665
657
|
if self.settings.opentelemetry_enabled:
|
|
666
658
|
# Use telemetry instrumentation
|
|
667
|
-
registration =
|
|
659
|
+
registration = (
|
|
660
|
+
f"# Register the {component_type.value} "
|
|
661
|
+
f"'{component.name}' with telemetry"
|
|
662
|
+
)
|
|
668
663
|
entry_func = (
|
|
669
664
|
component.entry_function
|
|
670
665
|
if hasattr(component, "entry_function")
|
|
@@ -672,19 +667,31 @@ class CodeGenerator:
|
|
|
672
667
|
else "export"
|
|
673
668
|
)
|
|
674
669
|
|
|
675
|
-
|
|
676
|
-
|
|
670
|
+
registration += (
|
|
671
|
+
f"\n_wrapped_func = instrument_{component_type.value}("
|
|
672
|
+
f"{full_module_path}.{entry_func}, '{component.name}')"
|
|
673
|
+
)
|
|
677
674
|
|
|
678
675
|
if component_type == ComponentType.TOOL:
|
|
679
|
-
registration +=
|
|
676
|
+
registration += (
|
|
677
|
+
f'\nmcp.add_tool(_wrapped_func, name="{component.name}", '
|
|
678
|
+
f'description="{component.docstring or ""}"'
|
|
679
|
+
)
|
|
680
680
|
# Add annotations if present
|
|
681
681
|
if hasattr(component, "annotations") and component.annotations:
|
|
682
682
|
registration += f", annotations={component.annotations}"
|
|
683
683
|
registration += ")"
|
|
684
684
|
elif component_type == ComponentType.RESOURCE:
|
|
685
|
-
registration +=
|
|
685
|
+
registration += (
|
|
686
|
+
f"\nmcp.add_resource_fn(_wrapped_func, "
|
|
687
|
+
f'uri="{component.uri_template}", name="{component.name}", '
|
|
688
|
+
f'description="{component.docstring or ""}")'
|
|
689
|
+
)
|
|
686
690
|
else: # PROMPT
|
|
687
|
-
registration +=
|
|
691
|
+
registration += (
|
|
692
|
+
f'\nmcp.add_prompt(_wrapped_func, name="{component.name}", '
|
|
693
|
+
f'description="{component.docstring or ""}")'
|
|
694
|
+
)
|
|
688
695
|
else:
|
|
689
696
|
# Standard registration without telemetry
|
|
690
697
|
if component_type == ComponentType.TOOL:
|
|
@@ -795,6 +802,10 @@ class CodeGenerator:
|
|
|
795
802
|
for key, value in auth_components["fastmcp_args"].items():
|
|
796
803
|
mcp_constructor_args.append(f"{key}={value}")
|
|
797
804
|
|
|
805
|
+
# Add stateless HTTP parameter if enabled
|
|
806
|
+
if self.settings.stateless_http:
|
|
807
|
+
mcp_constructor_args.append("stateless_http=True")
|
|
808
|
+
|
|
798
809
|
# Add OpenTelemetry parameters if enabled
|
|
799
810
|
if self.settings.opentelemetry_enabled:
|
|
800
811
|
mcp_constructor_args.append("lifespan=telemetry_lifespan")
|
|
@@ -803,6 +814,18 @@ class CodeGenerator:
|
|
|
803
814
|
server_code_lines.append(mcp_instance_line)
|
|
804
815
|
server_code_lines.append("")
|
|
805
816
|
|
|
817
|
+
# Add early telemetry initialization if enabled (before component registration)
|
|
818
|
+
early_telemetry_init = []
|
|
819
|
+
if self.settings.opentelemetry_enabled:
|
|
820
|
+
early_telemetry_init.extend(
|
|
821
|
+
[
|
|
822
|
+
"# Initialize telemetry early to ensure instrumentation works",
|
|
823
|
+
"from golf.telemetry.instrumentation import init_telemetry",
|
|
824
|
+
f'init_telemetry("{self.settings.name}")',
|
|
825
|
+
"",
|
|
826
|
+
]
|
|
827
|
+
)
|
|
828
|
+
|
|
806
829
|
# Main entry point with transport-specific app initialization
|
|
807
830
|
main_code = [
|
|
808
831
|
'if __name__ == "__main__":',
|
|
@@ -830,71 +853,84 @@ class CodeGenerator:
|
|
|
830
853
|
|
|
831
854
|
# Transport-specific run methods
|
|
832
855
|
if self.settings.transport == "sse":
|
|
833
|
-
# Check if we need
|
|
856
|
+
# Check if we need middleware for SSE
|
|
857
|
+
middleware_setup = []
|
|
858
|
+
middleware_list = []
|
|
859
|
+
|
|
834
860
|
api_key_config = get_api_key_config()
|
|
835
861
|
if auth_components.get("has_auth") and api_key_config:
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
" # For SSE with API key auth, we need to get the app and add middleware",
|
|
839
|
-
' app = mcp.http_app(transport="sse")',
|
|
840
|
-
" app.add_middleware(ApiKeyMiddleware)",
|
|
841
|
-
]
|
|
862
|
+
middleware_setup.append(
|
|
863
|
+
" from starlette.middleware import Middleware"
|
|
842
864
|
)
|
|
843
|
-
|
|
865
|
+
middleware_list.append("Middleware(ApiKeyMiddleware)")
|
|
866
|
+
|
|
867
|
+
# Add OpenTelemetry middleware if enabled
|
|
868
|
+
if self.settings.opentelemetry_enabled:
|
|
869
|
+
middleware_setup.append(
|
|
870
|
+
" from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware"
|
|
871
|
+
)
|
|
872
|
+
middleware_setup.append(
|
|
873
|
+
" from starlette.middleware import Middleware"
|
|
874
|
+
)
|
|
875
|
+
middleware_list.append("Middleware(OpenTelemetryMiddleware)")
|
|
876
|
+
|
|
877
|
+
if middleware_setup:
|
|
878
|
+
main_code.extend(middleware_setup)
|
|
879
|
+
main_code.append(f" middleware = [{', '.join(middleware_list)}]")
|
|
880
|
+
main_code.append("")
|
|
844
881
|
main_code.extend(
|
|
845
882
|
[
|
|
846
|
-
" #
|
|
847
|
-
'
|
|
883
|
+
" # Run SSE server with middleware using FastMCP's run method",
|
|
884
|
+
' mcp.run(transport="sse", host=host, port=port, log_level="info", middleware=middleware)',
|
|
848
885
|
]
|
|
849
886
|
)
|
|
850
|
-
|
|
851
|
-
# Add OpenTelemetry middleware to the SSE app if enabled
|
|
852
|
-
if self.settings.opentelemetry_enabled:
|
|
887
|
+
else:
|
|
853
888
|
main_code.extend(
|
|
854
889
|
[
|
|
855
|
-
" #
|
|
856
|
-
|
|
857
|
-
" app = OpenTelemetryMiddleware(app)",
|
|
890
|
+
" # Run SSE server using FastMCP's run method",
|
|
891
|
+
' mcp.run(transport="sse", host=host, port=port, log_level="info")',
|
|
858
892
|
]
|
|
859
893
|
)
|
|
860
894
|
|
|
861
|
-
main_code.extend(
|
|
862
|
-
[
|
|
863
|
-
" # Run with the configured app",
|
|
864
|
-
' uvicorn.run(app, host=host, port=port, log_level="info")',
|
|
865
|
-
]
|
|
866
|
-
)
|
|
867
895
|
elif self.settings.transport in ["streamable-http", "http"]:
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
" app = mcp.http_app()",
|
|
872
|
-
]
|
|
873
|
-
)
|
|
896
|
+
# Check if we need middleware for streamable-http
|
|
897
|
+
middleware_setup = []
|
|
898
|
+
middleware_list = []
|
|
874
899
|
|
|
875
|
-
# Check if we need to add API key middleware
|
|
876
900
|
api_key_config = get_api_key_config()
|
|
877
901
|
if auth_components.get("has_auth") and api_key_config:
|
|
902
|
+
middleware_setup.append(
|
|
903
|
+
" from starlette.middleware import Middleware"
|
|
904
|
+
)
|
|
905
|
+
middleware_list.append("Middleware(ApiKeyMiddleware)")
|
|
906
|
+
|
|
907
|
+
# Add OpenTelemetry middleware if enabled
|
|
908
|
+
if self.settings.opentelemetry_enabled:
|
|
909
|
+
middleware_setup.append(
|
|
910
|
+
" from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware"
|
|
911
|
+
)
|
|
912
|
+
middleware_setup.append(
|
|
913
|
+
" from starlette.middleware import Middleware"
|
|
914
|
+
)
|
|
915
|
+
middleware_list.append("Middleware(OpenTelemetryMiddleware)")
|
|
916
|
+
|
|
917
|
+
if middleware_setup:
|
|
918
|
+
main_code.extend(middleware_setup)
|
|
919
|
+
main_code.append(f" middleware = [{', '.join(middleware_list)}]")
|
|
920
|
+
main_code.append("")
|
|
878
921
|
main_code.extend(
|
|
879
922
|
[
|
|
880
|
-
" #
|
|
881
|
-
|
|
923
|
+
" # Run HTTP server with middleware using FastMCP's run method",
|
|
924
|
+
' mcp.run(transport="streamable-http", host=host, port=port, log_level="info", middleware=middleware)',
|
|
882
925
|
]
|
|
883
926
|
)
|
|
884
|
-
|
|
885
|
-
# Add OpenTelemetry middleware to the HTTP app if enabled
|
|
886
|
-
if self.settings.opentelemetry_enabled:
|
|
927
|
+
else:
|
|
887
928
|
main_code.extend(
|
|
888
929
|
[
|
|
889
|
-
" #
|
|
890
|
-
|
|
891
|
-
" app = OpenTelemetryMiddleware(app)",
|
|
930
|
+
" # Run HTTP server using FastMCP's run method",
|
|
931
|
+
' mcp.run(transport="streamable-http", host=host, port=port, log_level="info")',
|
|
892
932
|
]
|
|
893
933
|
)
|
|
894
|
-
|
|
895
|
-
main_code.extend(
|
|
896
|
-
[' uvicorn.run(app, host=host, port=port, log_level="info")']
|
|
897
|
-
)
|
|
898
934
|
else:
|
|
899
935
|
# For stdio transport, use mcp.run()
|
|
900
936
|
main_code.extend(
|
|
@@ -917,12 +953,13 @@ class CodeGenerator:
|
|
|
917
953
|
|
|
918
954
|
# Combine all sections
|
|
919
955
|
# Order: imports, env_section, auth_setup, server_code (mcp init),
|
|
920
|
-
#
|
|
956
|
+
# early_telemetry_init, component_registrations, health_check_code, main_code (run block)
|
|
921
957
|
code = "\n".join(
|
|
922
958
|
imports
|
|
923
959
|
+ env_section
|
|
924
960
|
+ auth_setup_code
|
|
925
961
|
+ server_code_lines
|
|
962
|
+
+ early_telemetry_init
|
|
926
963
|
+ component_registrations
|
|
927
964
|
+ health_check_code
|
|
928
965
|
+ main_code
|
|
@@ -955,6 +992,21 @@ def build_project(
|
|
|
955
992
|
build_env: Build environment ('dev' or 'prod')
|
|
956
993
|
copy_env: Whether to copy environment variables to the built app
|
|
957
994
|
"""
|
|
995
|
+
# Load Golf credentials from .env for build operations (platform registration, etc.)
|
|
996
|
+
# This happens regardless of copy_env setting to ensure build process works
|
|
997
|
+
from dotenv import load_dotenv
|
|
998
|
+
|
|
999
|
+
project_env_file = project_path / ".env"
|
|
1000
|
+
if project_env_file.exists():
|
|
1001
|
+
# Load GOLF_* variables for build process
|
|
1002
|
+
load_dotenv(project_env_file, override=False)
|
|
1003
|
+
|
|
1004
|
+
# Only log if we actually found the specific Golf platform credentials
|
|
1005
|
+
has_api_key = "GOLF_API_KEY" in os.environ
|
|
1006
|
+
has_server_id = "GOLF_SERVER_ID" in os.environ
|
|
1007
|
+
if has_api_key and has_server_id:
|
|
1008
|
+
console.print("[dim]Loaded Golf credentials for build operations[/dim]")
|
|
1009
|
+
|
|
958
1010
|
# Execute pre_build.py if it exists
|
|
959
1011
|
pre_build_path = project_path / "pre_build.py"
|
|
960
1012
|
if pre_build_path.exists():
|
|
@@ -1056,9 +1108,6 @@ def build_project(
|
|
|
1056
1108
|
env_vars_to_write["OTEL_TRACES_EXPORTER"] = (
|
|
1057
1109
|
settings.opentelemetry_default_exporter
|
|
1058
1110
|
)
|
|
1059
|
-
console.print(
|
|
1060
|
-
f"[info]Setting OTEL_TRACES_EXPORTER to '{settings.opentelemetry_default_exporter}' from golf.json in built app's .env[/info]"
|
|
1061
|
-
)
|
|
1062
1111
|
|
|
1063
1112
|
# 3. Apply Golf's project name as OTEL_SERVICE_NAME if not already set
|
|
1064
1113
|
# (Ensures service name defaults to project name if not specified in user's .env)
|
|
@@ -1110,6 +1159,36 @@ def build_project(
|
|
|
1110
1159
|
)
|
|
1111
1160
|
generator.generate()
|
|
1112
1161
|
|
|
1162
|
+
# Platform registration (only for prod builds)
|
|
1163
|
+
if build_env == "prod":
|
|
1164
|
+
console.print(
|
|
1165
|
+
"[dim]Registering with Golf platform and updating resources...[/dim]"
|
|
1166
|
+
)
|
|
1167
|
+
import asyncio
|
|
1168
|
+
|
|
1169
|
+
try:
|
|
1170
|
+
from golf.core.platform import register_project_with_platform
|
|
1171
|
+
|
|
1172
|
+
asyncio.run(
|
|
1173
|
+
register_project_with_platform(
|
|
1174
|
+
project_path=project_path,
|
|
1175
|
+
settings=settings,
|
|
1176
|
+
components=generator.components,
|
|
1177
|
+
)
|
|
1178
|
+
)
|
|
1179
|
+
console.print("[green]✓ Platform registration completed[/green]")
|
|
1180
|
+
except ImportError:
|
|
1181
|
+
console.print(
|
|
1182
|
+
"[yellow]Warning: Platform registration module not available[/yellow]"
|
|
1183
|
+
)
|
|
1184
|
+
except Exception as e:
|
|
1185
|
+
console.print(
|
|
1186
|
+
f"[yellow]Warning: Platform registration failed: {e}[/yellow]"
|
|
1187
|
+
)
|
|
1188
|
+
console.print(
|
|
1189
|
+
"[yellow]Tip: Ensure GOLF_API_KEY and GOLF_SERVER_ID are available in your .env file[/yellow]"
|
|
1190
|
+
)
|
|
1191
|
+
|
|
1113
1192
|
# Create a simple README
|
|
1114
1193
|
readme_content = f"""# {settings.name}
|
|
1115
1194
|
|
|
@@ -1130,7 +1209,7 @@ This is a standalone FastMCP server generated by GolfMCP.
|
|
|
1130
1209
|
|
|
1131
1210
|
# Copy pyproject.toml with required dependencies
|
|
1132
1211
|
base_dependencies = [
|
|
1133
|
-
"fastmcp>=2.0.0",
|
|
1212
|
+
"fastmcp>=2.0.0,<2.6.0",
|
|
1134
1213
|
"uvicorn>=0.20.0",
|
|
1135
1214
|
"pydantic>=2.0.0",
|
|
1136
1215
|
"python-dotenv>=1.0.0",
|
golf/core/config.py
CHANGED
|
@@ -109,6 +109,12 @@ class Settings(BaseSettings):
|
|
|
109
109
|
health_check_path: str = Field("/health", description="Health check endpoint path")
|
|
110
110
|
health_check_response: str = Field("OK", description="Health check response text")
|
|
111
111
|
|
|
112
|
+
# HTTP session behaviour
|
|
113
|
+
stateless_http: bool = Field(
|
|
114
|
+
False,
|
|
115
|
+
description="Make Streamable-HTTP transport stateless (new session per request)",
|
|
116
|
+
)
|
|
117
|
+
|
|
112
118
|
|
|
113
119
|
def find_config_path(start_path: Path | None = None) -> Path | None:
|
|
114
120
|
"""Find the golf config file by searching upwards from the given path.
|