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 buildStart
npm startCLI
vases-mcp --module-config ./examples/github-slack.modules.jsonCLI options
--port <port>: run as an HTTP MCP server; if omitted, the server uses stdio unlessPORTis 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-inping,add, andvases.*tools
Transport selection
- No
--portand noPORTenv: runs over stdio --portorPORTenv 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:
defaultcreateModulemoduleFactory
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 throughcallTool().
Built-in Vases tools
Default tools now include:
vases.stock.recommendations.getvases.user.subscription.getvases.user.stockAgentPrompts.getvases.stock.domestic.queryvases.stock.tradeConfig.getvases.stock.tradeConfig.updatevases.stock.tradeCandidates.listvases.stock.tradeCandidates.upsertvases.stock.tradeLogs.listvases.stock.tradeScore.getvases.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.appVASES_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 areall,recommendationFilter,domesticChartScoreFilter,averagingDown, andmarketReboundEntry. If omitted orall, 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: optionalYYYY-MM-DDstring. 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.getSuggestStockstool.
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 forcurrentReturnRate.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 offailureRiskScore. 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, default80.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.comKiwoom 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.
