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

@juppytt/fws

v0.4.2

Published

Fake Web Services — local mock server for testing CLI tools and agents without real credentials

Downloads

1,513

Readme

fws — Fake Web Services

A local mock server for testing CLI tools and agents against fake web services without real credentials. Supports Google Workspace (gws CLI), GitHub (gh CLI), and more.

Built with Claude Code.

🦀 Powering PinchBench, the OpenClaw benchmarking framework! fws provides the fake web environment that makes realistic agent evaluation possible.

Note: OpenClaw's web_fetch tool does not currently support proxy routing, so fws cannot intercept web_fetch requests. This is a known upstream issue — see openclaw#63565 for details. Other network actions (web_search tool, curl, etc.) work fine through fws.

How it works

fws runs a local HTTP mock server (port 4100) and a MITM CONNECT proxy (port 4101) that intercepts HTTPS traffic to *.googleapis.com, api.github.com, and github.com, forwarding it to the mock server. The github.com handler speaks the git smart HTTP protocol so git clone / gh repo clone against fws-seeded repos works end-to-end.

For gws: discovery cache URLs are rewritten to localhost, and GOOGLE_WORKSPACE_CLI_TOKEN=fake bypasses auth. For gh: HTTPS_PROXY routes traffic through the MITM proxy, and GH_TOKEN=fake bypasses auth.

All data lives in memory. When the server stops, everything is lost unless you save a snapshot first. Use fws snapshot save to persist state.

Install

npm install -g @juppytt/fws

Or from source:

git clone https://github.com/juppytt/fws.git && cd fws
npm install && npm link

Quick Start

# Start the server (runs in background)
fws server start

# Configure your shell
eval $(fws server env)

# Try gws commands
gws gmail +triage
gws calendar events list --params '{"calendarId":"primary"}'
gws drive files list

# Try gh commands (gh reads owner/repo from the current checkout's
# .git/config — run inside a checkout, or prefix with GH_REPO=owner/repo)
gh api /user
GH_REPO=testuser/my-project gh issue list
gh api /repos/testuser/my-project/issues

# When done
fws server stop

The server starts with sample seed data so you can try commands immediately.

Usage

Start the server

fws server start                  # Start in background
fws server status                 # Check if running
fws server stop                   # Stop
fws server start --foreground     # Run in foreground (for debugging)

After starting, configure your shell so gws, gh, curl, etc. route through the mock:

eval $(fws server env)

Then run the CLI tools normally:

gws gmail users messages list --params '{"userId":"me"}'
gws gmail +triage
gh issue list
curl https://example.com/        # mocked via Web Fetch (see below)

Inject data into a running server

Each service is its own top-level command. The action is add for all services that just take new entries.

fws gmail    add --from [email protected] --subject "Meeting" --body "See you at 3pm"
fws calendar add --summary "Team sync" --start 2026-04-08T15:00:00 --duration 1h
fws drive    add --name "report.pdf" --mimeType application/pdf
fws search   add --keywords python,py --results '[{"title":"Python","link":"https://python.org/","displayLink":"python.org","snippet":"..."}]'
fws fetch    add --url https://api.example.com/v1/echo --status 200 --body '{"hello":"world"}' --header 'content-type: application/json'

fws fetch add is the entry point to Web Fetch — a generic mock for arbitrary HTTP/HTTPS URLs. Adding a fixture for a URL or host automatically makes that host eligible for proxy interception, so any client routed through HTTPS_PROXY will see the mock instead of hitting the real internet.

Snapshots

Data is in-memory only. Save before stopping the server if you need to keep it.

fws snapshot save my-scenario     # Save current state to disk
fws snapshot load my-scenario     # Restore saved state into running server
fws snapshot list                 # List saved snapshots
fws snapshot delete my-scenario   # Delete a snapshot
fws reset                        # Reset to default seed data
fws reset --snapshot my-scenario  # Reset to a specific snapshot

Snapshots are stored in ~/.local/share/fws/snapshots/ (override with FWS_DATA_DIR).

Posting issues / PRs as different users

The default seeded "self" user is testuser / "Test User" / [email protected]. When fws creates a new issue, PR, or comment via the gh API it stamps user.login with whoever the seeded self user is at that moment — agents read this back from the API and weight a request from testuser differently from one from alex.park, so for agent-eval runs you'll typically want a plausible login.

Set the initial identity at server start (optional):

FWS_USER_LOGIN=alex.park \
FWS_USER_NAME="Alex Park" \
[email protected] \
fws server start

…and switch it at runtime to alternate authors in one session:

fws github user set --login alex.park --name "Alex Park"
gh issue create -t "..." -b "..."   # → user.login = alex.park

fws github user set --login david.kim --name "David Kim"
gh issue create -t "..." -b "..."   # → user.login = david.kim

The display name also flows to Drive owner / Gmail sendAs without a restart. Snapshots capture the live identity, so it persists across fws snapshot save / fws snapshot load.

Working against a different repo

The seeded repo is always ${login}/my-project. The store is keyed by repo full_name, so additional repos are first-class — create one and work in it:

gh repo create platform/weather-outfit-recommender   # API-only repo entry
# …or, to also materialize a clonable bare repo on disk so `git clone` works:
curl -sX POST http://localhost:4100/__fws/setup/github/repo \
  -H 'content-type: application/json' \
  -d '{"owner":"platform","repo":"weather-outfit-recommender","files":[{"path":"README.md","content":"# weather-outfit-recommender\n"}]}'
git clone http://localhost:4100/git/platform/weather-outfit-recommender.git
cd weather-outfit-recommender
gh issue create -t "Fix login bug" -b "..."   # gh reads owner/repo from .git/config

fws server env does not export GH_REPO — gh reads owner/repo from the current checkout's .git/config. If you run gh outside a checkout, prefix the call with GH_REPO=owner/repo.

Default seed data

| Service | Data | |----------|------| | Gmail | 5 messages (3 inbox, 1 sent, 1 read), system labels + "Projects" user label | | Calendar | 4 events (Daily Standup, Q3 Planning, 1:1, Team Lunch) | | Drive | 5 files (docs, spreadsheet, image, folder) | | Tasks | 1 task list with 2 tasks (1 pending, 1 completed) | | Sheets | 1 spreadsheet ("Budget 2026") | | People | 2 contacts (Alice, Bob), 1 contact group | | GitHub | 1 repo (${login}/my-project, default testuser/my-project), 2 issues, 1 PR, 1 comment — see "Posting issues / PRs as different users" and "Working against a different repo" |

Documentation

Structure

bin/fws.ts              CLI entry point
src/server/routes/      Gmail, Calendar, Drive, and control API routes
src/store/              In-memory data store + seed data
src/config/             Discovery cache URL rewriting
src/proxy/              MITM proxy for helper commands
test/                   Vitest tests (with gws CLI validation)
docs/                   API support documentation