This guide covers the optional features and their configuration in Morphic.
Morphic uses PostgreSQL for chat history storage. A database is optional for basic usage — without it, Morphic runs in a stateless mode where chat history is not persisted.
Set the connection string in .env.local:
DATABASE_URL=postgresql://user:password@localhost:5432/morphicAny PostgreSQL provider works: Neon, Supabase, or a local PostgreSQL instance.
After configuring your database, run migrations to create the necessary tables:
bun run migrateThis command applies all migrations from the drizzle/ directory.
By default, Morphic runs in anonymous mode with authentication disabled (ENABLE_AUTH=false in .env.local.example). This is ideal for personal use where all users share a single anonymous user ID.
No configuration needed. The default settings in .env.local.example include:
ENABLE_AUTH=false
ANONYMOUS_USER_ID=anonymous-userTo enable user authentication with Supabase:
-
Create a Supabase project at supabase.com
-
Set the following environment variables in
.env.local:
ENABLE_AUTH=true
NEXT_PUBLIC_SUPABASE_URL=[YOUR_SUPABASE_PROJECT_URL]
NEXT_PUBLIC_SUPABASE_ANON_KEY=[YOUR_SUPABASE_ANON_KEY]- Obtain your credentials from the Supabase dashboard:
- Project URL: Settings → API → Project URL
- Anon Key: Settings → API → Project API keys → anon/public
With authentication enabled, users will need to sign up/login to use Morphic, and each user will have isolated chat history.
Guest mode allows users to try Morphic without creating an account. Guest sessions are ephemeral - no chat history is stored in the database.
Set the following environment variable:
ENABLE_GUEST_CHAT=trueWhen guest mode is enabled:
- No authentication required: Users can start chatting immediately
- No chat history: Messages are not saved to the database
- Full context per request: The client sends all messages with each request to maintain conversation context
- No URL navigation: Guests stay on the root path (no
/search/[id]URLs) - Disabled features:
- File upload
- Quality mode (forced to "Speed")
- Chat sharing
- Sidebar history
For cloud deployments, you can limit guest usage per IP address:
GUEST_CHAT_DAILY_LIMIT=10 # Maximum requests per IP per day (default: 10)Rate limiting requires Redis (Upstash) configuration:
UPSTASH_REDIS_REST_URL=[YOUR_UPSTASH_URL]
UPSTASH_REDIS_REST_TOKEN=[YOUR_UPSTASH_TOKEN]Note: Rate limiting only applies when MORPHIC_CLOUD_DEPLOYMENT=true. For self-hosted deployments, rate limiting is disabled by default.
| Environment | Configuration |
|---|---|
| Personal/Local | ENABLE_AUTH=false (anonymous mode) |
| Public Demo | ENABLE_GUEST_CHAT=true with rate limiting |
| Production | ENABLE_AUTH=true (Supabase authentication) |
SearXNG can be used as an alternative search backend with advanced search capabilities.
- Set up SearXNG as your search provider:
SEARCH_API=searxng
SEARXNG_API_URL=http://localhost:8080
SEARXNG_SECRET="" # generate with: openssl rand -base64 32- Ensure you have Docker and Docker Compose installed
- Two configuration files are provided in the root directory:
searxng-settings.yml: Contains main configuration for SearXNGsearxng-limiter.toml: Configures rate limiting and bot detection
- Configure environment variables in your
.env.local:
# SearXNG Base Configuration
SEARXNG_PORT=8080
SEARXNG_BIND_ADDRESS=0.0.0.0
SEARXNG_IMAGE_PROXY=true
# Search Behavior
SEARXNG_DEFAULT_DEPTH=basic # Set to 'basic' or 'advanced'
SEARXNG_MAX_RESULTS=50 # Maximum number of results to return
SEARXNG_ENGINES=google,bing,duckduckgo,wikipedia # Comma-separated list of search engines
SEARXNG_TIME_RANGE=None # Time range: day, week, month, year, or None
SEARXNG_SAFESEARCH=0 # 0: off, 1: moderate, 2: strict
# Rate Limiting
SEARXNG_LIMITER=false # Enable to limit requests per IPSEARXNG_DEFAULT_DEPTH: Controls search depthbasic: Standard searchadvanced: Includes content crawling and relevance scoring
SEARXNG_MAX_RESULTS: Maximum results to returnSEARXNG_CRAWL_MULTIPLIER: In advanced mode, determines how many results to crawl- Example: If
MAX_RESULTS=10andCRAWL_MULTIPLIER=4, up to 40 results will be crawled
- Example: If
You can modify searxng-settings.yml to:
- Enable/disable specific search engines
- Change UI settings
- Adjust server options
Example of disabling specific engines:
engines:
- name: wikidata
disabled: trueFor detailed configuration options, refer to the SearXNG documentation
- If specific search engines aren't working, try disabling them in
searxng-settings.yml - For rate limiting issues, adjust settings in
searxng-limiter.toml - Check Docker logs for potential configuration errors:
docker-compose logs searxngBrave Search provides enhanced support for video and image searches when used as a general search provider:
BRAVE_SEARCH_API_KEY=[YOUR_BRAVE_SEARCH_API_KEY]Get your API key at: https://brave.com/search/api/
Features:
- Multiple content types in single search (web, video, image, news)
- Optimized for multimedia content with thumbnails
- Direct video duration and metadata support
- Used automatically when
type="general"is specified in search queries
Fallback Behavior:
If BRAVE_SEARCH_API_KEY is not configured, type="general" searches will automatically fall back to your configured optimized search provider. Video and image searches will still work but may have limited multimedia support depending on the provider.
Models are configured in config/models/*.json files. Each provider requires its corresponding API key to be set in the environment variables.
Model configuration files use the following structure:
{
"version": 1,
"models": {
"byMode": {
"quick": {
"speed": {
"id": "model-id",
"name": "Model Name",
"provider": "Provider Name",
"providerId": "provider-id",
"providerOptions": {}
},
"quality": {
"id": "model-id",
"name": "Model Name",
"provider": "Provider Name",
"providerId": "provider-id",
"providerOptions": {}
}
},
"adaptive": {
"speed": {
"id": "model-id",
"name": "Model Name",
"provider": "Provider Name",
"providerId": "provider-id",
"providerOptions": {}
},
"quality": {
"id": "model-id",
"name": "Model Name",
"provider": "Provider Name",
"providerId": "provider-id",
"providerOptions": {}
}
}
},
"relatedQuestions": {
"id": "model-id",
"name": "Model Name",
"provider": "Provider Name",
"providerId": "provider-id"
}
}
}Define all four combinations to control which model runs for every search mode (quick, adaptive) and preference (speed, quality). For example, you can pair quick/speed with gemini-2.5-flash-lite while keeping adaptive/quality on GPT-5. The default config ships with OpenAI models for every slot so Morphic works out-of-the-box.
OPENAI_API_KEY=[YOUR_API_KEY]GOOGLE_GENERATIVE_AI_API_KEY=[YOUR_API_KEY]ANTHROPIC_API_KEY=[YOUR_API_KEY]Vercel AI Gateway allows you to use multiple AI providers through a single endpoint with automatic failover and load balancing.
AI_GATEWAY_API_KEY=[YOUR_AI_GATEWAY_API_KEY]Ollama enables you to run large language models locally on your own hardware.
Configuration:
OLLAMA_BASE_URL=http://localhost:11434Then update your config/models/*.json files to use Ollama models:
{
"id": "qwen3:latest",
"name": "Qwen 3",
"provider": "Ollama",
"providerId": "ollama"
}Important Notes:
-
Tools Capability: Morphic requires models to support the
toolscapability for function calling. On server startup, Morphic validates configured models and logs the results. Note that even if a model reports tools support, actual tool calling performance depends on the model's capabilities and is not guaranteed. -
Validation Logs: Check server logs on startup to verify your configured models:
✓ qwen3:latest (configured and tools supported) ✗ deepseek-r1:latest (configured but lacks tools support)
Enable tracing and monitoring with Langfuse:
LANGFUSE_SECRET_KEY=[YOUR_SECRET_KEY]
LANGFUSE_PUBLIC_KEY=[YOUR_PUBLIC_KEY]
LANGFUSE_HOST=https://cloud.langfuse.comEnable file upload with Cloudflare R2:
CLOUDFLARE_R2_ACCESS_KEY_ID=[YOUR_ACCESS_KEY]
CLOUDFLARE_R2_SECRET_ACCESS_KEY=[YOUR_SECRET_KEY]
CLOUDFLARE_R2_ACCOUNT_ID=[YOUR_ACCOUNT_ID]
CLOUDFLARE_R2_BUCKET_NAME=[YOUR_BUCKET_NAME]Use Jina for enhanced content extraction:
JINA_API_KEY=[YOUR_API_KEY]