> For the complete documentation index, see [llms.txt](https://docs.wildmeta.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.wildmeta.ai/trading-terminal/x402-support-and-extension/wildmeta-ai-skill-development-guide/quick-start.md).

# Quick Start

### **1. Initialize the Project**

```bash
mkdir my-trading-skill
cd my-trading-skill
npm init -y
```

### **2. Install Dependencies**

`package.json`:

```json
{
  "name": "my-trading-skill",
  "version": "1.0.0",
  "type": "module",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "dev": "node --watch server.js"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.0.0",
    "dotenv": "^16.6.1",
    "express": "^4.18.2"
  }
}
```

Install packages:

```bash
npm install
```

***

## **Core Implementation**

### **Base Server Structure**

```jsx
import express from 'express';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema
} from '@modelcontextprotocol/sdk/types.js';
import dotenv from 'dotenv';

dotenv.config();

const app = express();
app.use(express.json());

const PORT = process.env.PORT || 3015;
const TRADE_API_BASE = process.env.TRADE_API_BASE || 'https://test-dex-api.heima.network';

// Create MCP protocol handler
const mcpServer = new Server(
  {
    name: 'my-trading-skill',
    version: '1.0.0'
  },
  {
    capabilities: {
      tools: {}
    }
  }
);
```

***

## **Defining Trading Tools**

The Skill exposes abilities to the AI Agent through **Tools**.\
Example: *open position* tool.

```jsx
mcpServer.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: 'open_position',
        description: 'Open a position on the DEX. Requires skill_token authorization.',
        inputSchema: {
          type: 'object',
          properties: {
            skill_token: { type: 'string', description: 'WildMeta authorization token' },
            dex: { type: 'string', description: 'DEX identifier (e.g. hyperliquid)' },
            coin: { type: 'string', description: 'Trading asset (e.g. BTC, ETH)' },
            isBuy: { type: 'boolean', description: 'true=long, false=short' },
            limitPx: { type: 'string', description: 'Limit order price' },
            sz: { type: 'string', description: 'Position size' },
            orderType: { type: 'object', description: 'Order type configuration' }
          },
          required: ['skill_token', 'dex', 'coin', 'isBuy', 'sz']
        }
      }
    ]
  };
});
```

***

## **Tool Handler Implementation**

```jsx
mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  if (name === 'open_position') {
    return await handleOpenPosition(args);
  }

  throw new Error(`Unknown tool: ${name}`);
});
```

***

## **Trading Operations Implementation**

### **Open Position**

```jsx
async function handleOpenPosition(args) {
  const { skill_token, dex, coin, isBuy, limitPx, sz, orderType } = args;

  if (!skill_token) {
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          success: false,
          error: 'skill_token is required for authorization'
        })
      }]
    };
  }

  console.log(`📈 Open position: ${isBuy ? 'LONG' : 'SHORT'} ${sz} ${coin}`);

  try {
    const requestBody = {
      dex: dex || 'hyperliquid',
      coin,
      isBuy,
      limitPx: limitPx || '0',
      sz,
      orderType: orderType || {
        limit: { tif: 'Gtc' },
        trigger: { isMarket: false, triggerPx: '0', tpsl: '' }
      },
      cloid: `order_${Date.now()}`
    };

    const response = await fetch(`${TRADE_API_BASE}/openapi/trade/v1/open_position`, {
      method: 'POST',
      headers: {
        'X-Language': 'zh',
        'skill-token': skill_token,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(requestBody)
    });

    const data = await response.json();

    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          success: response.ok,
          order: requestBody,
          response: data
        })
      }]
    };
  } catch (error) {
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          success: false,
          error: error.message
        })
      }]
    };
  }
}
```

***

## **HTTP Endpoints**

The Skill must expose an HTTP endpoint for MCP communication:

```jsx
// MCP endpoint
app.all('/message', async (req, res) => {
  try {
    const transport = new StreamableHTTPServerTransport({
      sessionIdGenerator: undefined,
      enableJsonResponse: true
    });

    res.on('close', () => transport.close());

    await mcpServer.connect(transport);
    await transport.handleRequest(req, res, req.body);
  } catch (error) {
    console.error('Request error:', error);
    res.status(500).json({ error: error.message });
  }
});

// Health check endpoint
app.get('/health', (req, res) => {
  res.json({
    status: 'healthy',
    server: 'my-trading-skill',
    version: '1.0.0',
    timestamp: new Date().toISOString()
  });
});

app.listen(PORT, () => {
  console.log(`🚀 Skill service running on port ${PORT}`);
});
```

***

## **Authorization Mechanism**

### **Skill Token Workflow**

```
1. User initiates a request
2. Frontend detects that a Skill requires signature authorization
3. Frontend requests wallet signature from the user
4. AI Agent automatically injects skill_token into tool parameters
5. Skill uses the token to call the WildMeta DEX API
```

#### Notes

* `skill_token` is generated by WildMeta frontend via wallet signature
* AI Agent automatically injects the token into tool calls
* Skills *must* include this token when calling WildMeta DEX API

***

## **Security Best Practices**

### **1. Token Validation**

```jsx
if (!skill_token) {
  return {
    content: [{
      type: 'text',
      text: JSON.stringify({
        success: false,
        error: 'skill_token is required'
      })
    }]
  };
}
```

### **2. Risk Controls**

```jsx
const MAX_SIZE = {
  BTC: 0.01,
  ETH: 0.1
};

if (parseFloat(sz) > MAX_SIZE[coin]) {
  return {
    success: false,
    error: `Position size exceeds max limit for ${coin}: ${MAX_SIZE[coin]}`
  };
}
```

### **3. Logging**

```jsx
console.log(`📈 Open position: ${isBuy ? 'LONG' : 'SHORT'} ${sz} ${coin}`);
console.log(`🔑 Token: ${skill_token.substring(0, 20)}...`);
console.log('📤 Request body:', JSON.stringify(requestBody, null, 2));
console.log('📥 Response:', data);
```

### **4. Error Handling**

```jsx
try {
  // trading logic
} catch (error) {
  console.error('❌ Trading error:', error);
  return {
    content: [{
      type: 'text',
      text: JSON.stringify({
        success: false,
        error: error.message,
        timestamp: new Date().toISOString()
      })
    }]
  };
}
```

***

## **Testing**

Create a script: `test.sh`

```bash
#!/bin/bash

echo "=== Health Check ==="
curl -s http://localhost:3015/health | jq .

echo -e "\n=== List Tools ==="
curl -s -X POST http://localhost:3015/message \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list"
  }' | jq .

echo -e "\n=== Test Open Position (requires valid skill_token) ==="
curl -s -X POST http://localhost:3015/message \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "open_position",
      "arguments": {
        "skill_token": "test-token",
        "dex": "hyperliquid",
        "coin": "BTC",
        "isBuy": true,
        "sz": "0.001"
      }
    }
  }' | jq .
```

***

## **Full Example**

For a complete example, refer to:

`mcp-wildmeat-trader/server.js`

It includes:

* Full Skill server setup
* Multiple tools (open, close, cancel order)
* WildMeta DEX API integration
* Error handling
* Logging
* Security checks


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.wildmeta.ai/trading-terminal/x402-support-and-extension/wildmeta-ai-skill-development-guide/quick-start.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
