Skill: haveblue997/mcp-llm-inference (version 1.0.0)

--- name: mcp-llm-inference description: Anonymous LLM inference via L402 micropayments — chat completions, text generation, and model discovery. No API key, no signup, no KYC. Pay per request in sats. Use when agents need LLM access without accounts or identity. version: 1.0.0 metadata: openclaw: requires: bins: - npx env: - L402_API_BASE_URL emoji: 🧠 --- # LLM Inference (L402) Anonymous LLM inference — pay per request with Lightning sats. No API key, no signup. ## Setup ```json { "mcpServers": { "llm-inference": { "command": "npx", "args": ["-y", "@vbotholemu/mcp-llm-inference"], "env": { "L402_API_BASE_URL": "https://api.nautdev.com" } } } } ``` ## Tools ### `chat_completion` Multi-turn chat with message history. ### `generate_text` Single-prompt text generation. ### `list_models` Discover available models and pricing. ## Payment Powered by L402 micropayments over Lightning Network. Each request returns a Lightning invoice — pay it, get your response. ~10 sats per request. ## When to Use - Agents needing LLM access without API key management - Anonymous inference (no identity required) - Pay-as-you-go without billing portals - Agent-to-agent service consumption

path: README.md
content: # @blue-trianon/mcp-llm-inference

MCP tool for LLM inference — chat completions, text generation, and model discovery via the L402 API.

## Features

- Chat completions with multi-turn message history
- Single-prompt text generation
- List available models
- Optional streaming support
- Configurable base URL via environment variable
- Powered by L402 micropayments

## MCP Server Configuration

Add to your MCP client configuration:

```json
{
  "mcpServers": {
    "llm-inference": {
      "command": "npx",
      "args": ["-y", "@blue-trianon/mcp-llm-inference"],
      "env": {
        "NAUTDEV_BASE_URL": "https://api.nautdev.com"
      }
    }
  }
}
```

Or if installed globally:

```json
{
  "mcpServers": {
    "llm-inference": {
      "command": "mcp-llm-inference"
    }
  }
}
```

## Tools

### chat

Send a chat completion request to an LLM.

| Parameter | Type    | Required | Description                                    |
|-----------|---------|----------|------------------------------------------------|
| model     | string  | yes      | Model identifier (e.g. llama3, mistral, gemma) |
| messages  | array   | yes      | Array of {role, content} message objects        |
| stream    | boolean | no       | Stream the response (default: false)           |

### generate

Generate text from a single prompt.

| Parameter | Type    | Required | Description                                    |
|-----------|---------|----------|------------------------------------------------|
| model     | string  | yes      | Model identifier (e.g. llama3, mistral, gemma) |
| prompt    | string  | yes      | Text prompt for generation                     |
| stream    | boolean | no       | Stream the response (default: false)           |

### models

List all available LLM models.

No parameters required.

## Pricing

