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

qqdocs

v1.25.0

Published

Tencent Docs (docs.qq.com) CLI and library — thin MCP JSON-RPC client.

Readme

qqdocs

Tencent Docs (docs.qq.com) CLI and library. Thin wrapper over the MCP JSON-RPC endpoints — no SDK, no handshake, one HTTP POST per call.

Requirements

Bun ≥ 1.x. The CLI is shipped as .ts with a Bun shebang, so node/npx is not supported — use bun/bunx.

Install

bunx qqdocs ls        # run without install
bun add qqdocs        # library
bun add -g qqdocs     # `qqdocs` CLI

Published binaries:

  • qqdocs (canonical)
  • qqdoc (typo-tolerant alias)

Auth

Get a token from docs.qq.com MCP settings and either:

  • export TENCENT_DOCS_TOKEN=... in your shell, or
  • put TENCENT_DOCS_TOKEN=... in a .env.local file. Lookup order (first hit wins): package dir, its parents, the current working directory, and $HOME/.qqdocs/.env.local.

Non-secret defaults (e.g. default space, default permission) can live in a YAML config. Lookup order:

  • $PWD/.qqdocs/config.yaml
  • $PWD/.qqdocs.config.yaml
  • $HOME/.qqdocs/config.yaml
  • $HOME/.qqdocs.config.yaml

CLI

A public read-only example document is available at: https://docs.qq.com/aio/DZEZ6TEFiQmpGdUJy (name: qqdocs-example, ID: dFzLAbBjFuBr)

qqdocs tools [pattern]                                # list live MCP tools
qqdocs raw <tool> --json '{"file_id":"..."}'          # raw tool call

qqdocs ls [--json]                                   # recent documents
qqdocs ls [root|<folder-id>|<name/subname>] [--json] # root, folder ID, or path navigation
qqdocs ls --dates                                    # include last-modified dates
qqdocs search <query> [--json]                       # keyword search
qqdocs read <ref>                 # read document content
qqdocs rename <ref> <new-title>   # rename (alias: mv)
qqdocs open <ref>                 # open in browser
qqdocs cp <ref> [--title <t>]     # copy document (alias: copy)
qqdocs delete <ref>                       # dry run; prints delete confirm code (alias: rm)
qqdocs delete <ref> --confirm=1234        # delete using current content-hash code
qqdocs delete <ref> -c 1234               # same as --confirm
qqdocs info <ref> [--json]                # document metadata
qqdocs import <path> [--title <title>]                # import pdf/docx/pptx/... or ingest .md/.mdx
qqdocs perm get <ref>                     # read permission
qqdocs perm set <ref> <private|link-read|link-edit>

qqdocs space list [--scope all|mine|joined]
qqdocs space create <title> [--description <text>]
qqdocs space ls <space-id> [--parent <node-id>] [--page <n>]
qqdocs space mkdir <space-id> <title> [--parent <node-id>]
qqdocs space mkdoc <space-id> <title> [--type smartcanvas|doc|sheet|slide|mind|flowchart|smartsheet|form]
qqdocs space link <space-id> <title> <url> [--description <text>]
qqdocs space rm <space-id> <node-id> [--all]
qqdocs space move <ref> <space-id> [--parent <node-id>]

qqdocs canvas read <ref> [--page <page-id>] [--size <n>] [--next <token>] [--all]
qqdocs canvas find <ref> <query>
qqdocs canvas edit <ref> <insert-before|insert-after|append|update|delete>
                 [--id <block-id>] [--content '<mdx>']

qqdocs create <title> [--type smartcanvas|doc|sheet|slide|mind|flowchart|smartsheet|form]
                      [--format mdx|markdown]
                      [--content '<mdx-or-markdown>']
                      [--perm private|link-read|link-edit]

