Environment Variables
Required
# Observee Configuration
OBSERVEE_API_KEY=obs_your_api_key_here
OBSERVEE_CLIENT_ID=your_client_id_here # Optional
# LLM Provider Keys (choose one or more)
ANTHROPIC_API_KEY=your_anthropic_key_here
OPENAI_API_KEY=your_openai_key_here
GOOGLE_API_KEY=your_gemini_key_here
Optional
# Custom server URL
OBSERVEE_URL=https://your-custom-server.com/mcp
# Tool filtering
MCP_FILTER_TYPE=bm25 # bm25, local_embedding, cloud
# Cloud filtering (if using cloud filter)
PINECONE_API_KEY=your_pinecone_key_here
Function Parameters
All configuration can be passed as function parameters:
from observee_agents import chat_with_tools
result = chat_with_tools(
message="Hello",
# Provider settings
provider="anthropic",
model="claude-sonnet-4-20250514",
# Authentication
observee_api_key="obs_your_key",
observee_url="https://custom-server.com/mcp",
client_id="custom_client_123",
# Tool filtering
enable_filtering=True,
filter_type="bm25",
max_tools=10,
min_score=7.0,
# Performance
sync_tools=False,
# LLM parameters
temperature=0.7,
max_tokens=1000,
top_p=0.9
)
Provider-Specific Settings
Anthropic Claude
result = chat_with_tools(
message="Hello",
provider="anthropic",
model="claude-sonnet-4-20250514",
temperature=0.7,
max_tokens=1000,
top_p=0.9,
top_k=40
)
OpenAI GPT
result = chat_with_tools(
message="Hello",
provider="openai",
model="gpt-4o",
temperature=0.7,
max_tokens=1000,
top_p=0.9,
frequency_penalty=0.0,
presence_penalty=0.0
)
Google Gemini
result = chat_with_tools(
message="Hello",
provider="gemini",
model="gemini-2.5-pro",
temperature=0.7,
max_tokens=1000,
top_p=0.9,
top_k=40
)
BM25 Filter (Default)
result = chat_with_tools(
message="Gmail email management",
filter_type="bm25",
max_tools=5,
min_score=8.0
)
Local Embedding Filter
# Requires: pip install mcp-agents[embedding]
result = chat_with_tools(
message="Help me be productive",
filter_type="local_embedding",
max_tools=10,
min_score=7.0
)
Cloud Filter
# Requires: pip install mcp-agents[cloud]
# Requires: PINECONE_API_KEY and OPENAI_API_KEY
result = chat_with_tools(
message="Complex analytical task",
filter_type="cloud",
max_tools=15,
min_score=6.0
)
Disable Filtering
result = chat_with_tools(
message="What can you do?",
enable_filtering=False # Uses all available tools
)
Development Mode
result = chat_with_tools(
message="Test query",
sync_tools=True, # Refresh tool cache
enable_filtering=False, # See all tools
max_tools=50 # More tools for testing
)
Production Mode
result = chat_with_tools(
message="Production query",
sync_tools=False, # Use cached tools
filter_type="bm25", # Fast filtering
max_tools=10, # Optimized performance
min_score=8.0 # High relevance threshold
)
Authentication Priority
The SDK uses this priority order for authentication:
- Function parameters:
observee_api_key
, observee_url
- Environment variables:
OBSERVEE_API_KEY
, OBSERVEE_URL
- Default values: Built-in defaults
# This will use the function parameter, not environment variable
result = chat_with_tools(
message="Hello",
observee_api_key="obs_override_key" # Takes priority
)
Custom Server Configuration
Using Custom URL
result = chat_with_tools(
message="Hello",
observee_url="https://your-company.mcp.server/endpoint",
client_id="company_client_id"
)
Environment Variable
export OBSERVEE_URL="https://your-company.mcp.server/endpoint"
Error Handling Configuration
Timeout Settings
# Custom timeout (if supported by provider)
result = chat_with_tools(
message="Long running task",
provider="anthropic",
timeout=60 # 60 seconds
)
Retry Configuration
import time
def retry_chat(message, max_retries=3, backoff=2):
for attempt in range(max_retries):
try:
return chat_with_tools(
message=message,
provider="anthropic"
)
except Exception as e:
if attempt == max_retries - 1:
raise e
time.sleep(backoff ** attempt)
Configuration Examples
Multi-Environment Setup
import os
def get_config():
env = os.getenv("ENVIRONMENT", "development")
if env == "development":
return {
"sync_tools": True,
"enable_filtering": False,
"max_tools": 50,
"temperature": 0.9
}
elif env == "staging":
return {
"sync_tools": False,
"filter_type": "local_embedding",
"max_tools": 20,
"temperature": 0.7
}
else: # production
return {
"sync_tools": False,
"filter_type": "bm25",
"max_tools": 10,
"temperature": 0.5
}
config = get_config()
result = chat_with_tools(
message="Hello",
provider="anthropic",
**config
)
Provider Fallback
def chat_with_fallback(message, providers=None):
if providers is None:
providers = ["anthropic", "openai", "gemini"]
for provider in providers:
try:
return chat_with_tools(
message=message,
provider=provider
)
except Exception as e:
print(f"Failed with {provider}: {e}")
continue
raise Exception("All providers failed")
result = chat_with_fallback("Hello world")
Dynamic Configuration
def smart_config(message):
# Use different configs based on message content
if "email" in message.lower():
return {
"filter_type": "bm25",
"max_tools": 5,
"provider": "anthropic"
}
elif "creative" in message.lower():
return {
"filter_type": "local_embedding",
"max_tools": 15,
"provider": "openai",
"temperature": 0.9
}
else:
return {
"filter_type": "bm25",
"max_tools": 10,
"provider": "anthropic"
}
config = smart_config("Help me write a creative story")
result = chat_with_tools(
message="Help me write a creative story",
**config
)
Best Practices
- Use environment variables for sensitive data
- Choose appropriate filtering based on use case
- Optimize max_tools for performance
- Set reasonable timeouts for long operations
- Implement fallback providers for reliability
- Use different configs for different environments
Next Steps