Skip to main content
Glama
parse-args.ts6.6 kB
import { resolve } from "path" import fs from "fs" export interface ParsedArgs { remainingArgs: string[] transport: "stdio" | "http" httpPort: number host: string } function parseArgs(): ParsedArgs { const args = process.argv.slice(2) let transport: "stdio" | "http" = "stdio" let httpPort = 3000 let host = "127.0.0.1" // Load environment variables without dotenv debug output (for MCP stdio compatibility) const loadEnvFile = (envPath: string) => { try { if (fs.existsSync(envPath)) { process.stderr.write(`📄 Loading environment from: ${envPath}\n`) const envContent = fs.readFileSync(envPath, "utf-8") const envLines = envContent.split("\n") const loadedVars: string[] = [] for (const line of envLines) { const trimmedLine = line.trim() if (trimmedLine && !trimmedLine.startsWith("#")) { const [key, ...valueParts] = trimmedLine.split("=") if (key && valueParts.length > 0) { const value = valueParts.join("=").replace(/^["']|["']$/g, "") if (!process.env[key.trim()]) { process.env[key.trim()] = value // Only show key name, not the actual value for security loadedVars.push(key.trim()) } } } } if (loadedVars.length > 0) { process.stderr.write(`✅ Loaded variables: ${loadedVars.join(", ")}\n`) } } else { process.stderr.write(`⚠️ Environment file not found: ${envPath}\n`) } } catch (error: unknown) { process.stderr.write(`❌ Error loading environment file: ${error}\n`) } } // Handle --env-file if (args.includes("--env-file")) { const envFileIndex = args.indexOf("--env-file") const envFile = args[envFileIndex + 1] if (!envFile || envFile.startsWith("--")) { process.stderr.write("Error: --env-file requires a file path\n") process.exit(1) } // Remove the --env-file and its value from args args.splice(envFileIndex, 2) // Load the environment variables from the specified file loadEnvFile(resolve(process.cwd(), envFile)) } else { // Load from default .env file loadEnvFile(".env") } // Handle --port if (args.includes("--port")) { const portIndex = args.indexOf("--port") const port = args[portIndex + 1] if (!port || port.startsWith("--")) { process.stderr.write("Error: --port requires a port number\n") process.exit(1) } // Remove the --port and its value from args args.splice(portIndex, 2) // Set environment variable process.env.JOPLIN_PORT = port } // Handle --token if (args.includes("--token")) { const tokenIndex = args.indexOf("--token") const token = args[tokenIndex + 1] if (!token || token.startsWith("--")) { process.stderr.write("Error: --token requires a token value\n") process.exit(1) } // Remove the --token and its value from args args.splice(tokenIndex, 2) // Set environment variable process.env.JOPLIN_TOKEN = token } // Handle --host if (args.includes("--host")) { const hostIndex = args.indexOf("--host") const hostValue = args[hostIndex + 1] if (!hostValue || hostValue.startsWith("--")) { process.stderr.write("Error: --host requires a hostname or IP address\n") process.exit(1) } // Remove the --host and its value from args args.splice(hostIndex, 2) // Set host variable host = hostValue } else if (process.env.JOPLIN_HOST) { // Use environment variable if set host = process.env.JOPLIN_HOST } // Handle --transport if (args.includes("--transport")) { const transportIndex = args.indexOf("--transport") const transportValue = args[transportIndex + 1] if (!transportValue || transportValue.startsWith("--")) { process.stderr.write("Error: --transport requires a transport type (stdio|http)\n") process.exit(1) } if (transportValue !== "stdio" && transportValue !== "http") { process.stderr.write("Error: --transport must be either 'stdio' or 'http'\n") process.exit(1) } transport = transportValue as "stdio" | "http" // Remove the --transport and its value from args args.splice(transportIndex, 2) } // Handle --http-port if (args.includes("--http-port")) { const httpPortIndex = args.indexOf("--http-port") const httpPortValue = args[httpPortIndex + 1] if (!httpPortValue || httpPortValue.startsWith("--")) { process.stderr.write("Error: --http-port requires a port number\n") process.exit(1) } httpPort = parseInt(httpPortValue, 10) if (isNaN(httpPort) || httpPort < 1 || httpPort > 65535) { process.stderr.write("Error: --http-port must be a valid port number (1-65535)\n") process.exit(1) } // Remove the --http-port and its value from args args.splice(httpPortIndex, 2) } // Handle --help if (args.includes("--help") || args.includes("-h")) { process.stderr.write(` Joplin MCP Server USAGE: joplin-mcp-server [OPTIONS] OPTIONS: --env-file <file> Load environment variables from file --host <hostname> Joplin hostname or IP (default: 127.0.0.1) --port <port> Joplin port (default: 41184) --token <token> Joplin API token --transport <type> Transport type: stdio (default) or http --http-port <port> HTTP server port (default: 3000, only used with --transport http) --help, -h Show this help message ENVIRONMENT VARIABLES: JOPLIN_HOST Joplin hostname or IP (default: 127.0.0.1) JOPLIN_PORT Joplin port (default: 41184) JOPLIN_TOKEN Joplin API token (required) LOG_LEVEL Log level: debug, info, warn, error (default: info) EXAMPLES: # Stdio transport (default, for Claude Desktop) joplin-mcp-server --port 41184 --token your_token joplin-mcp-server --env-file /path/to/.env # HTTP transport (for web applications) joplin-mcp-server --transport http --http-port 3000 --token your_token joplin-mcp-server --env-file .env.local --transport http # WSL - Connect to Windows host joplin-mcp-server --host 172.20.208.1 --token your_token export JOPLIN_HOST=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}') joplin-mcp-server --transport http Find your Joplin token in: Tools > Options > Web Clipper `) process.exit(0) } return { remainingArgs: args, transport, httpPort, host, } } export default parseArgs

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/jordanburke/joplin-mcp-server'

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