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

vases-mcp

v1.1.0

Published

A small MCP server that can expose local tools and proxy tools from other MCP servers under a namespace such as `github.{toolName}` or `slack.{toolName}`.

Readme

vases-mcp

A small MCP server that can expose local tools and proxy tools from other MCP servers under a namespace such as github.{toolName} or slack.{toolName}.

What changed

This version supports:

  • built-in tool proxy modules for GitHub and Slack MCP servers
  • generic remote MCP proxy modules for any upstream MCP server
  • installable module loading from npm packages or local file paths
  • module config JSON for clean deployment

Install

npm install
npm run build

Start

npm start

CLI

vases-mcp --module-config ./examples/github-slack.modules.json

CLI options

  • --port <port>: run as an HTTP MCP server; if omitted, the server uses stdio unless PORT is set in the environment
  • --host <host>: HTTP bind host
  • --path <path>: HTTP MCP route path
  • --module <specifier>: install a module from an npm package or local file
  • --module-config <path>: load JSON module config
  • --no-default-tools: disable the built-in ping, add, and vases.* tools

Transport selection

  • No --port and no PORT env: runs over stdio
  • --port or PORT env set: runs as a streamable HTTP MCP server

Built-in GitHub / Slack proxy modules

Create a config file like this:

{
  "modules": [
    {
      "module": "builtin:github",
      "options": {
        "remote": {
          "type": "streamable-http",
          "url": "http://127.0.0.1:9001/mcp"
        }
      }
    },
    {
      "module": "builtin:slack",
      "options": {
        "remote": {
          "type": "stdio",
          "command": "npx",
          "args": ["-y", "your-slack-mcp-server-package"]
        }
      }
    }
  ]
}

When loaded, tools from the upstream servers are re-registered into this server as:

  • github.{toolName}
  • slack.{toolName}

Programmatic usage

import {
  HttpMcpServer,
  createGithubProxyModule,
  createSlackProxyModule,
} from 'vases-mcp';

const server = new HttpMcpServer({
  port: 8282,
  modules: [
    createGithubProxyModule({
      remote: {
        type: 'streamable-http',
        url: 'http://127.0.0.1:9001/mcp',
      },
    }),
    createSlackProxyModule({
      remote: {
        type: 'stdio',
        command: 'npx',
        args: ['-y', 'your-slack-mcp-server-package'],
      },
    }),
  ],
});

await server.start();

External installable module packages

You can publish your own module package and load it with --module your-package-name.

Example package entry:

import { createRemoteToolProxyModule } from 'vases-mcp';

export default function createModule() {
  return createRemoteToolProxyModule({
    namespace: 'github',
    remote: {
      type: 'streamable-http',
      url: 'http://127.0.0.1:9001/mcp',
    },
  });
}

Your module package should export one of these:

  • default
  • createModule
  • moduleFactory

Each must return a valid Vases MCP module object with an install() function.

Notes

  • The proxy layer currently focuses on tools.
  • Resource/prompt proxying can be added later with the same module pattern.
  • Upstream MCP tools are discovered via listTools() and forwarded through callTool().

Built-in Vases tools

Default tools now include:

  • vases.stock.recommendations.get
  • vases.user.subscription.get
  • vases.user.stockAgentPrompts.get
  • vases.stock.domestic.query
  • vases.stock.tradeConfig.get
  • vases.stock.tradeConfig.update
  • vases.stock.tradeCandidates.list
  • vases.stock.tradeCandidates.upsert
  • vases.stock.tradeLogs.list
  • vases.stock.tradeScore.get
  • vases.stock.chart.inspect

These tools read credentials from environment variables:

VASES_API_KEY=your_api_key
VASES_API_SECRET=your_api_secret
VASES_BASE_URL=https://vases.app

VASES_BASE_URL is optional and defaults to https://vases.app.

vases.user.subscription.get wraps GET /api/user/subscription/status. Use it to confirm whether the configured VASES API credentials belong to a free, PLUS, PRO, or admin account. The response also includes chartInspectApiAllowed, which is true only for PRO and admin accounts.