qqdocs flowchart <title> --mermaid 'graph LR; A-->B'  # create flowchart/UML/infra diagram from Mermaid
qqdocs flowchart <title> --file diagram.mmd          # read Mermaid from file
qqdocs sync                                          # cache recent + root docs to ~/.qqdocs/cache.json
qqdocs usage [--tier free|member|plus]               # show API call quota progress bars
qqdocs completion                                    # prints a shell completion script

Shell completion

qqdocs completion prints a completion script. Source it from your shell rc:

qqdocs completion >> ~/.zshrc     # zsh
qqdocs completion >> ~/.bashrc    # bash

The live Tencent Docs MCP surface changes over time. qqdocs tools is the source of truth for what the current server actually exposes.

File arguments accept a raw file_id, a full docs.qq.com URL, or a filename. When a filename is given, qqdocs searches Tencent Docs and resolves to a unique match; if multiple documents share the name the command throws a list of candidates so you can disambiguate by ID, URL, or rename.

qqdocs delete is intentionally two-step. Running it without --confirm does a dry run and prints the current 4-digit confirmation code derived from the document's current content. The delete only happens when that exact code is passed back via --confirm=<4-digit-code>, so if the content changes, the code changes.

qqdocs import supports:

  • Markdown sources: .md, .markdown, .mdx
  • Tencent async import formats: xls, xlsx, csv, doc, docx, txt, text, ppt, pptx, pdf, xmind

For .md and .markdown, the CLI creates a smartcanvas document with content_format=markdown. For .mdx, it creates a smartcanvas document with MDX content. For the importable binary/text formats, the CLI uploads the local file, starts Tencent Docs async import, waits for completion, and can optionally rename the result with --title.

Permission policies:

  • private
  • link-read
  • link-edit

New documents are private by default. qqdocs perm get can report all three states. qqdocs perm set accepts private|link-read|link-edit, but Tencent Docs MCP currently only supports setting the public modes, so private prints a clear unsupported message. The create command also prints the new document's initial policy plus ready-to-run qqdocs perm get and qqdocs perm set commands.

Library

import {
  callTool,
  copyDoc,
  createDoc,
  getFolderMeta,
  listFolderContents,
  loadSyncCache,
  resolveFolderId,
  syncDocs,
  createSpace,
  createSpaceDocNode,
  editCanvas,
  findCanvasBlocks,
  getDocInfo,
  getDocDeleteConfirmCode,
  importLocalFile,
  getDocPermission,
  listRecent,
  listSpaceNodes,
  listSpaces,
  listTools,
  renameDoc,
  readCanvas,
  readDoc,
  searchDocs,
  setDocPermission,
} from "qqdocs";

const tools = await listTools("space");
const files = await listRecent(10);
const hits = await searchDocs("Q4 planning");
const content = await readDoc("YOUR_FILE_ID");
const info = await getDocInfo("YOUR_FILE_ID");
const deleteConfirmCode = await getDocDeleteConfirmCode("YOUR_FILE_ID");
const permission = await getDocPermission("YOUR_FILE_ID");
await setDocPermission("YOUR_FILE_ID", "link-read");

const spaces = await listSpaces({ scope: "all" });
const space = await createSpace("Docs Playground");
const nodes = await listSpaceNodes("space_id_here");
const node = await createSpaceDocNode("space_id_here", "New Space Doc", "smartcanvas");

const canvas = await readCanvas("YOUR_FILE_ID");
const blocks = await findCanvasBlocks("YOUR_FILE_ID", "Hello");
await editCanvas("YOUR_FILE_ID", "append", { content: "<Text>Hello</Text>" });

const raw = await callTool("manage.query_file_info", { file_id: "YOUR_FILE_ID" });
const { url } = await createDoc("New Doc", "smartcanvas", {
  content: "# Hello",
  contentFormat: "markdown",
});
const imported = await importLocalFile("./report.pdf");
await renameDoc(imported.file_id, "Quarterly Report");
const copy = await copyDoc("YOUR_FILE_ID");

All functions throw on MCP errors (Error: MCP error: <message>).

License

MIT