Clay transforms Claude into an OpenAI-compatible API server, allowing you to use Claude with any OpenAI client library while adding powerful project-specific configuration.
macOS:
curl -L https://github.com/rizrmd/clay/releases/latest/download/clay-macos-x64 -o clay
chmod +x clayLinux:
curl -L https://github.com/rizrmd/clay/releases/latest/download/clay-linux-x64 -o clay
chmod +x clayClay automatically configures everything for you:
# Start Clay server (zero configuration required)
./clayOn first run, Clay will:
- Generate a
clay.yamlconfiguration file automatically - Download and install a portable Claude CLI
- Guide you through Claude authentication
- Start the OpenAI-compatible server on port 3000
Once running, use Clay exactly like OpenAI's API:
curl -X POST http://localhost:3000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-sonnet",
"messages": [{"role": "user", "content": "Hello!"}]
}'- Zero Configuration: Just run
./clay- no setup files needed - OpenAI Compatible: Drop-in replacement for OpenAI API calls
- Project Context: Add custom context that Claude remembers
- MCP Support: Connect to Model Context Protocol servers
- Isolated: Portable installation, doesn't affect your system
- Auto-Configuration: Generates
clay.yamlautomatically and manages Claude CLI config files
Clay uses a single clay.yaml file to configure both Clay itself and the underlying Claude CLI. When you start Clay, it automatically generates Claude CLI's config.json and mcp.json files from your clay.yaml settings.
Clay automatically creates a clay.yaml file when it doesn't exist, so you can run it with zero configuration. However, you'll want to customize it for your project.
Clay generates a default clay.yaml automatically. To customize it for your project, simply edit the file that was created:
# Define context that Claude will remember for every conversation
context: |
You are an expert Python developer working on a data analysis project.
The codebase uses pandas, numpy, and scikit-learn.
Always suggest type hints and follow PEP 8 conventions.
# Connect to tools and databases via MCP servers
mcp:
servers:
# File system access
filesystem:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "."]
# Connect to your API
myapi:
transport: "http"
url: "http://localhost:8080/mcp"
headers:
Authorization: "Bearer ${API_TOKEN}"
# Server settings
server:
port: 3000
max_processes: 50Force regenerate the default configuration:
./clay --init-configCheck your configuration is correct:
./clay --validate-configcontext: |
You are working on a React TypeScript project with Next.js.
Project structure:
- /pages - Next.js pages
- /components - Reusable React components
- /lib - Utility functions
- /types - TypeScript type definitions
Code style: Use functional components, prefer const assertions,
include proper JSDoc comments.context: |
You are a PostgreSQL expert working with this database schema:
Users table: id, email, created_at, subscription_type
Posts table: id, user_id, title, content, published_at
Comments table: id, post_id, user_id, content, created_at
Always write optimized queries and explain the execution plan.
mcp:
servers:
database:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-postgres"]
env:
DATABASE_URL: "${DATABASE_URL}"context: |
You are a technical writer creating API documentation.
Documentation standards:
- Use OpenAPI 3.0 specification
- Include request/response examples
- Add error codes and descriptions
- Write clear, concise descriptions
- Include authentication requirementsThe context field lets you define instructions that Claude will remember:
context: |
Your role and expertise here.
Project-specific information.
Coding standards and preferences.
Any other context Claude should know.Command-based servers (most common):
mcp:
servers:
filesystem:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "."]
env:
NODE_ENV: "production"HTTP servers (for remote APIs):
mcp:
servers:
myapi:
transport: "http"
url: "https://api.example.com/mcp"
headers:
Authorization: "Bearer ${API_TOKEN}"
timeout: 30WebSocket servers (for real-time data):
mcp:
servers:
realtime:
transport: "ws"
url: "ws://localhost:9000/mcp"
reconnect: trueReference environment variables in your configuration:
mcp:
servers:
database:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-postgres"]
env:
DATABASE_URL: "${DATABASE_URL}" # Uses $DATABASE_URL from environment# Run on different port
./clay --port 8080
# Or set in clay.yaml
server:
port: 8080Each project can have its own clay.yaml:
cd /path/to/project1
./clay --port 3000 &
cd /path/to/project2
./clay --port 3001 &# Check installation and auth status
./clay --status
# Validate configuration without starting server
./clay --validate-config
# Send test message
./clay --message "Hello Claude!"import openai
client = openai.OpenAI(
base_url="http://localhost:3000/v1",
api_key="not-required" # Clay doesn't require API keys
)
response = client.chat.completions.create(
model="claude-3-sonnet",
messages=[{"role": "user", "content": "Help me debug this code"}]
)
print(response.choices[0].message.content)import OpenAI from 'openai';
const openai = new OpenAI({
baseURL: 'http://localhost:3000/v1',
apiKey: 'not-required'
});
const completion = await openai.chat.completions.create({
model: 'claude-3-sonnet',
messages: [{ role: 'user', content: 'Explain this algorithm' }],
});
console.log(completion.choices[0].message.content);curl -X POST http://localhost:3000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-sonnet",
"messages": [
{"role": "user", "content": "Write a Python function to calculate fibonacci"}
]
}'Clay creates a bridge between OpenAI-compatible clients and Claude CLI:
- Isolated Installation: Downloads portable Claude CLI and Bun runtime
- Configuration Generation: Reads
clay.yamland generates Claude CLI'sconfig.jsonandmcp.jsonfiles - Context Injection: Adds your custom context to every conversation
- MCP Integration: Connects Claude to external tools and data sources (proxies HTTP/WebSocket servers)
- API Translation: Converts OpenAI API calls to Claude CLI commands
- Response Formatting: Returns Claude responses in OpenAI format
Clay acts as a configuration layer on top of Claude CLI, automatically managing all the Claude-specific config files from your single clay.yaml file.
Your files:
clay.yaml- Your project configuration (you edit this)
Generated automatically by Clay:
.claude-home/.config/claude/config.json- Claude CLI's main configuration.claude-home/.config/claude/mcp.json- Claude CLI's MCP server configuration.claude-home/.config/claude/clay-mcp.json- Clay's internal MCP configuration backup
You only need to edit clay.yaml - Clay handles the rest.
Clay won't start:
# Check status and authentication
./clay --status
# Reinstall Claude CLI
./clay --setupConfiguration errors:
# Validate your clay.yaml
./clay --validate-config
# Regenerate sample config
./clay --init-configPort conflicts:
# Use different port
./clay --port 8080- MCP Server Directory - Official MCP servers
- MCP Documentation - Protocol specification
- Claude MCP Guide - Getting started with MCP
If you're building Rust applications, you can use Clay as a library:
[dependencies]
clay = "0.1.0"use clay::{ClaudeSetup, ClaudeProcess};
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let setup = Arc::new(ClaudeSetup::new(".")?);
if !setup.is_installed() {
setup.setup_with_mcp()?;
}
if !setup.check_authentication()? {
setup.run_claude_login()?;
}
let mut process = ClaudeProcess::new(setup)?;
let response = process.send_message("Hello Claude!")?;
println!("Claude: {}", response);
Ok(())
}