vases.user.stockAgentPrompts.get wraps GET /api/user/stock-agent-prompts. Use it to fetch server-generated Codex stock automation prompts for the authenticated VASES account. API key authentication returns automation-mode prompts. The response never includes the raw Kiwoom access token; it only reports whether a server-stored Kiwoom token is available.

Input schema

{
  "type": "marketReboundEntry"
}
  • type: optional prompt type. Supported values are all, recommendationFilter, domesticChartScoreFilter, averagingDown, and marketReboundEntry. If omitted or all, the API returns every prompt allowed for the authenticated account.

vases.stock.recommendations.get wraps GET /api/stock/domestic/recommendation-summary.

Input schema

{
  "date": "2026-05-08"
}
  • date: optional YYYY-MM-DD string. If omitted, the API returns the latest available recommendation summary.

Output schema

The tool returns the API response as-is in both content[].text and structuredContent. The top-level payload shape is:

type BaseResponse<T> = {
  success: boolean;
  result: T;
  message?: string | null;
  error?: unknown;
};

For this tool, result is RecommendationSummaryResponse | null.

type RecommendationBucket =
  | "readyToBuy"
  | "watching"
  | "reached"
  | "expired";

type RecommendationFinanceStatus =
  | "양호"
  | "보통"
  | "주의"
  | "위험";

type RecommendationSummaryItem = {
  stockCode: string;
  stockName: string;
  marketName: string;
  industryName: string;
  suggestDate: string;
  suggestDateValue: number;
  suggestClose: number;
  currentClose: number;
  currentReturnRate: number;
  maxReturnRate: number;
  volume: number;
  volumeRate: number;
  savedAsCandidate: boolean;
  holding: boolean;
  buyCount: number;
  remainDays: number;
  reachedTarget: boolean;
  bucket: RecommendationBucket;
  tags: string[];
  financeStatus: RecommendationFinanceStatus;
  financeNote: string;
  financeMetrics: {
    per: number;
    pbr: number;
    roe: number;
    saleAmt: number;
    busPro: number;
  };
};

type RecommendationSummaryResponse = {
  asOfDate: string;
  availableDates: string[];
  config: {
    successRate: number;
    withinDays: number;
    buyRatioPerTime: number;
    buyLimitPerStock: number;
    maxInvestmentRatio: number;
    mode: string;
  };
  overview: {
    totalRecommended: number;
    profitableNow: number;
    pendingNow: number;
    reachedTarget: number;
    candidateSavedCount: number;
    holdingTrackedCount: number;
    avgCurrentReturn: number;
    avgMaxReturn: number;
  };
  buckets: Record<RecommendationBucket, RecommendationSummaryItem[]>;
  insights: {
    topIndustry: string | null;
    avgVolumeRate: number;
    duplicateHoldingCount: number;
    recentBuyLogs: number;
    recentSellLogs: number;
  };
  timeline: Array<{
    date: string;
    recommended: number;
    avgVolumeRate: number;
  }>;
};

Bucket semantics

  • readyToBuy: near the recommendation price and not yet reached the configured target.
  • watching: still active, but price/action needs more confirmation.
  • reached: hit the configured success threshold at least once.
  • expired: exceeded the configured observation window or needs cleanup review.

Notes

  • Candidate and holding flags are user-specific because the endpoint reads the authenticated user's trade config, trade candidates, and trade logs.
  • The summary can differ across users even on the same date.
  • This tool replaces the old vases.stock.getSuggestStocks tool.

vases.stock.domestic.query wraps POST /api/stock/domestic/query. This read-only stock screener API requires VASES PLUS, PRO, or admin credentials. It supports keyword search, market selection, exact code lists, AND-combined filters, multi-column sorting, and pagination.

Input schema

{
  "page": 1,
  "pageSize": 30,
  "search": "반도체",
  "markets": ["KOSPI", "KOSDAQ"],
  "codes": ["005930", "000660"],
  "filters": [
    { "field": "flu_rt", "operator": "gte", "value": 1 },
    { "field": "trde_qty", "operator": "gte", "value": 100000 },
    { "field": "per", "operator": "between", "values": [0, 30] }
  ],
  "sorts": [
    { "field": "trde_qty", "direction": "desc" },
    { "field": "flu_rt", "direction": "desc" }
  ]
}

