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

@dtst/img

v0.1.0

Published

MCP server and CLI for generating and editing images through any OpenAI-compatible API (OpenAI, OpenRouter, vLLM, Ollama, LiteLLM). Saves to agent-specified paths.

Readme

@dtst/img

MCP server and CLI for generating and editing images through any OpenAI-compatible API (OpenAI, OpenRouter, LiteLLM, vLLM, …). Images are written to the file you ask for and returned inline for vision-capable clients.

npx -y @dtst/img    # MCP stdio server

Tools: generate_image, edit_image, list_image_models.

Configuration

OPENAI_BASE_URL=https://openrouter.ai/api/v1   # any OpenAI-compatible root
OPENAI_API_KEY=sk-...
OPENAI_MODEL=meta/muse-image                   # an IMAGE model

Optional: DEBUG=true for verbose stderr logs, DTST_WORKSPACE=/path to resolve relative output paths, DTST_OUTPUT_DIR=out for a default destination. A .env file next to your project is picked up automatically.

Add to your client

This entry works as-is in Claude Desktop, Cursor, Windsurf, Cline and Roo Code:

{
  "mcpServers": {
    "img": {
      "command": "npx",
      "args": ["-y", "@dtst/img"],
      "env": {
        "OPENAI_BASE_URL": "https://openrouter.ai/api/v1",
        "OPENAI_API_KEY": "sk-...",
        "OPENAI_MODEL": "meta/muse-image"
      }
    }
  }
}

| Client | Where it goes | Key | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | | Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json (macOS), %APPDATA%\Claude\claude_desktop_config.json (Windows) | mcpServers | | Cursor | ~/.cursor/mcp.json or .cursor/mcp.json | mcpServers (add "type": "stdio") | | Windsurf | ~/.codeium/windsurf/mcp_config.json | mcpServers | | Cline | ~/.cline/mcp.json | mcpServers | | Roo Code | .roo/mcp.json | mcpServers | | VS Code (Copilot) | .vscode/mcp.json | servers + "type": "stdio" | | Zed | Zed settings.json | context_servers | | JetBrains | Settings → Tools → AI Assistant → MCP → Add → STDIO | paste the JSON above |

Use an image model: meta/muse-image, google/gemini-3.1-flash-image, openai/gpt-image-1, dall-e-3. img models lists what your endpoint offers.

opencode

opencode.json — command is an array and env vars use environment:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "img": {
      "type": "local",
      "command": ["npx", "-y", "@dtst/img"],
      "environment": {
        "OPENAI_BASE_URL": "https://openrouter.ai/api/v1",
        "OPENAI_API_KEY": "sk-...",
        "OPENAI_MODEL": "meta/muse-image"
      },
      "enabled": true
    }
  }
}

Codex CLI

~/.codex/config.toml:

[mcp_servers.img]
command = "npx"
args = ["-y", "@dtst/img"]

[mcp_servers.img.env]
OPENAI_BASE_URL = "https://openrouter.ai/api/v1"
OPENAI_API_KEY = "sk-..."
OPENAI_MODEL = "meta/muse-image"

Command-line clients

claude mcp add --transport stdio img \
  --env OPENAI_API_KEY=sk-... --env OPENAI_MODEL=meta/muse-image \
  -- npx -y @dtst/img

codex mcp add img --env OPENAI_MODEL=meta/muse-image -- npx -y @dtst/img

gemini mcp add -e OPENAI_MODEL=meta/muse-image img npx -y @dtst/img

Tools

generate_image

| param | type | what it does | | -------------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------- | | prompt | required, string | What to draw — subject, composition, lighting, medium. Up to 30,000 chars. | | model | string | One-off override of OPENAI_MODEL. | | n | int 1–10 | How many images. Default 1. | | size | string | Explicit pixels (1024x1024, 1536x1024, any WxH the provider allows) or a tier (1K, 2K, 4K, auto). | | aspect_ratio | string | For providers taking a ratio instead of pixels: 16:9, 1:1, 4:5, auto, … | | quality | string | low, medium, high, xhigh, max, auto (DALL·E also standard, hd). | | output_format | png | jpeg | webp | Encoding of the saved file. | | background | transparent | opaque | auto | transparent needs png/webp. | | output_compression | int 0–100 | Compression for jpeg/webp. | | seed | int | Reproducible results where the provider supports it. | | style | string | Style guidance appended to the prompt, e.g. watercolour, 35mm. | | negative_prompt | string | Things to avoid. | | output_path | string | Exact file or directory to write to. Wins over output_dir. | | output_dir | string | Directory to write into. | | filename | string | Preferred name; the extension follows the returned image type. | | overwrite | boolean | false (default) appends -1, -2, … instead of clobbering. | | save | boolean | false = generate without touching the disk. Default true. | | inline | boolean | false = skip the base64 preview in the response. Default true. |

edit_image

| param | type | what it does | | ---------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | prompt | required, string | The change to apply. | | images | required, string[] 1–16 | Inputs: file paths, globs (assets/*.png), http(s) URLs, data: URLs, raw base64, or dtst://artifact/<id> from an earlier call. | | mask | string | Mask image; transparent pixels mark the region to regenerate. OpenAI images-API backends only. | | input_fidelity | high | low | How strongly to preserve input details (gpt-image models). | | model, n, size, aspect_ratio, quality, output_format, background, output_compression, seed, style, negative_prompt | | Same as generate_image. | | output_path, output_dir, filename, overwrite, save, inline | | Same saving controls. |

list_image_models

| param | type | what it does | | ------------------- | ---------------- | ----------------------------------------------------- | | query | string | Substring filter over model id, name and description. | | limit | int 1–500 | Maximum results (default 50). | | output_modalities | image | any | image (default) lists models that emit images. |

How an agent uses it

list_image_models { "query": "muse", "limit": 5 }

generate_image {
  "prompt": "a red panda astronaut, studio lighting, 35mm photo",
  "n": 3, "output_dir": "assets/hero", "filename": "hero", "output_format": "webp"
}
// → /abs/assets/hero.webp, hero-1.webp, hero-2.webp + dtst://artifact/<id> for each

edit_image {
  "prompt": "add a warm sunset behind the panda",
  "images": ["dtst://artifact/<id>"],
  "output_path": "assets/hero/hero-sunset.webp"
}

Saving to a local file

Images are written to disk by default. output_path wins over output_dir; filename sets the name and the extension is added from the returned type. Relative paths resolve against DTST_WORKSPACE (default: the directory the server was started in), or DTST_OUTPUT_DIR when set. overwrite: false (default) never clobbers — it appends -1, -2, … save: false skips the disk entirely, inline: false skips the base64 preview.

generate_image { "prompt": "…", "output_path": "~/Desktop/panda.png" }
generate_image { "prompt": "…", "n": 3, "output_dir": "out", "filename": "icon" }
generate_image { "prompt": "…", "save": false, "inline": false }   // preview only

Writes are atomic, and each result carries the absolute path, a file:// resource link and a dtst://artifact/<id> URI for later calls in the same session. DTST_ALLOWED_WRITE_ROOTS=/a:/b confines writes to those directories.

CLI

The same operations without an MCP client:

img generate "a red panda astronaut, studio lighting" --out-dir out
img edit "make it a watercolour" -i out/panda.png --out out/panda-water.png
img models
img --help

MIT licensed.