npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@voygent/roadtrip-tools

v0.1.1

Published

Reusable roadtrip guide tools for Scaffold MCP apps

Readme

@voygent/roadtrip-tools

21 pre-built MCP tools for roadtrip guide assistants. Add spots, driving days, position tracking, day plans, visit logging, knowledge lookup, and runtime learning — all wired up and ready to deploy on Cloudflare Workers.

Quick Start

mkdir my-roadtrip-guide && cd my-roadtrip-guide
npm init -y
npm install @voygent/scaffold-core @voygent/roadtrip-tools
npm install -D @cloudflare/workers-types typescript wrangler

Entry point (src/index.ts)

import { ScaffoldServer, CloudflareKVAdapter, type ScaffoldConfig } from '@voygent/scaffold-core';
import { createRoadtripTools, seedContent, type SeedEntry } from '@voygent/roadtrip-tools';

interface Env {
  DATA: KVNamespace;
  ADMIN_KEY: string;
}

const config: ScaffoldConfig = {
  app: {
    name: 'Iceland Ring Road Guide',
    description: 'Roadtrip assistant for Iceland\'s Ring Road',
    version: '0.1.0',
  },
  mcp: {
    serverName: 'scaffold-iceland-ring-road',
    protocolVersion: '2024-11-05',
  },
  auth: {
    adminKey: undefined,
    requireAuth: true,
    enableKeyIndex: false,
    enableFallbackScan: false,
    fallbackScanRateLimit: 0,
    fallbackScanBudget: 0,
  },
  admin: { path: '/admin' },
};

// Create all 21 tools with a short prefix
const tools = createRoadtripTools({
  prefix: 'ice',
  config: { avgSpeedKmh: 70, defaultLookaheadKm: 50 },
});

// Seed knowledge on first request
const KNOWLEDGE: SeedEntry[] = [
  {
    topic: 'driving-tips',
    content: '# Driving in Iceland\n\n- Speed limit: 90 km/h on highways, 50 km/h in towns\n- Single-lane bridges: first to arrive has right of way\n- F-roads require 4WD — rental agreements prohibit 2WD on F-roads',
  },
  {
    topic: 'weather-safety',
    content: '# Weather Safety\n\n- Check road.is and vedur.is before driving\n- Wind gusts can exceed 100 km/h — hold car doors firmly\n- Conditions change rapidly — carry warm layers even in summer',
  },
];

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const storage = new CloudflareKVAdapter(env.DATA);
    ctx.waitUntil(seedContent(storage, KNOWLEDGE));

    const server = new ScaffoldServer({
      config: { ...config, auth: { ...config.auth, adminKey: env.ADMIN_KEY } },
      storage,
      tools,
    });

    return server.fetch(request, env as unknown as Record<string, unknown>, ctx);
  },
};

Wrangler config (wrangler.toml)

name = "scaffold-iceland-ring-road"
main = "src/index.ts"
compatibility_date = "2024-12-01"
compatibility_flags = ["nodejs_compat"]

[[kv_namespaces]]
binding = "DATA"
id = "REPLACE_AFTER_wrangler_kv_namespace_create_DATA"
preview_id = "REPLACE_AFTER_wrangler_kv_namespace_create_DATA_--preview"

Deploy

wrangler login
wrangler kv namespace create DATA          # copy the id into wrangler.toml
wrangler kv namespace create DATA --preview # copy the preview_id
wrangler deploy
openssl rand -hex 20                       # generate admin key (hex only, not base64)
echo "YOUR_KEY" | wrangler secret put ADMIN_KEY

Connect to Claude

Claude Web: Settings → Integrations → Add Custom MCP → paste your Worker URL

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "iceland-ring-road": {
      "url": "https://scaffold-iceland-ring-road.YOUR-SUBDOMAIN.workers.dev/sse",
      "headers": { "Authorization": "Bearer YOUR-ADMIN-KEY" }
    }
  }
}

Claude Code (.mcp.json):

{
  "mcpServers": {
    "iceland-ring-road": {
      "type": "sse",
      "url": "https://scaffold-iceland-ring-road.YOUR-SUBDOMAIN.workers.dev/sse",
      "headers": { "Authorization": "Bearer YOUR-ADMIN-KEY" }
    }
  }
}

