Documentation Index
Fetch the complete documentation index at: https://docs.golf.dev/llms.txt
Use this file to discover all available pages before exploring further.
Golf v0.2.0 introduces powerful built-in utilities that enhance your tool development experience.
Overview
Golf utilities provide four core capabilities:
- Context Access - Direct access to FastMCP context without manual parameter passing
- Elicitation - Interactive user prompting and input collection
- Sampling - LLM interactions and text generation with multiple modes
- Authentication Integration - Seamless token extraction
All utilities automatically handle context management using Python’s contextvars for thread-safe, async-aware access to FastMCP features.
Context access
Get current context
The get_current_context() function provides direct access to the FastMCP context without requiring explicit context parameter passing.
from golf.utilities import get_current_context
async def context_aware_tool():
# Get the current FastMCP context
context = get_current_context()
# Access request information
request_id = getattr(context, 'request_id', None)
return {
"request_id": request_id,
"context_available": True
}
Context with logging
from golf.utilities import get_current_context
async def logging_tool(message: str):
context = get_current_context()
# Use context for structured logging
context.logger.info(f"Processing message: {message}")
return {"status": "logged", "message": message}
Error handling
from golf.utilities import get_current_context
async def safe_context_tool():
try:
context = get_current_context()
return {"context_available": True}
except RuntimeError as e:
# Context not available (e.g., called outside MCP tool)
return {
"context_available": False,
"error": str(e)
}
except ImportError as e:
# FastMCP not available or incompatible version
return {
"context_available": False,
"error": "FastMCP >=2.11.0 required"
}
Elicitation utilities
Elicitation utilities enable your tools to interact with users, collect additional information, and create dynamic conversational experiences.
Basic elicitation
from golf.utilities import elicit
async def interactive_tool():
# Simple text prompt
color = await elicit("What's your favorite color?")
# Use the response in your tool logic
return {"message": f"Great choice! {color} is a beautiful color."}
Type-safe elicitation
from golf.utilities import elicit
from pydantic import BaseModel
class UserInfo(BaseModel):
name: str
email: str
age: int
async def user_registration_tool():
# Collect structured data with validation
user_info = await elicit("Please provide your information:", UserInfo)
return {
"name": user_info.name,
"email": user_info.email,
"age": user_info.age
}
Confirmation dialogs
from golf.utilities import elicit_confirmation
async def deletion_tool(file_path: str):
# Ask for confirmation before destructive action
confirmed = await elicit_confirmation(
f"Are you sure you want to delete {file_path}?"
)
if confirmed:
# Perform deletion
return {"status": "deleted", "file": file_path}
else:
return {"status": "cancelled", "file": file_path}
Advanced elicitation with error handling
from golf.utilities import elicit, elicit_confirmation
async def configuration_tool():
try:
# Collect multiple pieces of information
name = await elicit("What's your name?")
email = await elicit("What's your email address?")
# Confirm before saving
confirmed = await elicit_confirmation(
f"Save configuration for {name} ({email})?"
)
if confirmed:
config = {"name": name, "email": email}
return {"configuration": config, "saved": True}
else:
return {"configuration": None, "saved": False}
except RuntimeError as e:
# User declined or cancelled
return {"error": f"Configuration failed: {str(e)}"}
Sampling utilities
Sampling utilities provide direct access to LLM capabilities within your tools, enabling text generation, analysis, and AI-powered processing with multiple modes.
Basic sampling
from golf.utilities import sample
async def explanation_tool(topic: str):
# Generate an explanation using the default model
explanation = await sample(f"Explain {topic} in simple terms")
return {"topic": topic, "explanation": explanation}
Structured sampling
The sample_structured() function uses a lower temperature (0.1) for more consistent, formatted outputs.
from golf.utilities import sample_structured
async def entity_extraction_tool(text: str):
# Use structured sampling for formatted outputs
entities = await sample_structured(
f"Extract entities from this text: {text}",
format_instructions="Return as JSON with keys: persons, organizations, locations"
)
return {"text": text, "entities": entities}
Context-enhanced sampling
The sample_with_context() function automatically appends context data to prompts.
from golf.utilities import sample_with_context
async def personalized_report_tool(data: str):
# Sample with automatic context enhancement
report = await sample_with_context(
f"Generate a personalized report based on this data: {data}",
context_data={
"user_preferences": "detailed analysis",
"report_format": "executive summary"
}
)
return {"data": data, "report": report}
Advanced sampling with parameters
from golf.utilities import sample
async def creative_writing_tool(prompt: str, style: str):
# Advanced sampling with custom parameters
story = await sample(
f"Write a short story in {style} style based on: {prompt}",
model="gpt-4",
max_tokens=500,
temperature=0.8
)
return {
"prompt": prompt,
"style": style,
"story": story
}
Sampling error handling
from golf.utilities import sample, sample_structured
async def robust_analysis_tool(text: str):
try:
# Attempt structured analysis
analysis = await sample_structured(
f"Analyze the sentiment and themes in: {text}",
format_instructions="Return JSON with sentiment and themes"
)
return {"analysis": analysis, "method": "structured"}
except RuntimeError as e:
# Fall back to basic sampling
try:
analysis = await sample(f"Analyze: {text}")
return {"analysis": analysis, "method": "basic"}
except RuntimeError:
return {
"error": "Analysis failed",
"text": text
}
Authentication integration
Golf utilities seamlessly integrate with the authentication system for secure API forwarding.
Basic token forwarding
from golf.utilities import sample
from golf.auth import get_auth_token
async def api_analysis_tool(data: str):
# Get authentication token
auth_token = get_auth_token()
if not auth_token:
return {"error": "Authentication required"}
# Use token for upstream API call
import httpx
async with httpx.AsyncClient() as client:
response = await client.post(
"https://api.example.com/analyze",
headers={"Authorization": f"Bearer {auth_token}"},
json={"data": data}
)
# Enhance results with LLM sampling
summary = await sample(
f"Summarize this API response: {response.text}"
)
return {
"api_response": response.json(),
"summary": summary
}
Combined context and auth
from golf.utilities import get_current_context, sample
from golf.auth import get_auth_token
async def secure_personalized_tool(request: str):
# Get both context and auth
context = get_current_context()
auth_token = get_auth_token()
if not auth_token:
return {"error": "Authentication required"}
# Log request with context
context.logger.info(f"Processing request: {request}")
# Generate personalized response
response = await sample(
f"Respond to this request personally: {request}",
context_data={
"user_authenticated": True,
"request_id": getattr(context, 'request_id', None)
}
)
return {
"request": request,
"response": response,
"authenticated": True
}
Error handling best practices
Comprehensive error handling
from golf.utilities import get_current_context, sample, elicit
from golf.auth import get_auth_token
async def production_ready_tool(task: str):
try:
# Verify context availability
context = get_current_context()
# Check authentication
auth_token = get_auth_token()
if not auth_token:
confirmation = await elicit_confirmation(
"No authentication found. Continue with limited functionality?"
)
if not confirmation:
return {"error": "Authentication required"}
# Perform main task
result = await sample(f"Complete this task: {task}")
# Log success
context.logger.info(f"Task completed: {task}")
return {
"task": task,
"result": result,
"authenticated": bool(auth_token)
}
except ImportError:
return {
"error": "FastMCP >=2.11.0 required",
"task": task
}
except RuntimeError as e:
if "Context" in str(e):
return {
"error": "Must be called from MCP tool context",
"task": task
}
elif "declined" in str(e):
return {
"error": "User declined operation",
"task": task
}
else:
return {
"error": f"Operation failed: {str(e)}",
"task": task
}