clawdirect-dev について
ClawDirect-Devは、ATXP認証を使ったAIエージェント向けウェブ体験の構築ガイドです。MCPサーバー、Cookieによるブラウザー認証、Express API、エージェントスキルを扱います。
主な機能
- 01ATXP認証アーキテクチャ
- 02MCPサーバーとCookieツールの設定
- 03Cookieによるブラウザー認証
- 04Express APIとCookie検証
- 05エージェントスキルとデプロイの案内
活用シーン
- 01AIエージェント向けウェブサービスの構築
- 02MCP認証とブラウザーセッションの連携
- 03エージェント向け操作へのATXP決済の追加
MCP 対応
ウェブサイトと併設するMCPサーバーの構築方法を案内し、エージェント認証やプログラムからの操作に使うCookieツールを扱います。エージェントはMCP経由でCookieを取得し、サイトの閲覧時に使用できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ napoleond/ clawdirect --skill clawdirect-devインストール後、Claude Code で/clawdirect-devを入力して読み込まれたか確認します。
詳細
ClawDirect-Dev
ATXP ベースの認証を使用して、エージェント向けのウェブ体験を構築します。
リファレンス実装:https://github.com/napoleond/clawdirect
ATXP とは?
ATXP(Agent Transaction Protocol)は、AI エージェントがサービスの認証を受け、料金を支払えるようにします。エージェント向けのウェブサイトを構築する際、ATXP は次の機能を提供します。
- エージェントの ID:リクエストを行っているエージェントを把握できます
- 支払い:プレミアム機能の利用に料金を請求できます(任意)
- MCP 連携:エージェントがプログラムから呼び出せるツールを公開できます
ATXP の詳細については、次をご覧ください:https://skills.sh/atxp-dev/cli/atxp
エージェントの利用方法
エージェントは次の 2 つの方法でサイトを利用します。
- ブラウザー:エージェントはブラウザー自動化ツールを使用してウェブサイトにアクセスし、人間と同じようにボタンをクリックしたり、フォームに入力したり、ページを移動したりします
- MCP ツール:エージェントは MCP エンドポイントを直接呼び出し、認証や支払いなどの操作をプログラムから実行します
Cookie ベースの認証パターンは、この 2 つをつなぎます。エージェントは MCP 経由で認証 Cookie を取得し、ブラウザーでの閲覧時に使用します。
重要:エージェントのブラウザーでは、HTTP 専用 Cookie を直接設定できないことがよくあります。推奨されるパターンは、エージェントが Cookie の値をクエリ文字列(例:?myapp_cookie=XYZ)で渡し、サーバーが Cookie を設定してから、クリーンな URL にリダイレクトする方法です。
アーキテクチャの概要
┌──────────────────────────────────────────────────────────────────┐
│ AI Agent │
│ ┌─────────────────────┐ ┌─────────────────────────┐ │
│ │ Browser Tool │ │ MCP Client │ │
│ │ (visits website) │ │ (calls tools) │ │
│ └─────────┬───────────┘ └───────────┬─────────────┘ │
└────────────┼─────────────────────────────────┼──────────────────┘
│ │
▼ ▼
┌────────────────────────────────────────────────────────────────┐
│ Your Application │
│ ┌─────────────────────┐ ┌─────────────────────────┐ │
│ │ Web Server │ │ MCP Server │ │
│ │ (Express) │ │ (@longrun/turtle) │ │
│ │ │ │ │ │
│ │ - Serves UI │ │ - yourapp_cookie │ │
│ │ - Cookie auth │ │ - yourapp_action │ │
│ └─────────┬───────────┘ └───────────┬─────────────┘ │
│ │ │ │
│ └──────────┬─────────────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ SQLite │ │
│ │ auth_cookies │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
構築手順
- ウェブサイトと並行して MCP サーバーを作成する
- MCP サーバーに Cookie ツールを実装する
- ウェブ API の認証に Cookie を使用する
- サイト用のエージェントスキルを公開する
手順 1:プロジェクトのセットアップ
必要なスタックを使用して Node.js プロジェクトを初期化します。
mkdir my-agent-app && cd my-agent-app
npm init -y
npm install @longrun/turtle @atxp/server @atxp/express better-sqlite3 express cors dotenv zod
npm install -D typescript @types/node @types/express @types/cors @types/better-sqlite3 tsx
tsconfig.json を作成します。
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "dist",
"rootDir": "src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"]
}
.env を作成します。
FUNDING_DESTINATION_ATXP=<your_atxp_account>
PORT=3001
手順 2:Cookie 認証を備えたデータベース
src/db.ts を作成します。
import Database from 'better-sqlite3';
import crypto from 'crypto';
const DB_PATH = process.env.DB_PATH || './data.db';
let db: Database.Database;
export function getDb(): Database.Database {
if (!db) {
db = new Database(DB_PATH);
db.pragma('journal_mode = WAL');
// Auth cookies table - maps cookies to ATXP accounts
db.exec(`
CREATE TABLE IF NOT EXISTS auth_cookies (
cookie_value TEXT PRIMARY KEY,
atxp_account TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
// Add your app's tables here
}
return db;
}
export function createAuthCookie(atxpAccount: string): string {
const cookieValue = crypto.randomBytes(32).toString('hex');
getDb().prepare(`
INSERT INTO auth_cookies (cookie_value, atxp_account)
VALUES (?, ?)
`).run(cookieValue, atxpAccount);
return cookieValue;
}
export function getAtxpAccountFromCookie(cookieValue: string): string | null {
const result = getDb().prepare(`
SELECT atxp_account FROM auth_cookies WHERE cookie_value = ?
`).get(cookieValue) as { atxp_account: string } | undefined;
return result?.atxp_account || null;
}
手順 3:Cookie ツールを備えた MCP ツール
src/tools.ts を作成します。
import { defineTool } from '@longrun/turtle';
import { z } from 'zod';
import { requirePayment, atxpAccountId } from '@atxp/server';
import BigNumber from 'bignumber.js';
import { createAuthCookie } from './db.js';
// Cookie tool - agents call this to get browser auth
export const cookieTool = defineTool(
'myapp_cookie', // Replace 'myapp' with your app name
'Get an authentication cookie for browser use. Set this cookie to authenticate when using the web interface.',
z.object({}),
async () => {
// Free but requires ATXP auth
const accountId = atxpAccountId();
if (!accountId) {
throw new Error('Authentication required');
}
const cookie = createAuthCookie(accountId);
return JSON.stringify({
cookie,
instructions: 'To authenticate in a browser, navigate to https://your-domain.com?myapp_cookie=<cookie_value> - the server will set the HTTP-only cookie and redirect. Alternatively, set the cookie directly if your browser tool supports it.'
});
}
);
// Example paid tool
export const paidActionTool = defineTool(
'myapp_action',
'Perform some action. Cost: $0.10',
z.object({
input: z.string().describe('Input for the action')
}),
async ({ input }) => {
await requirePayment({ price: new BigNumber(0.10) });
const accountId = atxpAccountId();
if (!accountId) {
throw new Error('Authentication required');
}
// Your action logic here
return JSON.stringify({ success: true, input });
}
);
export const allTools = [cookieTool, paidActionTool];
手順 4:Cookie 検証を備えた Express API
src/api.ts を作成します。
import { Router, Request, Response } from 'express';
import { getAtxpAccountFromCookie } from './db.js';
export const apiRouter = Router();
// Helper to extract cookie
function getCookieValue(req: Request, cookieName: string): string | null {
const cookieHeader = req.headers.cookie;
if (!cookieHeader) return null;
const cookies = cookieHeader.split(';').map(c => c.trim());
for (const cookie of cookies) {
if (cookie.startsWith(`${cookieName}=`)) {
return cookie.substring(cookieName.length + 1);
}
}
return null;
}
// Middleware to require cookie auth
function requireCookieAuth(req: Request, res: Response, next: Function) {
const cookieValue = getCookieValue(req, 'myapp_cookie');
if (!cookieValue) {
res.status(401).json({
error: 'Authentication required',
message: 'Use the myapp_cookie MCP tool to get an authentication cookie'
});
return;
}
const atxpAccount = getAtxpAccountFromCookie(cookieValue);
if (!atxpAccount) {
res.status(401).json({
error: 'Invalid cookie',
message: 'Your cookie is invalid or expired. Get a new one via the MCP tool.'
});
return;
}
// Attach account to request for use in handlers
(req as any).atxpAccount = atxpAccount;
next();
}
// Public endpoint (no auth)
apiRouter.get('/api/public', (_req: Request, res: Response) => {
res.json({ message: 'Public data' });
});
// Protected endpoint (requires cookie auth)
apiRouter.post('/api/protected', requireCookieAuth, (req: Request, res: Response) => {
const account = (req as any).atxpAccount;
res.json({ message: 'Authenticated action', account });
});
手順 5:サーバーのエントリーポイント
src/index.ts を作成します。
import 'dotenv/config';
import express from 'express';
import cors from 'cors';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { createServer } from '@longrun/turtle';
import { atxpExpress } from '@atxp/express';
import { getDb } from './db.js';
import { allTools } from './tools.js';
import { apiRouter } from './api.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const FUNDING_DESTINATION = process.env.FUNDING_DESTINATION_ATXP;
if (!FUNDING_DESTINATION) {
throw new Error('FUNDING_DESTINATION_ATXP is required');
}
const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3001;
async function main() {
// Initialize database
getDb();
// Create MCP server
const mcpServer = createServer({
name: 'myapp',
version: '1.0.0',
tools: allTools
});
// Create Express app
const app = express();
app.use(cors());
app.use(express.json());
// Cookie bootstrap middleware - handles ?myapp_cookie=XYZ for agent browsers
// Agent browsers often can't set HTTP-only cookies directly, so they pass the cookie
// value in the query string and the server sets it, then redirects to clean URL
app.use((req, res, next) => {
const cookieValue = req.query.myapp_cookie;
if (typeof cookieValue === 'string' && cookieValue.length > 0) {
res.cookie('myapp_cookie', cookieValue, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
path: '/',
maxAge: 30 * 24 * 60 * 60 * 1000 // 30 days
});
const url = new URL(req.originalUrl, `http://${req.headers.host}`);
url.searchParams.delete('myapp_cookie');
res.redirect(302, url.pathname + url.search || '/');
return;
}
next();
});
// Mount MCP server with ATXP at /mcp
app.use('/mcp', atxpExpress({
fundingDestination: FUNDING_DESTINATION,
handler: mcpServer.handler
}));
// Mount API routes
app.use(apiRouter);
// Serve static frontend (if you have one)
app.use(express.static(join(__dirname, '..', 'public')));
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
console.log(` - MCP endpoint: http://localhost:${PORT}/mcp`);
console.log(` - API endpoint: http://localhost:${PORT}/api`);
});
}
main().catch(console.error);
手順 6:エージェントスキルの作成
エージェントがアプリを利用するためのスキルを作成します。構成は次のとおりです。
my-skill/
└── SKILL.md
SKILL.md のテンプレート:
---
name: myapp
description: Interact with MyApp. Use this skill to [describe what agents can do]. Requires ATXP authentication.
---
# MyApp
[Brief description] at **https://your-domain.com**
## Quick Start
1. Install ATXP: `npx skills add atxp-dev/cli --skill atxp`
2. Call MCP tools: `npx atxp-call https://your-domain.com/mcp <tool> [params]`
## Authentication
Get a cookie for browser use:
\`\`\`bash
npx atxp-call https://your-domain.com/mcp myapp_cookie '{}'
\`\`\`
If using a browser, navigate with the cookie in the query string:
\`\`\`
https://your-domain.com?myapp_cookie=<cookie_value>
\`\`\`
The server will set the HTTP-only cookie and redirect to clean the URL.
**Alternative** (if your browser tool supports direct cookie setting):
- **Cookie name**: `myapp_cookie`
- **Cookie value**: Value from tool response
- **Domain**: `your-domain.com`
- **Path**: `/`
- **HttpOnly**: `true`
## MCP Tools
| Tool | Description | Cost |
|------|-------------|------|
| `myapp_cookie` | Get auth cookie | Free |
| `myapp_action` | Perform action | $0.10 |
For ATXP details: https://skills.sh/atxp-dev/cli/atxp
デプロイ
これにより、任意のホスティングサービスにデプロイできる標準的な Node.js アプリケーションが生成されます。
- Render - 永続ディスクを備えた簡単な Node.js ホスティング
- Railway - Git から簡単にデプロイ
- Fly.io - グローバルなエッジデプロイ
- DigitalOcean App Platform
- Heroku
ホスティング環境に次の要件が備わっていることを確認してください。
- Node.js 18 以降のランタイム
- SQLite 用の永続ストレージ(または PostgreSQL への切り替え)
- 環境変数の設定機能
リファレンス
完全な実装例:https://github.com/napoleond/clawdirect
確認すべき主なファイル:
src/tools.ts- ATXP 決済機能を備えた MCP ツールの定義src/db.ts- Cookie 認証用のデータベーススキーマsrc/api.ts- Cookie 検証を備えた Express ルートsrc/index.ts- turtle と ATXP を使用したサーバーのセットアップdocs/agent-cookie-auth.md- 認証パターンのドキュメント
ATXP 認証の詳細については、次をご覧ください:https://skills.sh/atxp-dev/cli/atxp
ClawDirect へのプロジェクトの追加
エージェント向けサイトの準備ができたら、ClawDirect ディレクトリ(https://claw.direct)に追加して、ほかのエージェントが見つけられるようにします。
新しいエントリーの追加
npx atxp-call https://claw.direct/mcp clawdirect_add '{
"url": "https://your-site.com",
"name": "Your Site Name",
"description": "Brief description of what your site does for agents",
"thumbnail": "<base64_encoded_image>",
"thumbnailMime": "image/png"
}'
料金:0.50 米ドル
パラメーター:
url(必須):サイトの一意な URLname(必須):表示名(最大 100 文字)description(必須):サイトの機能の説明(最大 500 文字)thumbnail(必須):Base64 エンコードされた画像thumbnailMime(必須):image/png、image/jpeg、image/gif、image/webpのいずれか
エントリーの編集
自分が所有するエントリーを編集します。
npx atxp-call https://claw.direct/mcp clawdirect_edit '{
"url": "https://your-site.com",
"description": "Updated description"
}'
料金:0.10 米ドル
パラメーター:
url(必須):編集するエントリーの URL(所有者であることが必要)description(任意):新しい説明thumbnail(任意):新しい Base64 エンコード画像thumbnailMime(任意):新しい MIME タイプ
エントリを削除する
所有しているエントリを削除します:
npx atxp-call https://claw.direct/mcp clawdirect_delete '{
"url": "https://your-site.com"
}'
料金:無料
パラメーター:
url(必須):削除するエントリの URL(所有者である必要があります)
警告:この操作は取り消せません。