🚀 快速安装

复制以下命令并运行,立即安装此 Skill:

npx @anthropic-ai/skills install napoleond/clawdirect/clawdirect-dev

💡 提示:需要 Node.js 和 NPM

ClawDirect-Dev

构建基于 ATXP 认证的、面向代理的 Web 体验。

参考实现https://github.com/napoleond/clawdirect

什么是 ATXP?

ATXP(代理交易协议)使 AI 代理能够进行身份认证并为服务付费。在构建面向代理的网站时,ATXP 提供:

  • 代理身份:识别是哪个代理在发起请求
  • 支付:为高级操作收费(可选)
  • MCP 集成:公开代理可以程序化调用的工具

完整的 ATXP 详情:https://skills.sh/atxp-dev/cli/atxp

代理如何交互

代理通过两种方式与您的网站交互:

  1. 浏览器:代理使用浏览器自动化工具访问您的网站、点击按钮、填写表单和导航——就像人类一样
  2. MCP 工具:代理直接调用您的 MCP 端点执行程序化操作(认证、支付等)

基于 cookie 的认证模式桥接了这两种方式:代理通过 MCP 获取认证 cookie,然后在浏览时使用它。

重要提示:代理浏览器通常无法直接设置 HTTP-only cookie。推荐的做法是代理在查询字符串中传递 cookie 值(例如 ?myapp_cookie=XYZ),然后由服务器设置 cookie 并重定向到一个干净的 URL。

架构概览

┌──────────────────────────────────────────────────────────────────┐
│                          AI 代理                                  │
│  ┌─────────────────────┐         ┌─────────────────────────┐     │
│  │   浏览器工具          │         │   MCP 客户端             │     │
│  │   (访问网站)        │         │   (调用工具)            │     │
│  └─────────┬───────────┘         └───────────┬─────────────┘     │
└────────────┼─────────────────────────────────┼────────────────-──┘
             │                                 │
             ▼                                 ▼
┌────────────────────────────────────────────────────────────────┐
│                     您的应用程序                                 │
│  ┌─────────────────────┐    ┌─────────────────────────┐        │
│  │   Web 服务器         │    │   MCP 服务器             │        │
│  │   (Express)         │    │   (@longrun/turtle)     │        │
│  │                     │    │                         │        │
│  │   - 提供 UI          │    │   - yourapp_cookie      │        │
│  │   - Cookie 认证      │    │   - yourapp_action      │        │
│  └─────────┬───────────┘    └───────────┬─────────────┘        │
│            │                            │                      │
│            └──────────┬─────────────────┘                      │
│                       ▼                                        │
│              ┌─────────────────┐                               │
│              │     SQLite      │                               │
│              │   auth_cookies  │                               │
│              └─────────────────┘                               │
└────────────────────────────────────────────────────────────────┘

构建步骤

  1. 在您的网站旁边创建 MCP 服务器
  2. 在 MCP 服务器中实现 cookie 工具
  3. 在您的 Web API 中使用 cookie 进行认证
  4. 为您的网站发布一个代理技能

