mcpField
C
clawdirect-dev

clawdirect-dev

github.com/napoleond开发14.6k 次安装38 周前更新
代码仓库

关于 clawdirect-dev

ClawDirect-Dev 是面向开发者的指南,介绍如何使用 ATXP 认证构建面向 AI Agent 的网站体验。内容涵盖 MCP 服务、基于 Cookie 的浏览器认证、Express API 和 Agent 技能。

主要功能

  1. 01ATXP 认证架构
  2. 02MCP 服务与 Cookie 工具配置
  3. 03基于 Cookie 的浏览器认证
  4. 04Express API 与 Cookie 验证
  5. 05Agent 技能和部署指南

适用场景

  1. 01构建面向 AI Agent 的网站服务
  2. 02将 MCP 认证衔接到浏览器会话
  3. 03为面向 Agent 的操作添加 ATXP 支付

MCP 相关

指南介绍如何在网站旁构建 MCP 服务,包含用于 Agent 认证和程序化操作的 Cookie 工具。Agent 可通过 MCP 获取 Cookie,并在浏览网站时使用。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/napoleond/clawdirect --skill clawdirect-dev

安装后在 Claude Code 中输入/clawdirect-dev确认已加载。

详细介绍

ClawDirect-Dev

使用基于 ATXP 的身份验证,构建面向 Agent 的 Web 体验。

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

什么是 ATXP?

ATXP(Agent Transaction Protocol,Agent 交易协议)支持 AI Agent 对服务进行身份验证和付款。构建面向 Agent 的网站时,ATXP 可提供:

  • Agent 身份:识别发出请求的 Agent
  • 付款:为高级操作收费(可选)
  • MCP 集成:公开 Agent 可通过编程方式调用的工具

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

Agent 如何与网站交互

Agent 可以通过两种方式与网站交互:

  1. 浏览器:Agent 使用浏览器自动化工具访问网站、点击按钮、填写表单和浏览页面,就像人类一样
  2. MCP 工具:Agent 直接调用 MCP 端点,以编程方式执行操作(身份验证、付款等)

基于 Cookie 的身份验证模式将这两种方式衔接起来:Agent 通过 MCP 获取身份验证 Cookie,然后在浏览网站时使用它。

重要提示:Agent 浏览器通常无法直接设置仅限 HTTP 的 Cookie。建议的模式是让 Agent 在查询字符串中传递 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  │                                │
│              └─────────────────┘                                │
└─────────────────────────────────────────────────────────────────┘

构建步骤

  1. 创建 MCP 服务,与网站并行运行
  2. 在 MCP 服务中实现 Cookie 工具
  3. 在 Web API 中使用 Cookie 进行身份验证
  4. 为网站发布 Agent 技能

步骤 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:创建 Agent 技能

创建供 Agent 与应用交互的技能。结构如下:

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 应用,可部署到任何托管服务:

确保托管服务提供:

  • 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

面向 Agent 的网站准备就绪后,请将其添加到 https://claw.direct 上的 ClawDirect 目录,方便其他 Agent 发现。

添加新条目
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(必需):网站的唯一 URL
  • name(必需):显示名称(最多 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(必须是所有者)

警告:此操作不可逆。

评论

支持 Markdown