Pump.fun MCP Server
by noahgsolomon
- src
import { Keypair } from "@solana/web3.js";
import fs from "fs";
import path from "path";
import { rootDir } from "./utils.js";
import { createMcpResponse } from "./get-token-info.js";
import dotenv from "dotenv";
dotenv.config({ path: path.join(rootDir, ".env") });
export async function listAccounts() {
try {
console.error("Starting listAccounts function");
const keysFolder = path.resolve(rootDir, ".keys");
console.error(`Using keys folder path: ${keysFolder}`);
console.error(
`Checking if keys folder exists: ${fs.existsSync(keysFolder)}`
);
if (!fs.existsSync(keysFolder)) {
console.error(`Creating keys folder: ${keysFolder}`);
try {
fs.mkdirSync(keysFolder, { recursive: true });
console.error(`Keys folder created successfully`);
return {
success: true,
message: `No accounts found. Keys folder created at ${keysFolder}. Use the create-token or buy-token tools to create an account.`,
accounts: [],
};
} catch (mkdirError: any) {
console.error(`Error creating keys folder:`, mkdirError);
return {
success: false,
error: `Error creating keys folder: ${
mkdirError.message || JSON.stringify(mkdirError)
}`,
accounts: [],
};
}
}
console.error(`Reading files from keys folder: ${keysFolder}`);
const files = fs.readdirSync(keysFolder);
console.error(`Found ${files.length} files in keys folder`);
const accounts = files
.filter((file) => !file.startsWith("mint-") && file.endsWith(".json"))
.map((file) => {
const name = file.replace(".json", "");
console.error(`Processing account file: ${file}`);
try {
const keypairData = JSON.parse(
fs.readFileSync(path.join(keysFolder, file), "utf-8")
);
const keypair = Keypair.fromSecretKey(new Uint8Array(keypairData));
return { name, publicKey: keypair.publicKey.toString() };
} catch (error: any) {
console.error(`Error processing account file ${file}:`, error);
return { name, publicKey: "Error reading keypair" };
}
});
console.error(`Found ${accounts.length} accounts`);
if (accounts.length === 0) {
return {
success: true,
message: `No accounts found in ${keysFolder}. Use the create-token or buy-token tools to create an account.`,
accounts: [],
};
}
return {
success: true,
message: `Accounts in ${keysFolder}:`,
accounts,
};
} catch (error: any) {
console.error("Error listing accounts:", error);
console.error("Error stack:", error.stack);
let errorMessage = "Unknown error";
if (error) {
if (typeof error === "object") {
if (error.message) {
errorMessage = error.message;
} else {
try {
errorMessage = JSON.stringify(error);
} catch (e) {
errorMessage = "Error object could not be stringified";
}
}
} else {
errorMessage = String(error);
}
}
return { success: false, error: errorMessage, accounts: [] };
}
}
export function formatListAccountsResult(
result: ReturnType<typeof listAccounts> extends Promise<infer T> ? T : never
) {
if (!result.success) {
return `Error listing accounts: ${result.error}`;
}
if (result.accounts.length === 0) {
return result.message;
}
const accountsText = result.accounts
.map((account) => `${account.name}: ${account.publicKey}`)
.join("\n");
return `${result.message}\n\n${accountsText}`;
}
async function main() {
try {
const result = await listAccounts();
console.log("\nResult:");
const formattedResult = formatListAccountsResult(result);
console.log(formattedResult);
const mcpResponse = createMcpResponse(
formattedResult || "Error: No result"
);
console.log("\nMCP Response (for reference):");
console.log(JSON.stringify(mcpResponse, null, 2));
} catch (error: any) {
console.error("Error in main:", error);
}
}
const isMainModule = import.meta.url === `file://${process.argv[1]}`;
if (isMainModule) {
main().catch(console.error);
}
export default {
listAccounts,
formatListAccountsResult,
};