From c1cc97a3ad45dad1b5c96fa6d148439b446c94c8 Mon Sep 17 00:00:00 2001 From: Jeff Rogers Date: Thu, 26 Feb 2026 18:16:39 -0600 Subject: [PATCH 1/2] chore: update server.json version to 0.1.3 Match the published npm and MCP registry version. Co-Authored-By: Claude Opus 4.6 --- server.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.json b/server.json index 3ca3968..93f5038 100644 --- a/server.json +++ b/server.json @@ -6,12 +6,12 @@ "url": "https://github.com/atriumn/tokencost-dev", "source": "github" }, - "version": "0.1.2", + "version": "0.1.3", "packages": [ { "registryType": "npm", "identifier": "tokencost-dev", - "version": "0.1.2", + "version": "0.1.3", "transport": { "type": "stdio" } From 01cf9a8c1778d93e049fe53be521c82481857651 Mon Sep 17 00:00:00 2001 From: Jeff Rogers Date: Thu, 26 Feb 2026 18:25:22 -0600 Subject: [PATCH 2/2] feat: add createSandboxServer export for registry scanning Extract server creation into a factory function and export createSandboxServer for MCP registries (like Smithery) that need to scan server capabilities without starting stdio transport. Also make __dirname resilient to CJS bundling environments. Co-Authored-By: Claude Opus 4.6 --- src/index.ts | 61 +++++++++++++++++++++++++++++++++----------------- src/pricing.ts | 3 ++- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/index.ts b/src/index.ts index 063ebe7..abeb85b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,28 +6,39 @@ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprot import { getModels } from "./pricing.js"; import { executeTool, tools } from "./tools.js"; -const server = new Server( - { - name: "tokencost-dev", - version: "0.1.0", - }, - { - capabilities: { - tools: {}, +function createServer(): Server { + const server = new Server( + { + name: "tokencost-dev", + version: "0.1.0", }, - }, -); + { + capabilities: { + tools: {}, + }, + }, + ); + + server.setRequestHandler(ListToolsRequestSchema, async () => { + return { tools }; + }); -server.setRequestHandler(ListToolsRequestSchema, async () => { - return { tools }; -}); + server.setRequestHandler(CallToolRequestSchema, async (request) => { + const { name, arguments: args } = request.params; + return executeTool(name, args); + }); -server.setRequestHandler(CallToolRequestSchema, async (request) => { - const { name, arguments: args } = request.params; - return executeTool(name, args); -}); + return server; +} + +/** Smithery sandbox: returns a server instance for capability scanning */ +export function createSandboxServer() { + return createServer(); +} async function main() { + const server = createServer(); + // Pre-warm the cache in background getModels().catch(() => { // Non-fatal — tools will retry on first call @@ -38,7 +49,15 @@ async function main() { console.error("tokencost MCP server started"); } -main().catch((error) => { - console.error("Failed to start server:", error); - process.exit(1); -}); +// Only start stdio transport when executed directly (not imported for scanning) +const isDirectExecution = + import.meta.url === `file://${process.argv[1]}` || + process.argv[1]?.endsWith("/tokencost-dev") || + process.argv[1]?.endsWith("dist/index.js"); + +if (isDirectExecution) { + main().catch((error) => { + console.error("Failed to start server:", error); + process.exit(1); + }); +} diff --git a/src/pricing.ts b/src/pricing.ts index b7d9e0c..658cad7 100644 --- a/src/pricing.ts +++ b/src/pricing.ts @@ -2,7 +2,8 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = + typeof import.meta?.url === "string" ? dirname(fileURLToPath(import.meta.url)) : process.cwd(); const CACHE_DIR = join(__dirname, "..", ".cache"); const CACHE_FILE = join(CACHE_DIR, "prices.json"); const SOURCE_URL =