diff --git a/.github/actions/generate-mcp-tools/generate-tools.mjs b/.github/actions/generate-mcp-tools/generate-tools.mjs new file mode 100644 index 0000000..20ace7e --- /dev/null +++ b/.github/actions/generate-mcp-tools/generate-tools.mjs @@ -0,0 +1,156 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { zodToJsonSchema } from "zod-to-json-schema"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const ROOT = path.resolve(__dirname, "../../.."); +const README_PATH = path.join(ROOT, "README.md"); +const TOOLS_DIR = path.join(ROOT, "src", "tools"); + +const START = ""; +const END = ""; + +/** + * Load MCP tools + * Scans for any export that looks like an MCP tool: + * { + * name: string, + * description: string, + * parameters?: ZodSchema + * schema?: JSONSchema + * } + */ +async function loadTools() { + const files = fs + .readdirSync(TOOLS_DIR) + .filter((f) => f.endsWith(".ts") && f !== "index.ts"); + + const toolPromises = files.map(async (file) => { + const mod = await import(path.join(TOOLS_DIR, file)); + + const matches = Object.values(mod).filter( + (exp) => + exp && + typeof exp === "object" && + typeof exp.name === "string" && + typeof exp.description === "string" && + (exp.parameters || exp.schema), + ); + + if (matches.length === 0) { + return null; + } + + if (matches.length > 1) { + console.warn( + `Warning: ${file} exports multiple MCP-like tools. Using the first one.`, + ); + } + + return matches[0]; + }); + + const loadedTools = await Promise.all(toolPromises); + const tools = loadedTools.filter(Boolean); + + return tools.sort((a, b) => a.name.localeCompare(b.name)); +} + +function renderSchema(schema) { + if (!schema) { + return "_No parameters_"; + } + + // If this is a Zod schema, convert it to JSON Schema + const jsonSchema = + typeof schema.safeParse === "function" ? zodToJsonSchema(schema) : schema; + + const properties = jsonSchema.properties ?? {}; + const required = new Set(jsonSchema.required ?? []); + + if (Object.keys(properties).length === 0) { + return "_No parameters_"; + } + + // Check if any param has a default value to determine table columns + const hasDefaults = Object.values(properties).some( + (prop) => prop.default !== undefined, + ); + + // Build table header + let table = hasDefaults + ? "| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n" + : "| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n"; + + // Build table rows + for (const [key, prop] of Object.entries(properties)) { + const type = Array.isArray(prop.type) + ? prop.type.join(" | ") + : (prop.type ?? "unknown"); + + const requiredStr = required.has(key) ? "โœ…" : ""; + const description = prop.description ?? ""; + const defaultVal = + prop.default !== undefined ? JSON.stringify(prop.default) : ""; + + if (hasDefaults) { + table += `| \`${key}\` | ${type} | ${requiredStr} | ${defaultVal} | ${description} |\n`; + } else { + table += `| \`${key}\` | ${type} | ${requiredStr} | ${description} |\n`; + } + } + + return table.trim(); +} + +function renderMarkdown(tools) { + let md = ""; + + for (const tool of tools) { + const schema = tool.parameters || tool.schema; + + md += `### \`${tool.name}\`\n`; + md += `${tool.description}\n\n`; + md += `${renderSchema(schema)}\n\n`; + } + + return md.trim(); +} + +function updateReadme({ readme, tools }) { + if (!readme.includes(START) || !readme.includes(END)) { + throw new Error("README missing AUTO-GENERATED TOOLS markers"); + } + + const toolsMd = renderMarkdown(tools); + + return readme.replace( + new RegExp(`${START}[\\s\\S]*?${END}`, "m"), + `${START}\n\n${toolsMd}\n\n${END}`, + ); +} + +async function main() { + try { + const readme = fs.readFileSync(README_PATH, "utf8"); + const tools = await loadTools(); + + if (tools.length === 0) { + console.warn("Warning: No tools found!"); + } + + const updated = updateReadme({ readme, tools }); + + fs.writeFileSync(README_PATH, updated); + console.log(`Synced ${tools.length} MCP tools to README.md`); + } catch (error) { + console.error("Error updating README:", error); + process.exit(1); + } +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 0000000..12fb746 --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,39 @@ +name: Push checks (Template - Manual Trigger) + +# To enable, change to e.g.: on: [push] +on: workflow_dispatch + +jobs: + Checkout: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 22.0.0 + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + - name: Install dependencies + run: pnpm install --frozen-lockfile + - name: Build project + run: pnpm run build + - name: Biome Lint Check + run: pnpm run lint diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..aa3d5b9 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,53 @@ +name: Release (Template - Manual Trigger) + +# To enable, change to e.g.: +# on: +# push: +# branches: +# - main +on: workflow_dispatch + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 22.0.0 + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + run_install: false + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install Dependencies + run: pnpm install --frozen-lockfile + + - name: Create Release Pull Request or Publish to npm + id: changesets + uses: changesets/action@v1 + with: + publish: pnpm run publish-packages + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/sync-tools.yml b/.github/workflows/sync-tools.yml new file mode 100644 index 0000000..81f62f4 --- /dev/null +++ b/.github/workflows/sync-tools.yml @@ -0,0 +1,47 @@ +name: Sync MCP Tool Docs + +on: + push: + branches: + - main + +permissions: + contents: write + +jobs: + sync-tools: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install dependencies + run: | + if [ -f pnpm-lock.yaml ]; then + corepack enable + pnpm install --frozen-lockfile + else + npm install + fi + + - name: Generate MCP tool documentation + run: npx tsx .github/actions/generate-mcp-tools/generate-tools.mjs + + - name: Commit README changes + run: | + if git diff --quiet; then + echo "No README changes" + exit 0 + fi + + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add README.md + git commit -m "chore: auto-sync MCP tool documentation" + git push diff --git a/README.md b/README.md index 36af467..2818a7c 100644 --- a/README.md +++ b/README.md @@ -1,71 +1,34 @@ -# Limitless MCP Server +# ๐ŸŽฏ Limitless MCP Server [![npm version](https://img.shields.io/npm/v/@iqai/mcp-limitless.svg)](https://www.npmjs.com/package/@iqai/mcp-limitless) [![CI](https://github.com/IQAIcom/mcp-limitless/actions/workflows/ci.yml/badge.svg)](https://github.com/IQAIcom/mcp-limitless/actions/workflows/ci.yml) [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC) -A Model Context Protocol (MCP) server for interacting with [Limitless](https://limitless.exchange) prediction markets. This server provides tools for market discovery, portfolio management, and trading, enabling AI agents to interact with prediction markets seamlessly. +## ๐Ÿ“– Overview -## Features +The Limitless MCP Server enables AI agents to interact with [Limitless](https://limitless.exchange) prediction markets. This server provides comprehensive tools for market discovery, portfolio management, and trading, enabling AI agents to interact with prediction markets seamlessly. -### Authentication Tools (5 tools) -- **GET_AUTH_STATUS**: Check current authentication status -- **GET_SIGNING_MESSAGE**: Get a signing message with nonce for wallet authentication -- **VERIFY_AUTH**: Verify if the user is authenticated -- **LOGIN**: Authenticate a user with a signed message and create a session -- **LOGOUT**: Log out the user by clearing the session cookie - -### Market Data Tools (13 tools) -- **SEARCH_MARKETS**: Search for prediction markets using semantic similarity -- **GET_MARKET**: Get detailed information about a specific market by slug or address -- **GET_ACTIVE_MARKETS**: Browse active (unresolved) markets with optional filtering -- **GET_ACTIVE_MARKETS_BY_CATEGORY**: Browse active markets filtered by category ID -- **GET_CATEGORIES**: Get all available categories -- **GET_CATEGORIES_COUNT**: Get the number of active markets for each category -- **GET_ACTIVE_SLUGS**: Get slugs, strike prices, tickers, and deadlines for all active markets -- **GET_MARKET_ORDERBOOK**: View current orderbook with bids and asks -- **GET_HISTORICAL_PRICE**: Retrieve historical price data with configurable time intervals -- **GET_FEED_EVENTS**: Get the latest feed events for a specific market -- **GET_MARKET_EVENTS**: Get recent market events including trades and orders -- **GET_LOCKED_BALANCE**: Get funds locked in open orders (requires authentication) -- **GET_USER_ORDERS**: Get all user orders for a specific market (requires authentication) +By implementing the Model Context Protocol (MCP), this server allows Large Language Models (LLMs) to discover prediction markets, execute trades, manage portfolios, and track market activity directly through their context window, bridging the gap between AI and decentralized prediction markets. -### Portfolio Tools (8 tools) -- **GET_PORTFOLIO_POSITIONS**: Get user portfolio positions with P&L calculations -- **GET_PORTFOLIO_TRADES**: Retrieve all trades executed by the user -- **GET_PORTFOLIO_HISTORY**: Get paginated history including AMM/CLOB trades, splits/merges -- **GET_PORTFOLIO_POINTS**: Get points breakdown for the user -- **GET_USER_TRADED_VOLUME**: Get total traded volume for a specific user address (public) -- **GET_PUBLIC_USER_POSITIONS**: Get all positions for a specific user address (public) -- **GET_USER_PROFILE**: Get detailed user profile information -- **GET_TRADING_ALLOWANCE**: Check USDC allowance for CLOB or NegRisk trading +## โœจ Features -### Trading Tools (4 tools) -- **CREATE_ORDER**: Create a buy or sell order for prediction market positions -- **CANCEL_ORDER**: Cancel a specific open order by order ID -- **CANCEL_ORDER_BATCH**: Cancel multiple orders in a single batch operation -- **CANCEL_ALL_ORDERS**: Cancel all user orders in a specific market +* **Market Discovery**: Search and filter prediction markets by category, keywords, and activity. +* **Real-time Pricing**: Access live price data, order books, and historical price information. +* **Portfolio Tracking**: Monitor user positions, trade history, points, and P&L calculations. +* **Trading**: Create, cancel, and manage orders for prediction market positions. +* **Authentication**: Secure wallet-based authentication with session management. -## Quick Start +## ๐Ÿ“ฆ Installation -### Using with npx (Recommended) +### ๐Ÿš€ Using npx (Recommended) -The easiest way to use this MCP server is with `npx`: +To use this server without installing it globally: -```json -{ - "mcpServers": { - "limitless": { - "command": "npx", - "args": ["@iqai/mcp-limitless"] - } - } -} +```bash +npx @iqai/mcp-limitless ``` -No API key required for read-only operations. Authentication is handled via wallet signature for trading. - -### Manual Installation (For Development) +### ๐Ÿ”ง Build from Source ```bash git clone https://github.com/IQAIcom/mcp-limitless @@ -74,22 +37,26 @@ pnpm install pnpm run build ``` -## Configuration - -### Environment Variables +## โšก Running with an MCP Client -| Variable | Required | Description | -|----------|----------|-------------| -| None | - | No environment variables required for read-only operations | +Add the following configuration to your MCP client settings (e.g., `claude_desktop_config.json`). -Authentication is handled via wallet signature flow (GET_SIGNING_MESSAGE โ†’ LOGIN). +### ๐Ÿ“‹ Minimal Configuration -### For Claude Desktop +```json +{ + "mcpServers": { + "limitless": { + "command": "npx", + "args": ["@iqai/mcp-limitless"] + } + } +} +``` -Add to your Claude Desktop configuration: +No API key required for read-only operations. Authentication is handled via wallet signature for trading. -**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` -**Windows**: `%APPDATA%\Claude\claude_desktop_config.json` +### โš™๏ธ Advanced Configuration (Local Build) ```json { @@ -102,96 +69,86 @@ Add to your Claude Desktop configuration: } ``` -## How It Works - -This MCP server acts as a bridge between AI assistants and the Limitless prediction market API: - -``` -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ MCP Client โ”‚ โ† AI Assistant (Claude, IDE extensions, etc.) -โ”‚ (Claude AI) โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ Tool Calls (standardized MCP protocol) - โ–ผ -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ MCP Server โ”‚ โ† This project -โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ -โ”‚ โ”‚ 30 Tools โ”‚ โ”‚ โ† Search markets, create orders, etc. -โ”‚ โ”‚ Session โ”‚ โ”‚ โ† Automatic cookie-based authentication -โ”‚ โ”‚ Manager โ”‚ โ”‚ โ† Persists login across requests -โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ HTTP/REST API calls (with automatic cookies) - โ–ผ -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ Limitless API โ”‚ โ† Limitless Exchange backend -โ”‚ api.limitless โ”‚ -โ”‚ .exchange โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` - -**Key Features:** -- **Automatic Session Management**: Login once, stay authenticated for the entire session -- **No API Keys Required**: Uses wallet signature authentication -- **Type-Safe**: Full TypeScript with Zod schema validation -- **Browser-Like UX**: Cookies handled automatically using `tough-cookie` - -## Usage Examples +**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` +**Windows**: `%APPDATA%\Claude\claude_desktop_config.json` -### Sample Questions for AI Agents +## ๐Ÿ” Configuration (Environment Variables) -**Market Discovery:** -- "What prediction markets are currently active on Limitless?" -- "Search for crypto-related markets" -- "Show me the top markets by volume" -- "Get the order book for the Bitcoin $100k market" +| Variable | Required | Description | Default | +| :--- | :--- | :--- | :--- | +| None | - | No environment variables required for read-only operations | - | -**Portfolio Management:** -- "Show me my portfolio positions" -- "What's my P&L on open positions?" -- "List my recent trades" +Authentication is handled via wallet signature flow (GET_SIGNING_MESSAGE โ†’ LOGIN). -**Trading:** -- "Place a buy order for 50 shares at 60 cents" -- "Cancel all my orders in this market" -- "Show me my open orders" +## ๐Ÿ’ก Usage Examples -### Conversation Example +### ๐Ÿ” Market Discovery +* "What prediction markets are currently active on Limitless?" +* "Search for crypto-related markets" +* "Show me the top markets by volume" +* "Get the order book for the Bitcoin $100k market" -``` -You: "Show me the top 5 crypto prediction markets on Limitless" +### ๐Ÿ“Š Analytics & Pricing +* "Get the historical price data for this market" +* "Show me the current orderbook with bids and asks" +* "What are the feed events for this market?" -Claude: [Uses SEARCH_MARKETS tool] -โ†’ Here are the top 5 crypto markets: - 1. Will Bitcoin reach $100k in 2025? (75% YES) - 2. Will Ethereum surpass $5000? (62% YES) - ... +### ๐Ÿ’ผ Portfolio Management +* "Show me my portfolio positions" +* "What's my P&L on open positions?" +* "List my recent trades" +* "Check my points breakdown" -You: "Check if I'm logged into Limitless" +### ๐Ÿ’ฐ Trading +* "Place a buy order for 50 shares at 60 cents" +* "Cancel all my orders in this market" +* "Show me my open orders" -Claude: [Uses GET_AUTH_STATUS tool] -โ†’ You're not currently authenticated. Would you like to log in? +## ๐Ÿ› ๏ธ MCP Tools -You: "Yes, log me in. My address is 0x742d35Cc..." + -Claude: [Uses GET_SIGNING_MESSAGE tool] -โ†’ Please sign this message with your wallet: - "Welcome to Limitless.exchange!..." +### Authentication Tools (5 tools) +- **GET_AUTH_STATUS**: Check current authentication status +- **GET_SIGNING_MESSAGE**: Get a signing message with nonce for wallet authentication +- **VERIFY_AUTH**: Verify if the user is authenticated +- **LOGIN**: Authenticate a user with a signed message and create a session +- **LOGOUT**: Log out the user by clearing the session cookie -You: "Here's my signature: 0xabc123..." +### Market Data Tools (13 tools) +- **SEARCH_MARKETS**: Search for prediction markets using semantic similarity +- **GET_MARKET**: Get detailed information about a specific market by slug or address +- **GET_ACTIVE_MARKETS**: Browse active (unresolved) markets with optional filtering +- **GET_ACTIVE_MARKETS_BY_CATEGORY**: Browse active markets filtered by category ID +- **GET_CATEGORIES**: Get all available categories +- **GET_CATEGORIES_COUNT**: Get the number of active markets for each category +- **GET_ACTIVE_SLUGS**: Get slugs, strike prices, tickers, and deadlines for all active markets +- **GET_MARKET_ORDERBOOK**: View current orderbook with bids and asks +- **GET_HISTORICAL_PRICE**: Retrieve historical price data with configurable time intervals +- **GET_FEED_EVENTS**: Get the latest feed events for a specific market +- **GET_MARKET_EVENTS**: Get recent market events including trades and orders +- **GET_LOCKED_BALANCE**: Get funds locked in open orders (requires authentication) +- **GET_USER_ORDERS**: Get all user orders for a specific market (requires authentication) -Claude: [Uses LOGIN tool] -โ†’ โœ… Successfully logged in as 0x742d35Cc... +### Portfolio Tools (8 tools) +- **GET_PORTFOLIO_POSITIONS**: Get user portfolio positions with P&L calculations +- **GET_PORTFOLIO_TRADES**: Retrieve all trades executed by the user +- **GET_PORTFOLIO_HISTORY**: Get paginated history including AMM/CLOB trades, splits/merges +- **GET_PORTFOLIO_POINTS**: Get points breakdown for the user +- **GET_USER_TRADED_VOLUME**: Get total traded volume for a specific user address (public) +- **GET_PUBLIC_USER_POSITIONS**: Get all positions for a specific user address (public) +- **GET_USER_PROFILE**: Get detailed user profile information +- **GET_TRADING_ALLOWANCE**: Check USDC allowance for CLOB or NegRisk trading -You: "Show me my portfolio positions" +### Trading Tools (4 tools) +- **CREATE_ORDER**: Create a buy or sell order for prediction market positions +- **CANCEL_ORDER**: Cancel a specific open order by order ID +- **CANCEL_ORDER_BATCH**: Cancel multiple orders in a single batch operation +- **CANCEL_ALL_ORDERS**: Cancel all user orders in a specific market -Claude: [Uses GET_PORTFOLIO_POSITIONS tool] -โ†’ ๐Ÿ’ผ Your Portfolio: - 1. Bitcoin $100k (YES) - 100 shares @ $0.65 - Current: $0.75 | P&L: +$10.00 (+15.38%) -``` + -## Authentication +## ๐Ÿ” Authentication Many tools require authentication. This server implements **automatic session management** using HTTP cookies, just like a web browser. @@ -252,25 +209,19 @@ Step 5: Use Authenticated Tools - GET_SIGNING_MESSAGE - GET_AUTH_STATUS -## API Documentation - -This server uses the Limitless API: -- **Base URL**: `https://api.limitless.exchange` -- [Limitless Exchange](https://limitless.exchange/) - -## Development +## ๐Ÿ‘จโ€๐Ÿ’ป Development -### Build +### ๐Ÿ—๏ธ Build Project ```bash pnpm run build ``` -### Development Mode +### ๐Ÿ‘๏ธ Development Mode (Watch) ```bash pnpm run watch ``` -### Run Tests +### ๐Ÿงช Run Tests ```bash pnpm test:unit # Run unit tests pnpm test:watch # Watch mode @@ -278,64 +229,39 @@ pnpm test:coverage # Generate coverage report pnpm test:integration # Run integration tests ``` -### Linting and Formatting +### โœ… Linting & Formatting ```bash pnpm run lint pnpm run format ``` -## Project Structure - -``` -mcp-limitless/ -โ”œโ”€โ”€ src/ -โ”‚ โ”œโ”€โ”€ lib/ -โ”‚ โ”‚ โ”œโ”€โ”€ client.ts # HTTP client -โ”‚ โ”‚ โ”œโ”€โ”€ session-manager.ts # Cookie-based session management -โ”‚ โ”‚ โ””โ”€โ”€ logger.ts # Winston logger -โ”‚ โ”œโ”€โ”€ services/ -โ”‚ โ”‚ โ”œโ”€โ”€ search-markets.ts -โ”‚ โ”‚ โ”œโ”€โ”€ get-market.ts -โ”‚ โ”‚ โ”œโ”€โ”€ get-portfolio-positions.ts -โ”‚ โ”‚ โ””โ”€โ”€ ... # One service per tool -โ”‚ โ”œโ”€โ”€ tools/ -โ”‚ โ”‚ โ”œโ”€โ”€ search-markets.ts -โ”‚ โ”‚ โ”œโ”€โ”€ get-market.ts -โ”‚ โ”‚ โ””โ”€โ”€ ... # One tool definition per feature -โ”‚ โ””โ”€โ”€ index.ts # MCP server entry point -โ”œโ”€โ”€ tests/ -โ”‚ โ”œโ”€โ”€ unit/ # Unit tests -โ”‚ โ””โ”€โ”€ integration/ # Integration tests -โ”œโ”€โ”€ dist/ # Compiled output -โ”œโ”€โ”€ package.json -โ””โ”€โ”€ README.md -``` +### ๐Ÿ“ Project Structure +* `src/tools/`: Individual tool definitions +* `src/services/`: API client and business logic +* `src/lib/`: Shared utilities (HTTP client, session manager, logger) +* `src/index.ts`: Server entry point +* `tests/`: Unit and integration tests -## Technologies +## ๐Ÿ“š Resources -- **TypeScript**: Type-safe development -- **fastmcp**: MCP server implementation -- **tough-cookie**: Cookie management for session persistence -- **fetch-cookie**: HTTP client with automatic cookie handling -- **Winston**: Logging -- **Zod**: Parameter validation -- **Biome**: Linting and formatting -- **Vitest**: Testing framework +* [Limitless Exchange](https://limitless.exchange/) +* [Limitless API](https://api.limitless.exchange) +* [Model Context Protocol (MCP)](https://modelcontextprotocol.io) -## Disclaimer +## โš ๏ธ Disclaimer -This is an unofficial tool and is not affiliated with Limitless. Use at your own risk. Always verify transactions and understand the risks involved in prediction market trading. +This project is an unofficial tool and is not directly affiliated with Limitless. It interacts with financial and prediction market data. Users should exercise caution and verify all data independently. Trading in prediction markets involves risk. -## Related Projects +## ๐Ÿ”— Related Projects - [Polymarket MCP](https://github.com/IQAIcom/mcp-polymarket) - MCP server for Polymarket - [Kalshi MCP](https://github.com/IQAIcom/mcp-kalshi) - MCP server for Kalshi - [Opinion MCP](https://github.com/IQAIcom/mcp-opinion) - MCP server for Opinion -## Contributing +## ๐Ÿค Contributing Contributions are welcome! Please read our [Contributing Guide](.github/CONTRIBUTING.md) for details. -## License +## ๐Ÿ“„ License -ISC +[ISC](LICENSE)