Tools (21)

All tools are created by createRoadtripTools({ prefix }). Tool names use the pattern {prefix}-{action}.

Spots (6)

| Tool | Description | |------|-------------| | add_spot | Add a point of interest (restaurant, waterfall, viewpoint, etc.) | | get_spot | Get spot details by ID | | list_spots | List all spots, optionally filtered by category or region | | search_spots | Fuzzy text search across spots | | update_spot | Update spot fields | | recommend | Get context-aware recommendations (nearby, by interest, by route position) |

Driving Days (3)

| Tool | Description | |------|-------------| | create_drive | Create a driving day with waypoints, distance, and estimated time | | get_drive | Get driving day details | | list_drives | List all driving days sorted by day number |

Position Tracking (3)

| Tool | Description | |------|-------------| | update_position | Set current position on route (waypoint + km) | | whats_ahead | See upcoming waypoints and spots from current position | | trip_status | Overview of trip progress across all driving days |

Day Plans (4)

| Tool | Description | |------|-------------| | create_plan | Create a day plan grouping spots with a theme | | get_plan | Get day plan details | | list_plans | List all day plans | | update_plan | Update a day plan |

Visit Logging (3)

| Tool | Description | |------|-------------| | log_visit | Log visiting a spot with optional rating and notes | | get_log | Get visit log for a spot | | trip_summary | Summary of all visits with average rating |

Knowledge (2)

| Tool | Description | |------|-------------| | get_guide | Look up a knowledge topic, or list all available topics | | learn_topic | Add/update knowledge at runtime (admin only, two-step propose→apply) |

API

createRoadtripTools(options)

import { createRoadtripTools } from '@voygent/roadtrip-tools';

const tools = createRoadtripTools({
  prefix: 'ice',                // 2-5 char prefix for tool names
  config: {                     // optional
    avgSpeedKmh: 70,            // for position extrapolation (default: 80)
    defaultLookaheadKm: 50,     // for whats_ahead radius (default: 50)
  },
});

Returns an array of 21 ScaffoldTool objects ready to pass to ScaffoldServer.

seedContent(storage, entries)

import { seedContent, type SeedEntry } from '@voygent/roadtrip-tools';

const entries: SeedEntry[] = [
  { topic: 'driving-tips', content: '# Driving Tips\n\n...' },
];

const result = await seedContent(storage, entries);
// { seeded: 2, skipped: 0 }  — first call
// { seeded: 0, skipped: 2 }  — subsequent calls (idempotent)

Knowledge is stored at _knowledge/{topic} and accessible via the get_guide tool.

Individual tool creators

For custom composition (e.g. only spots + drives, no position tracking):

import { createSpotTools, createDriveTools } from '@voygent/roadtrip-tools';

const tools = [
  ...createSpotTools('ice'),
  ...createDriveTools('ice'),
];

Available: createSpotTools, createDriveTools, createPositionTools, createPlanTools, createLogTools, createGuideTools, createLearnTools.

Types

import type {
  Spot, DrivingDay, Waypoint, Position,
  DayPlan, TravelerLog, RoadtripConfig,
} from '@voygent/roadtrip-tools';

Key helpers

import {
  spotKey, spotsPrefix,       // {userId}/spots/{id}
  driveKey, drivesPrefix,     // {userId}/drives/{id}
  positionKey,                // {userId}/position/current
  planKey, plansPrefix,       // {userId}/plans/{id}
  logKey, logsPrefix,         // {userId}/logs/{id}
  knowledgeKey,               // _knowledge/{topic}
  generateId, makeTestCtx,
} from '@voygent/roadtrip-tools';

Storage Patterns

| Data | Key Pattern | Scope | |------|-------------|-------| | Spots | {userId}/spots/{id} | Per user | | Drives | {userId}/drives/{id} | Per user | | Position | {userId}/position/current | Per user (singleton) | | Plans | {userId}/plans/{id} | Per user | | Logs | {userId}/logs/{id} | Per user | | Knowledge | _knowledge/{topic} | Shared (all users) |

Interactive Setup

For a guided experience, use the /roadtrip-builder skill in Claude Code — it interviews you about the destination, generates the project, researches knowledge, and deploys.