Common filter/sort fields:

  • identity/text: code, name, marketName, upName, state, auditInfo, orderWarning
  • price/flow: lastPrice, flu_rt, trde_qty, trde_qty_rate
  • valuation/finance: per, pbr, roe, eps, sale_amt, bus_pro, bus_pro_rate, crd_rt, cap

Operators:

  • text: eq, ne, contains, startsWith, endsWith, in
  • numeric: eq, ne, gt, gte, lt, lte, between, in

vases.stock.tradeScore.get wraps POST /api/user/trade/score. Use it to calculate the current production finalScore, selectionScore, and riskScore for a single Korean stock. The tool is read-only and accepts the same latest-candle ohlcOverride style used by chart inspection.

Input schema

{
  "stock_code": "005930",
  "stock_name": "Samsung Electronics",
  "visibleDays": 220,
  "targetDate": "2026-05-14",
  "suggestClose": 70500,
  "ohlcOverride": {
    "date": "2026-05-14",
    "open": 70000,
    "high": 71000,
    "low": 69000,
    "close": 70500,
    "volume": 1234567
  }
}
  • stock_code: required 6-digit Korean stock code.
  • stock_name: optional stock name echoed in the response.
  • visibleDays: optional recent trading days to load. The API uses at least 220 days for score metrics.
  • targetDate: optional date/timestamp for historical scoring.
  • suggestClose: optional recommendation/base close for currentReturnRate.
  • ohlcOverride: optional latest candle override. If its date is newer than the saved candle, the API appends it; otherwise it replaces the latest candle.

Score interpretation

  • result.scores.finalScore: 0-100 overall recommendation quality. Higher is better. Bands are S(90+), A(80+), B(70+), C(60+), and D(<60).
  • result.scores.selectionScore: 0-100 legacy entry-quality/candidate guard. Higher is better, but it is not intended as the only sorter.
  • result.scores.riskScore: 0-100 alias of failureRiskScore. Lower is safer. Current calibration treats 60+ as the risk-block range.
  • result.interpretation: machine-readable guidance for agents explaining how to use the scores and current operating policy thresholds.

vases.stock.chart.inspect wraps POST /api/user/trade/vision. This read-only chart analysis API is available through API/MCP only to VASES PRO and admin accounts. PLUS and free API credentials are rejected by the VASES API. The tool does not place orders or change trade settings.

Input schema

{
  "stock_code": "005930",
  "stock_name": "삼성전자",
  "visibleDays": 80,
  "targetDate": "2026-05-14",
  "ohlcOverride": {
    "date": "2026-05-14",
    "open": 70000,
    "high": 71000,
    "low": 69000,
    "close": 70500,
    "volume": 1234567
  }
}
  • stock_code: required Korean stock code.
  • stock_name: required Korean stock name.
  • visibleDays: optional number of recent trading days, default 80.
  • targetDate: optional date/timestamp for inspecting a historical point.
  • ohlcOverride: optional latest candle override for fresher market data.

Built-in Kiwoom tools

Kiwoom tools read the access token from an environment variable:

KIWOOM_ACCESS_TOKEN=your_kiwoom_access_token
KIWOOM_BASE_URL=https://api.kiwoom.com

Kiwoom data/order tools use KIWOOM_ACCESS_TOKEN unless an accessToken input is provided. KIWOOM_BASE_URL is optional and defaults to https://api.kiwoom.com.

For Kiwoom quote/current-price/day-candle lookups, stockCode is passed through as Kiwoom stk_cd. Use the plain 6-digit code for KRX, append _NX for NXT, or append _AL for SOR. Example codes: 039490, 039490_NX, 039490_AL. Do not include labels such as KRX: in the actual input.

Kiwoom account and buy/sell order tools accept domesticExchange, which is passed as Kiwoom dmst_stex_tp. Supported values are KRX and NXT; the default is KRX.