tpmjs/apps/railway-executor
Ajax Davis 8f27d1cfa7 fix(executor): declare packageName/exportName before try block
Same issue as startTime - these variables were destructured inside the
try block but referenced in the catch block for health reporting. If
JSON parsing or any early error occurred, the catch block would crash
with 'packageName is not defined'.

Now declares them with 'unknown' defaults before try, then assigns
the actual values inside.
2025-12-12 06:14:08 +10:00
..
.gitignore feat: add dynamic tool loading system with Railway executor 2025-12-04 08:25:53 +10:00
Dockerfile fix: remove nonexistent deno.json from Dockerfile 2025-12-05 01:10:42 +10:00
package-lock.json feat: add dynamic tool loading system with Railway executor 2025-12-04 08:25:53 +10:00
package.json feat: add dynamic tool loading system with Railway executor 2025-12-04 08:25:53 +10:00
README.md feat: add dynamic tool loading system with Railway executor 2025-12-04 08:25:53 +10:00
server.js feat: add dynamic tool loading system with Railway executor 2025-12-04 08:25:53 +10:00
server.ts fix(executor): declare packageName/exportName before try block 2025-12-12 06:14:08 +10:00

Railway Dynamic Tool Executor

Dynamic tool executor service that runs with --experimental-network-imports to support loading npm packages from esm.sh at runtime.

Features

  • 🔥 Dynamic imports from esm.sh
  • 💾 Module caching for fast repeated loads
  • 🛡️ Validation of AI SDK tool structure
  • 🚀 Remote execution of tools with parameters

Endpoints

GET /health

Health check and cache statistics

POST /load-and-describe

Load a tool from esm.sh and return its schema

Request:

{
  "packageName": "firecrawl-aisdk",
  "exportName": "webSearchTool",
  "version": "0.7.2",
  "importUrl": "https://esm.sh/firecrawl-aisdk@0.7.2"
}

Response:

{
  "success": true,
  "tool": {
    "exportName": "webSearchTool",
    "description": "Search the web using Firecrawl",
    "inputSchema": { ... }
  }
}

POST /execute-tool

Execute a tool with parameters

Request:

{
  "packageName": "firecrawl-aisdk",
  "exportName": "webSearchTool",
  "version": "0.7.2",
  "params": {
    "query": "latest AI news"
  }
}

Response:

{
  "success": true,
  "output": { ... },
  "executionTimeMs": 1234
}

POST /cache/clear

Clear the module cache

GET /cache/stats

Get cache statistics

Local Development

# Install dependencies
npm install

# Start server
npm start

# Server runs on http://localhost:3001

Railway Deployment

This service is designed to run on Railway.

Deploy Steps

  1. Initialize Railway in this directory:
cd apps/railway-executor
railway init
  1. Link to your Railway project:
railway link
  1. Deploy:
railway up
  1. Railway will automatically:
    • Detect Node.js
    • Run npm install
    • Execute npm start (which includes --experimental-network-imports)

Environment Variables

No environment variables required for basic operation. Optional:

  • PORT - Server port (Railway sets this automatically)
  • NODE_ENV - Set to production in Railway

Testing

Test health endpoint:

curl http://localhost:3001/health

Test tool loading:

curl -X POST http://localhost:3001/load-and-describe \
  -H "Content-Type: application/json" \
  -d '{
    "packageName": "@tpmjs/hello",
    "exportName": "helloWorldTool",
    "version": "0.1.0"
  }'

Test tool execution:

curl -X POST http://localhost:3001/execute-tool \
  -H "Content-Type: application/json" \
  -d '{
    "packageName": "@tpmjs/hello",
    "exportName": "helloWorldTool",
    "version": "0.1.0",
    "params": {}
  }'

Integration with Playground

The playground app calls this service to load and execute tools dynamically.

Set in playground environment:

RAILWAY_SERVICE_URL=https://your-service.up.railway.app

Or use existing:

SANDBOX_EXECUTOR_URL=https://your-service.up.railway.app