Requests are metered via L402 micropayments. See [Blue-Trianon-Ventures](https://github.com/Blue-Trianon-Ventures) for pricing details.

## License

MIT


path: dist/index.d.ts
content: #!/usr/bin/env node
export {};
//# sourceMappingURL=index.d.ts.map

path: dist/index.js
content: #!/usr/bin/env node
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
const zod_1 = require("zod");
const BASE_URL = process.env.NAUTDEV_BASE_URL || "https://api.nautdev.com";
async function apiFetch(path, options) {
    const response = await fetch(`${BASE_URL}${path}`, {
        headers: { "Content-Type": "application/json", Accept: "application/json" },
        ...options,
    });
    if (!response.ok) {
        throw new Error(`API error: ${response.status} ${response.statusText}`);
    }
    return response.json();
}
const server = new mcp_js_1.McpServer({
    name: "llm-inference",
    version: "1.0.0",
});
server.tool("chat", "Send a chat completion request to an LLM. Provide a model name and an array of messages with role and content.", {
    model: zod_1.z.string().describe("Model identifier (e.g. llama3, mistral, gemma)"),
    messages: zod_1.z
        .array(zod_1.z.object({
        role: zod_1.z.enum(["system", "user", "assistant"]).describe("Message role"),
        content: zod_1.z.string().describe("Message content"),
    }))
        .describe("Array of chat messages"),
    stream: zod_1.z.boolean().optional().describe("Whether to stream the response (default: false)"),
}, async ({ model, messages, stream }) => {
    try {
        const body = { model, messages };
        if (stream !== undefined)
            body.stream = stream;
        const result = await apiFetch(`/api/v1/llm/chat`, {
            method: "POST",
            body: JSON.stringify(body),
        });
        return {
            content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
        };
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return {
            content: [{ type: "text", text: JSON.stringify({ error: `Failed to complete chat: ${message}` }) }],
            isError: true,
        };
    }
});
server.tool("generate", "Generate text from a prompt using an LLM.", {
    model: zod_1.z.string().describe("Model identifier (e.g. llama3, mistral, gemma)"),
    prompt: zod_1.z.string().describe("Text prompt for generation"),
    stream: zod_1.z.boolean().optional().describe("Whether to stream the response (default: false)"),
}, async ({ model, prompt, stream }) => {
    try {
        const body = { model, prompt };
        if (stream !== undefined)
            body.stream = stream;
        const result = await apiFetch(`/api/v1/llm/generate`, {
            method: "POST",
            body: JSON.stringify(body),
        });
        return {
            content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
        };
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return {
            content: [{ type: "text", text: JSON.stringify({ error: `Failed to generate text: ${message}` }) }],
            isError: true,
        };
    }
});
server.tool("models", "List all available LLM models.", {}, async () => {
    try {
        const result = await apiFetch(`/api/v1/llm/models`);
        return {
            content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
        };
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return {
            content: [{ type: "text", text: JSON.stringify({ error: `Failed to list models: ${message}` }) }],
            isError: true,
        };
    }
});
async function main() {
    const transport = new stdio_js_1.StdioServerTransport();
    await server.connect(transport);
}
main().catch((error) => {
    console.error("Server error:", error);
    process.exit(1);
});
//# sourceMappingURL=index.js.map

path: package.json
content: {
  "name": "@vbotholemu/mcp-llm-inference",
  "version": "1.0.0",
  "description": "MCP tool for LLM inference — chat completions, text generation, and model listing via L402 API",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "bin": {
    "mcp-llm-inference": "dist/index.js"
  },
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "tsc --watch"
  },
  "keywords": [
    "mcp",
    "llm",
    "inference",
    "chat",
    "ai",
    "l402"
  ],
  "author": "Blue-Trianon-Ventures",
  "license": "MIT",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.12.1",
    "zod": "^3.23.0"
  },
  "devDependencies": {
    "typescript": "^5.7.0",
    "@types/node": "^22.0.0"
  }
}


path: src/index.ts
content: #!/usr/bin/env node

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const BASE_URL = process.env.NAUTDEV_BASE_URL || "https://api.nautdev.com";

async function apiFetch<T>(path: string, options?: RequestInit): Promise<T> {
  const response = await fetch(`${BASE_URL}${path}`, {
    headers: { "Content-Type": "application/json", Accept: "application/json" },
    ...options,
  });

  if (!response.ok) {
    throw new Error(`API error: ${response.status} ${response.statusText}`);
  }

  return response.json() as Promise<T>;
}

const server = new McpServer({
  name: "llm-inference",
  version: "1.0.0",
});

server.tool(
  "chat",
  "Send a chat completion request to an LLM. Provide a model name and an array of messages with role and content.",
  {
    model: z.string().min(1).describe("Model identifier (e.g. llama3, mistral, gemma)"),
    messages: z
      .array(
        z.object({
          role: z.enum(["system", "user", "assistant"]).describe("Message role"),
          content: z.string().describe("Message content"),
        })
      )
      .min(1)
      .describe("Array of chat messages"),
  },
  async ({ model, messages }) => {
    try {
      const body: Record<string, unknown> = { model, messages };

      const result = await apiFetch(`/api/v1/llm/chat`, {
        method: "POST",
        body: JSON.stringify(body),
      });
      return {
        content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      return {
        content: [{ type: "text" as const, text: JSON.stringify({ error: `Failed to complete chat: ${message}` }) }],
        isError: true,
      };
    }
  }
);

server.tool(
  "generate",
  "Generate text from a prompt using an LLM.",
  {
    model: z.string().min(1).describe("Model identifier (e.g. llama3, mistral, gemma)"),
    prompt: z.string().describe("Text prompt for generation"),
  },
  async ({ model, prompt }) => {
    try {
      const body: Record<string, unknown> = { model, prompt };

      const result = await apiFetch(`/api/v1/llm/generate`, {
        method: "POST",
        body: JSON.stringify(body),
      });
      return {
        content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      return {
        content: [{ type: "text" as const, text: JSON.stringify({ error: `Failed to generate text: ${message}` }) }],
        isError: true,
      };
    }
  }
);

server.tool(
  "models",
  "List all available LLM models.",
  {},
  async () => {
    try {
      const result = await apiFetch(`/api/v1/llm/models`);
      return {
        content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      return {
        content: [{ type: "text" as const, text: JSON.stringify({ error: `Failed to list models: ${message}` }) }],
        isError: true,
      };
    }
  }
);

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
}

main().catch((error) => {
  console.error("Server error:", error);
  process.exit(1);
});


path: tsconfig.json
content: {
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src"]
}


Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)