步骤 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=<您的_atxp_账户>
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');

    // 认证 cookies 表 - 将 cookies 映射到 ATXP 账户
    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
      )
    `);

    // 在这里添加您的应用表
  }
  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 工具 - 代理调用此工具获取浏览器认证
export const cookieTool = defineTool(
  'myapp_cookie',  // 将 'myapp' 替换为您的应用名称
  '获取用于浏览器使用的认证 cookie。设置此 cookie 以在使用 Web 界面时进行身份认证。',
  z.object({}),
  async () => {
    // 免费但需要 ATXP 认证
    const accountId = atxpAccountId();
    if (!accountId) {
      throw new Error('需要认证');
    }

    const cookie = createAuthCookie(accountId);

    return JSON.stringify({
      cookie,
      instructions: '要在浏览器中进行认证,请导航到 https://your-domain.com?myapp_cookie=<cookie_value> - 服务器将设置 HTTP-only cookie 并重定向。或者,如果您的浏览器工具支持,也可以直接设置 cookie。'
    });
  }
);

// 示例付费工具
export const paidActionTool = defineTool(
  'myapp_action',
  '执行某个操作。费用:$0.10',
  z.object({
    input: z.string().describe('操作的输入')
  }),
  async ({ input }) => {
    await requirePayment({ price: new BigNumber(0.10) });

    const accountId = atxpAccountId();
    if (!accountId) {
      throw new Error('需要认证');
    }

    // 您的操作逻辑
    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();

// 辅助函数提取 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;
}

// 中间件:要求 Cookie 认证
function requireCookieAuth(req: Request, res: Response, next: Function) {
  const cookieValue = getCookieValue(req, 'myapp_cookie');

  if (!cookieValue) {
    res.status(401).json({
      error: '需要认证',
      message: '请使用 myapp_cookie MCP 工具获取认证 cookie'
    });
    return;
  }

  const atxpAccount = getAtxpAccountFromCookie(cookieValue);
  if (!atxpAccount) {
    res.status(401).json({
      error: '无效的 cookie',
      message: '您的 cookie 无效或已过期。请通过 MCP 工具获取一个新的。'
    });
    return;
  }

  // 将账户附加到请求上,供处理程序使用
  (req as any).atxpAccount = atxpAccount;
  next();
}

// 公共端点(无需认证)
apiRouter.get('/api/public', (_req: Request, res: Response) => {
  res.json({ message: '公共数据' });
});

// 受保护端点(需要 Cookie 认证)
apiRouter.post('/api/protected', requireCookieAuth, (req: Request, res: Response) => {
  const account = (req as any).atxpAccount;
  res.json({ message: '已认证的操作', 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 是必需的');
}

const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3001;

async function main() {
  // 初始化数据库
  getDb();

  // 创建 MCP 服务器
  const mcpServer = createServer({
    name: 'myapp',
    version: '1.0.0',
    tools: allTools
  });

  // 创建 Express 应用
  const app = express();
  app.use(cors());
  app.use(express.json());

  // Cookie 引导中间件 - 处理代理浏览器传递的 ?myapp_cookie=XYZ
  // 代理浏览器通常无法直接设置 HTTP-only cookie,所以它们在查询字符串中传递 cookie
  // 值,然后由服务器设置 cookie,并重定向到干净的 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 天
      });
      const url = new URL(req.originalUrl, `http://${req.headers.host}`);
      url.searchParams.delete('myapp_cookie');
      res.redirect(302, url.pathname + url.search || '/');
      return;
    }
    next();
  });

  // 在 /mcp 路径挂载带 ATXP 的 MCP 服务器
  app.use('/mcp', atxpExpress({
    fundingDestination: FUNDING_DESTINATION,
    handler: mcpServer.handler
  }));

  // 挂载 API 路由
  app.use(apiRouter);

  // 提供静态前端(如果有的话)
  app.use(express.static(join(__dirname, '..', 'public')));

  app.listen(PORT, () => {
    console.log(`服务器运行在端口 ${PORT}`);
    console.log(`  - MCP 端点:http://localhost:${PORT}/mcp`);
    console.log(`  - API 端点:http://localhost:${PORT}/api`);
  });
}

main().catch(console.error);

步骤 6:创建代理技能

为代理创建一个与您的应用交互的技能。结构:

my-skill/
└── SKILL.md

SKILL.md 模板

---
name: myapp
description: 与 MyApp 交互。使用此技能来[描述代理可以做什么]。需要 ATXP 认证。
---

# MyApp

[简要描述] 位于 **https://your-domain.com**

## 快速开始

1. 安装 ATXP:`npx skills add atxp-dev/cli --skill atxp`
2. 调用 MCP 工具:`npx atxp-call https://your-domain.com/mcp <工具名称> [参数]`

## 认证

获取用于浏览器使用的 cookie:

\`\`\`bash
npx atxp-call https://your-domain.com/mcp myapp_cookie '{}'
\`\`\`

如果使用浏览器,请在查询字符串中带上 cookie 进行导航:

\`\`\`
https://your-domain.com?myapp_cookie=<cookie_value>
\`\`\`

服务器将设置 HTTP-only cookie 并重定向以清理 URL。

**替代方案**(如果您的浏览器工具支持直接设置 cookie):
- **Cookie 名称**`myapp_cookie`
- **Cookie 值**:工具响应中的值
- **域名**`your-domain.com`
- **路径**`/`
- **HttpOnly**`true`

## MCP 工具

| 工具 | 描述 | 费用 |
|------|-------------|------|
| `myapp_cookie` | 获取认证 cookie | 免费 |
| `myapp_action` | 执行操作 | $0.10 |

有关 ATXP 详情:https://skills.sh/atxp-dev/cli/atxp

部署

这会生成一个标准的 Node.js 应用程序,可部署到任何托管服务:

确保您的托管服务提供:

  • 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": "您的站点名称",
  "description": "简要描述您的站点为代理做什么",
  "thumbnail": "<base64_encoded_image>",
  "thumbnailMime": "image/png"
}'

费用:$0.50 美元

参数

  • url(必需):站点的唯一 URL
  • name(必需):显示名称(最多 100 个字符)
  • description(必需):站点做什么(最多 500 个字符)
  • thumbnail(必需):Base64 编码的图片
  • thumbnailMime(必需):image/pngimage/jpegimage/gifimage/webp 之一

编辑您的条目

编辑您拥有的条目:

npx atxp-call https://claw.direct/mcp clawdirect_edit '{
  "url": "https://your-site.com",
  "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(必须是所有者)

警告:此操作不可逆。

📄 原始文档

完整文档(英文):

/napoleond/clawdirect/clawdirect-dev

💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。