openclaw-zero-token
Use major AI models (Claude, ChatGPT, Gemini, DeepSeek, Qwen, etc.) without API tokens by leveraging browser authentication instead of paid API keys
How do I install this agent skill?
npx skills add https://github.com/reason-machines/hermes-skills --skill openclaw-zero-tokenIs this agent skill safe to install?
- Gen Agent Trust Hubfail
This skill downloads and installs a software gateway from an untrusted source to capture sensitive browser credentials for AI providers. It also grants the AI agent the capability to execute arbitrary shell commands and fetch web content, creating a high risk of system compromise or credential theft if the agent is manipulated by malicious external data.
- Socketwarn
1 alert: gptSecurity
- Snykwarn
Risk: MEDIUM · 2 issues
What does this agent skill do?
OpenClaw Zero Token
Skill by ara.so — Hermes Skills collection.
OpenClaw Zero Token is a TypeScript-based gateway that lets you use major AI models (Claude, ChatGPT, Gemini, DeepSeek, Qwen, Kimi, Doubao, Grok, GLM, Xiaomi MiMo, Manus) completely free by automating browser-based authentication instead of requiring paid API tokens. It drives official web UIs using Chrome DevTools Protocol (CDP) and Playwright to capture credentials, then proxies requests through a unified OpenAI-compatible API gateway.
What It Does
- Zero-cost LLM access: Log in via browser once, reuse credentials for API calls
- Unified gateway: OpenAI-compatible API endpoint on port 3001
- 11 web models with tool calling:
web_search,web_fetch,exec,read,write,message - AskOnce multi-model queries: Broadcast one question to all configured providers
- Web UI + CLI + Gateway: Multiple interaction modes (Lit 3.x UI, TUI, REST API)
Supported Providers
| Provider | Status | Auth Method |
|---|---|---|
| DeepSeek | ✅ | Browser login |
| Qwen (intl/cn) | ✅ | Browser login |
| Kimi | ✅ | Browser login |
| Claude Web | ✅ | Browser login |
| ChatGPT Web | ✅ | Browser login |
| Gemini Web | ✅ | Browser login |
| Grok Web | ✅ | Browser login |
| Doubao | ✅ | Browser login |
| GLM/GLM Intl | ✅ | Browser login |
| Xiaomi MiMo | ✅ | Browser login |
| Manus API | ✅ | API key (free) |
Installation
Prerequisites
# Check versions
node --version # >= 22.12.0
pnpm --version # >= 9.0.0
# Install Node.js 22+ if needed
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
# Install pnpm
npm install -g pnpm
Clone and Build
git clone https://github.com/linuxhsj/openclaw-zero-token.git
cd openclaw-zero-token
# Install dependencies
pnpm install
# Build backend + frontend
pnpm build
pnpm ui:build
Configuration
Environment Setup
Create .env file:
# Gateway settings
PORT=3001
NODE_ENV=production
# Browser debugging (DO NOT expose publicly)
CHROME_DEBUG_PORT=9222
# Optional: workspace for agent file access
AGENT_WORKSPACE=/home/user/agent-workspace
# Optional: logging
LOG_LEVEL=info
First-Time Authentication Flow
OpenClaw uses a three-step process:
- Start debug Chrome → Opens browser on port 9222
- Login to web models → Manual browser login (scan QR / password)
- Run onboard wizard → Captures credentials automatically
# Terminal 1: Start Chrome in debug mode (keep running)
./start-chrome-debug.sh
# This opens Chrome with tabs for:
# - DeepSeek: https://chat.deepseek.com
# - Qwen intl: https://hf.co/chat
# - Qwen cn: https://tongyi.aliyun.com
# - Kimi: https://kimi.moonshot.cn
# - Claude: https://claude.ai
# etc.
# LOG IN to each site manually in the browser
# Terminal 2: Run authentication wizard
./onboard.sh webauth
# Interactive menu:
# [1] deepseek-web
# [2] qwen-web
# [3] qwen-cn
# [4] kimi
# [5] claude-web
# ... etc
# Select provider → wizard captures auth automatically
# Saved to: data/auth/<provider>.json
The onboard.sh script uses Playwright CDP to intercept network requests and extract:
- Cookies
- Bearer tokens
- User-Agent headers
Starting the Gateway
# Start server (daemon mode)
./server.sh start
# Other commands
./server.sh stop
./server.sh restart
./server.sh status
# Manual start (foreground, for debugging)
pnpm start
Gateway runs on http://localhost:3001 with OpenAI-compatible endpoints.
Key Commands and Scripts
Core Scripts
| Script | Purpose |
|---|---|
./start-chrome-debug.sh | Launch Chrome on port 9222 for logins |
./onboard.sh webauth | Run auth wizard to capture credentials |
| `./server.sh [start | stop]` |
pnpm build | Build TypeScript backend |
pnpm ui:build | Build Lit 3.x frontend |
pnpm test | Run test suite |
pnpm Scripts (package.json)
# Build
pnpm build # Compile TypeScript
pnpm ui:build # Build frontend
pnpm build:all # Both backend + UI
# Development
pnpm dev # Watch mode with hot reload
pnpm start # Production server
# Testing
pnpm test # Run tests
pnpm lint # ESLint check
pnpm format # Prettier format
API Usage
OpenAI-Compatible Endpoints
OpenClaw exposes a standard OpenAI API format on port 3001:
# List available models
curl http://localhost:3001/v1/models
# Chat completion (non-streaming)
curl http://localhost:3001/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-web/deepseek-chat",
"messages": [{"role": "user", "content": "Hello!"}]
}'
# Streaming
curl http://localhost:3001/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-web/qwen-turbo",
"messages": [{"role": "user", "content": "Count to 5"}],
"stream": true
}'
TypeScript Client Example
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'http://localhost:3001/v1',
apiKey: 'not-needed', // Zero Token doesn't require keys
});
async function chat() {
const response = await client.chat.completions.create({
model: 'deepseek-web/deepseek-chat',
messages: [
{ role: 'user', content: 'Explain TypeScript generics' }
],
});
console.log(response.choices[0].message.content);
}
chat();
Streaming Response
async function streamChat() {
const stream = await client.chat.completions.create({
model: 'kimi/moonshot-v1-8k',
messages: [{ role: 'user', content: 'Write a haiku' }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || '');
}
}
Tool Calling (Web Models)
OpenClaw injects tool definitions into prompts for 11/13 web models. Tools are only injected when user message contains keywords like "search", "read", "execute".
Available Tools
| Tool | Function | Provider Support |
|---|---|---|
web_search | DuckDuckGo search | 11/13 models |
web_fetch | Fetch webpage content | 11/13 models |
exec | Execute shell command | 11/13 models |
read | Read file (workspace restricted) | 11/13 models |
write | Write file (workspace restricted) | 11/13 models |
message | Structured output | 11/13 models |
Tool Calling Example
const response = await client.chat.completions.create({
model: 'deepseek-web/deepseek-chat',
messages: [{
role: 'user',
content: 'Search for TypeScript 5.4 release notes and summarize'
}],
});
// Model automatically:
// 1. Detects "search" keyword
// 2. Calls web_search tool
// 3. Fetches results
// 4. Summarizes content
Agent File Access Configuration
Tools like read/write are restricted to the configured workspace:
# In .env
AGENT_WORKSPACE=/home/user/projects/safe-zone
// Attempting to read outside workspace fails
const badRead = await client.chat.completions.create({
model: 'kimi/moonshot-v1-32k',
messages: [{
role: 'user',
content: 'Read /etc/passwd' // ❌ Blocked
}],
});
// Within workspace succeeds
const goodRead = await client.chat.completions.create({
model: 'kimi/moonshot-v1-32k',
messages: [{
role: 'user',
content: 'Read project-notes.md' // ✅ Allowed if in workspace
}],
});
AskOnce: Multi-Model Queries
Query all configured providers simultaneously:
# CLI usage (if implemented)
pnpm ask-once "What is the capital of France?"
# Returns responses from:
# - DeepSeek: "Paris..."
# - Qwen: "The capital is Paris..."
# - Kimi: "Paris, established in..."
# etc.
// Programmatic AskOnce
import { askOnce } from './src/zero-token/ask-once';
const results = await askOnce({
query: 'Explain quantum entanglement in one sentence',
providers: ['deepseek-web', 'qwen-web', 'kimi', 'claude-web'],
});
results.forEach(({ provider, response, duration }) => {
console.log(`[${provider}] (${duration}ms): ${response}`);
});
Common Patterns
1. Multi-Provider Failover
const providers = [
'deepseek-web/deepseek-chat',
'qwen-web/qwen-turbo',
'kimi/moonshot-v1-8k',
];
async function chatWithFailover(message: string) {
for (const model of providers) {
try {
const response = await client.chat.completions.create({
model,
messages: [{ role: 'user', content: message }],
});
return response.choices[0].message.content;
} catch (error) {
console.warn(`${model} failed, trying next...`);
}
}
throw new Error('All providers failed');
}
2. Model Routing by Task
function selectModel(task: string): string {
if (task.includes('reasoning') || task.includes('logic')) {
return 'deepseek-web/deepseek-reasoner';
}
if (task.includes('code')) {
return 'qwen-web/qwen-plus';
}
return 'kimi/moonshot-v1-8k'; // default
}
const model = selectModel('Write a sorting algorithm');
const response = await client.chat.completions.create({
model,
messages: [{ role: 'user', content: 'Implement quicksort in Python' }],
});
3. Workspace-Safe Agent
import * as path from 'path';
const WORKSPACE = process.env.AGENT_WORKSPACE || '/tmp/agent-workspace';
async function safeAgentTask(instruction: string) {
// Ensure workspace exists
await fs.promises.mkdir(WORKSPACE, { recursive: true });
const response = await client.chat.completions.create({
model: 'kimi/moonshot-v1-32k',
messages: [{
role: 'system',
content: `You are a helpful agent. All file operations must be within ${WORKSPACE}.`
}, {
role: 'user',
content: instruction
}],
});
return response.choices[0].message.content;
}
// Example: "Create a file notes.txt with today's date"
await safeAgentTask('Write the current timestamp to notes.txt');
4. Re-authentication Helper
import { execSync } from 'child_process';
async function ensureAuth(provider: string) {
const authPath = `data/auth/${provider}.json`;
try {
const authData = await fs.promises.readFile(authPath, 'utf-8');
const parsed = JSON.parse(authData);
// Check if token is expired (example logic)
if (Date.now() > parsed.expiresAt) {
console.log(`Auth expired for ${provider}, re-running onboard...`);
execSync(`./onboard.sh webauth ${provider}`, { stdio: 'inherit' });
}
} catch (error) {
console.log(`No auth found for ${provider}, running onboard...`);
execSync(`./onboard.sh webauth ${provider}`, { stdio: 'inherit' });
}
}
// Before making API calls
await ensureAuth('deepseek-web');
Troubleshooting
Chrome Debug Port Issues
Symptom: onboard.sh fails with "Cannot connect to CDP"
# Kill existing Chrome processes
pkill -f "chrome.*remote-debugging-port=9222"
# Restart debug Chrome
./start-chrome-debug.sh
# Verify port is open
lsof -i :9222 # Should show Chrome process
Authentication Expired
Symptom: API calls return 401/403 after initial setup
# Re-run onboarding for specific provider
./onboard.sh webauth
# Select the provider that's failing
# Example: [1] deepseek-web
# Manually verify in browser:
# 1. Open http://localhost:9222 in another browser
# 2. Navigate to chat site
# 3. Check if logged in
Stream Parsing Errors
Symptom: "Cannot parse SSE stream" for Doubao or Gemini
// Use non-streaming for unstable providers
const response = await client.chat.completions.create({
model: 'doubao/doubao-pro',
messages: [{ role: 'user', content: 'Hello' }],
stream: false, // ← Disable streaming
});
Tool Calling Not Triggering
Symptom: Model doesn't use tools despite keyword in message
// Ensure keywords are explicit
const response = await client.chat.completions.create({
model: 'kimi/moonshot-v1-32k',
messages: [{
role: 'user',
content: 'SEARCH for TypeScript 5.4 release notes' // ← Explicit keyword
}],
});
// Check middleware logs
// Tool injection only happens when keywords detected:
// "search", "fetch", "execute", "read file", "write file"
Gateway Won't Start
# Check if port 3001 is already in use
lsof -i :3001
# Kill existing process
kill -9 $(lsof -t -i :3001)
# Check logs
tail -f logs/gateway.log
# Verify build succeeded
pnpm build
pnpm ui:build
Model Rate Limits
Symptom: Web model returns "Too many requests"
// Implement exponential backoff
async function chatWithRetry(model: string, message: string, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await client.chat.completions.create({
model,
messages: [{ role: 'user', content: message }],
});
} catch (error: any) {
if (error.status === 429 && i < retries - 1) {
const delay = Math.pow(2, i) * 1000;
console.log(`Rate limited, waiting ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
}
Advanced Configuration
Custom Provider Setup
// src/zero-token/providers/custom-provider.ts
import { BaseWebProvider } from './base-web-provider';
export class CustomProvider extends BaseWebProvider {
constructor() {
super({
name: 'custom-web',
chatUrl: 'https://custom-ai.example.com/chat',
apiEndpoint: 'https://custom-ai.example.com/api/v1/chat',
});
}
async authenticate(page: Page): Promise<AuthData> {
// Custom auth logic
const token = await page.evaluate(() => {
return localStorage.getItem('auth_token');
});
return {
token,
cookies: await page.context().cookies(),
userAgent: await page.evaluate(() => navigator.userAgent),
};
}
}
Environment Variables Reference
# Core settings
PORT=3001 # Gateway port
NODE_ENV=production # production | development
LOG_LEVEL=info # error | warn | info | debug
# Browser automation
CHROME_DEBUG_PORT=9222 # CDP port
HEADLESS=false # true for headless mode
# Agent configuration
AGENT_WORKSPACE=/path/to/workspace # Tool file access restriction
TOOL_TIMEOUT=30000 # Tool execution timeout (ms)
# Provider-specific (optional)
DEEPSEEK_CUSTOM_ENDPOINT=https://... # Override default endpoints
QWEN_API_VERSION=v1 # API version
File Structure
openclaw-zero-token/
├── src/
│ ├── zero-token/
│ │ ├── providers/ # Web model implementations
│ │ │ ├── deepseek-web.ts
│ │ │ ├── qwen-web.ts
│ │ │ ├── kimi.ts
│ │ │ └── ...
│ │ ├── tool-calling/ # Tool injection middleware
│ │ │ ├── tools.ts # Tool definitions
│ │ │ └── middleware.ts # Prompt injection logic
│ │ ├── ask-once/ # Multi-model query system
│ │ └── auth/ # Authentication capture
│ ├── gateway/ # OpenAI-compatible API gateway
│ └── ui/ # Lit 3.x web interface
├── data/
│ └── auth/ # Stored credentials (gitignored)
│ ├── deepseek-web.json
│ ├── qwen-web.json
│ └── ...
├── scripts/
│ ├── start-chrome-debug.sh # Chrome launcher
│ ├── onboard.sh # Auth wizard
│ └── server.sh # Gateway daemon manager
├── .env # Environment config
└── package.json
Security Notes
- Auth Data:
data/auth/*.jsoncontains sensitive credentials — never commit - Chrome Debug Port: Port 9222 allows full browser control — DO NOT expose externally
- Workspace Restriction: Agent file tools are sandboxed to
AGENT_WORKSPACE - HTTPS Required: Use reverse proxy (nginx/Caddy) for production deployment
Example nginx config:
server {
listen 443 ssl;
server_name openclaw.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
}
}
References
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/reason-machines/hermes-skills/openclaw-zero-token">View openclaw-zero-token on skillZs</a>