Skip to main content
Glama
mcp.ts7.76 kB
import { McpServer, ResourceTemplate, } from "@modelcontextprotocol/sdk/server/mcp.js"; import Arweave from "arweave"; import { createSigner, message, spawn, result } from "@permaweb/aoconnect"; import { z } from "zod"; import { installPackage } from "./helpers/apm"; import { addBlueprint, fetchBlueprintCode } from "./helpers/blueprint"; import { runLuaCode } from "./lib/runLua"; import { listHandlers, addHandler, runHandler } from "./helpers/handlers"; import { sleep } from "./lib/utils"; function cleanOutput(result: any): string { if (!result) return ""; return JSON.stringify(result, null, 2) .replace(/\\u001b\[\d+m/g, "") .replace(/\\n/g, "\n"); } class FluxServer { public server: McpServer; private signer!: ReturnType<typeof createSigner>; private initialized = false; constructor() { this.server = new McpServer( { name: "flux", version: "1.0.0", }, { capabilities: {}, } ); } async initialize() { if (this.initialized) return; const arweave = Arweave.init({ host: "arweave.net", port: 443, protocol: "https", }); // Generate wallet and create signer const wallet = await arweave.wallets.generate(); this.signer = createSigner(wallet); // Register all tools await this.registerTools(); this.initialized = true; } private async registerTools() { this.server.tool( "spawn", "spawn a new AO process", { tags: z.array( z.object({ name: z.string(), value: z.string(), }) ), needsSqlite: z.boolean().optional(), }, async ({ tags, needsSqlite }) => { const processId = await spawn({ module: needsSqlite ? "33d-3X8mpv6xYBlVB-eXMrPfH5Kzf6Hiwhcv0UA10sw" : "JArYBF-D8q2OmZ4Mok00sD2Y_6SYEQ7Hjx-6VZ_jl3g", signer: this.signer, scheduler: "_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA", tags, }); return { content: [{ type: "text", text: processId }], }; } ); this.server.tool( "send-message-to-process", "send a message to an existing AO process", { processId: z.string(), data: z.string(), tags: z .array( z.object({ name: z.string(), value: z.string(), }) ) .optional(), }, async ({ processId, data, tags }) => { const messageId = await message({ process: processId, signer: this.signer, data, tags, }); await sleep(100); const output = await result({ message: messageId, process: processId, }); if (output.Error) { return { content: [{ type: "text", text: cleanOutput(output.Error) }], }; } return { content: [ { type: "text", text: cleanOutput(output.Messages[0].Data) }, ], }; } ); this.server.tool( "apm-install", "install a package in an existing AO process", { packageName: z.string(), processId: z.string() }, async ({ packageName, processId }) => { const result = await installPackage( packageName, processId, this.signer ); return { content: [{ type: "text", text: cleanOutput(result) }], }; } ); this.server.tool( "load-token-blueprint", "load the token blueprint in an existing AO process", { processId: z.string() }, async ({ processId }) => { const result = await addBlueprint("token", processId, this.signer); return { content: [{ type: "text", text: cleanOutput(result) }], }; } ); this.server.tool( "create-sqlite-based-handler", "create a new sqlite based handler in an existing AO process", { processId: z.string(), handlerCode: z.string() }, async ({ processId, handlerCode }) => { const code = `local sqlite = require('lsqlite3')\nDb = sqlite.open_memory()\n${handlerCode}`; const result = await runLuaCode(code, processId, this.signer); return { content: [{ type: "text", text: cleanOutput(result) }], }; } ); this.server.tool( "run-lua-in-process", "run a lua script in an existing AO process", { code: z.string(), processId: z.string(), tags: z .array( z.object({ name: z.string(), value: z.string(), }) ) .optional(), }, async ({ code, processId, tags }) => { const result = await runLuaCode(code, processId, this.signer, tags); return { content: [{ type: "text", text: cleanOutput(result) }], }; } ); this.server.tool( "load-blueprint", "load a blueprint in an existing AO process", { url: z.string(), processId: z.string() }, async ({ url, processId }) => { const code = await fetchBlueprintCode(url); const result = await runLuaCode(code, processId, this.signer); return { content: [{ type: "text", text: cleanOutput(result) }], }; } ); this.server.tool( "load-local-blueprint", "load a local blueprint in an existing AO process", { blueprintCode: z.string(), processId: z.string() }, async ({ blueprintCode, processId }) => { const result = await runLuaCode(blueprintCode, processId, this.signer); return { content: [{ type: "text", text: cleanOutput(result) }], }; } ); this.server.tool( "load-official-blueprint", "load an official blueprint in an existing AO process", { blueprintName: z.string(), processId: z.string() }, async ({ blueprintName, processId }) => { const result = await addBlueprint( blueprintName, processId, this.signer ); return { content: [{ type: "text", text: cleanOutput(result) }], }; } ); this.server.tool( "list-available-handlers", "list all available handlers in an existing AO process", { processId: z.string() }, async ({ processId }) => { const handlers = await listHandlers(processId, this.signer); return { content: [{ type: "text", text: cleanOutput(handlers) }], }; } ); this.server.tool( "create-handler", "create a new handler in an existing AO process", { processId: z.string(), handlerCode: z.string() }, async ({ processId, handlerCode }) => { const result = await addHandler(processId, handlerCode, this.signer); return { content: [{ type: "text", text: cleanOutput(result) }], }; } ); this.server.tool( "run-handler-using-handler-name", "run a handler using its name in an existing AO process", { processId: z.string(), handlerName: z.string(), data: z.string() }, async ({ processId, handlerName, data }) => { const result = await runHandler( processId, handlerName, data, this.signer ); if (result.Error) { return { content: [{ type: "text", text: cleanOutput(result.Error) }], }; } return { content: [ { type: "text", text: cleanOutput(result.Messages[0].Data) }, ], }; } ); } } export default FluxServer;

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/asrvd/flux'

If you have feedback or need assistance with the MCP directory API, please join our Discord server