Skip to content

Commit ff0a397

Browse files
authored
fix: mcp logs error with stdio transport (#223)
* fix: mcp logs error with stdio transport * test: add coverage and badge
1 parent 073c757 commit ff0a397

File tree

7 files changed

+89
-8
lines changed

7 files changed

+89
-8
lines changed

.codecov.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Setting coverage targets per flag
2+
coverage:
3+
round: down
4+
range: 60..90
5+
precision: 2
6+
status:
7+
patch: off
8+
project:
9+
default: off
10+
mcp-server-chart:
11+
threshold: 1%
12+
flags:
13+
- mcp-server-chart
14+
15+
flags:
16+
mcp-server-chart:
17+
paths:
18+
# filter the folder(s) you wish to measure by that flag
19+
- src
20+
21+
comment:
22+
layout: "reach, diff, flags, files"
23+
behavior: default
24+
require_changes: true # only post the comment if coverage changes
25+
26+
github_checks:
27+
annotations: false
28+
29+
flag_management:
30+
default_rules:
31+
carryforward: false

.github/workflows/build.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,10 @@ jobs:
2323
run: |
2424
npm install
2525
npm run build
26-
npx vitest --watch=false --testTimeout=20000
26+
npx vitest --coverage --watch=false
27+
28+
- name: Upload coverage reports to Codecov
29+
uses: codecov/codecov-action@v5
30+
with:
31+
token: ${{ secrets.CODECOV_TOKEN }}
32+
slug: antvis/mcp-server-chart

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# MCP Server Chart ![](https://badge.mcpx.dev?type=server "MCP Server") [![build](https://github.com/antvis/mcp-server-chart/actions/workflows/build.yml/badge.svg)](https://github.com/antvis/mcp-server-chart/actions/workflows/build.yml) [![npm Version](https://img.shields.io/npm/v/@antv/mcp-server-chart.svg)](https://www.npmjs.com/package/@antv/mcp-server-chart) [![smithery badge](https://smithery.ai/badge/@antvis/mcp-server-chart)](https://smithery.ai/server/@antvis/mcp-server-chart) [![npm License](https://img.shields.io/npm/l/@antv/mcp-server-chart.svg)](https://www.npmjs.com/package/@antv/mcp-server-chart) [![Trust Score](https://archestra.ai/mcp-catalog/api/badge/quality/antvis/mcp-server-chart)](https://archestra.ai/mcp-catalog/antvis__mcp-server-chart)
1+
# MCP Server Chart ![](https://badge.mcpx.dev?type=server "MCP Server") [![build](https://github.com/antvis/mcp-server-chart/actions/workflows/build.yml/badge.svg)](https://github.com/antvis/mcp-server-chart/actions/workflows/build.yml) [![npm Version](https://img.shields.io/npm/v/@antv/mcp-server-chart.svg)](https://www.npmjs.com/package/@antv/mcp-server-chart) [![smithery badge](https://smithery.ai/badge/@antvis/mcp-server-chart)](https://smithery.ai/server/@antvis/mcp-server-chart) [![npm License](https://img.shields.io/npm/l/@antv/mcp-server-chart.svg)](https://www.npmjs.com/package/@antv/mcp-server-chart) [![Trust Score](https://archestra.ai/mcp-catalog/api/badge/quality/antvis/mcp-server-chart)](https://archestra.ai/mcp-catalog/antvis__mcp-server-chart) [![codecov](https://codecov.io/gh/antvis/mcp-server-chart/graph/badge.svg?token=7R98VGO5GL)](https://codecov.io/gh/antvis/mcp-server-chart)
22

33
A Model Context Protocol server for generating charts using [AntV](https://github.com/antvis/). We can use this mcp server for _chart generation_ and _data analysis_.
44

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@antv/mcp-server-chart",
33
"description": "A Model Context Protocol server for generating charts using AntV. This is a TypeScript-based MCP server that provides chart generation capabilities. It allows you to create various types of charts through MCP tools.",
4-
"version": "0.9.2",
4+
"version": "0.9.3",
55
"main": "build/index.js",
66
"types": "build/index.d.ts",
77
"exports": {
@@ -14,7 +14,7 @@
1414
"start": "npx @modelcontextprotocol/inspector node build/index.js",
1515
"prepare": "husky && npm run build",
1616
"prepublishOnly": "npm run build",
17-
"test": "vitest --testTimeout=20000"
17+
"test": "vitest"
1818
},
1919
"lint-staged": {
2020
"*.{ts,js,json}": [
@@ -55,6 +55,7 @@
5555
"@types/cors": "^2.8.19",
5656
"@types/express": "^5.0.3",
5757
"@types/node": "^22.15.21",
58+
"@vitest/coverage-v8": "3.2.4",
5859
"husky": "^9.1.7",
5960
"lint-staged": "^15.5.2",
6061
"tsc-alias": "^1.8.16",

src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
runSSEServer,
66
runStdioServer,
77
} from "./server";
8+
import { logger } from "./utils/logger";
89

910
// Parse command line arguments
1011
const { values } = parseArgs({
@@ -57,17 +58,20 @@ Options:
5758
const transport = values.transport.toLowerCase();
5859

5960
if (transport === "sse") {
61+
logger.setIsStdio(false);
6062
const port = Number.parseInt(values.port as string, 10);
6163
// Use provided endpoint or default to "/sse" for SSE
6264
const endpoint = values.endpoint || "/sse";
6365
const host = values.host || "localhost";
6466
runSSEServer(host, port, endpoint).catch(console.error);
6567
} else if (transport === "streamable") {
68+
logger.setIsStdio(false);
6669
const port = Number.parseInt(values.port as string, 10);
6770
// Use provided endpoint or default to "/mcp" for streamable
6871
const endpoint = values.endpoint || "/mcp";
6972
const host = values.host || "localhost";
7073
runHTTPStreamableServer(host, port, endpoint).catch(console.error);
7174
} else {
75+
logger.setIsStdio(true);
7276
runStdioServer().catch(console.error);
7377
}

src/utils/logger.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,51 @@
33
*/
44
const prefix = "[MCP-Server-Chart]";
55

6+
/**
7+
* Indicates if the logger is in stdio mode.
8+
* When true, logs are directed to stderr for info, warn, and success messages, using console.error.
9+
* When false, logs are directed to stdout.
10+
*/
11+
let IS_STDIO = true;
12+
13+
function setIsStdio(isStdio: boolean): void {
14+
IS_STDIO = isStdio;
15+
}
16+
17+
function getPrefix(): string {
18+
const timestamp = new Date().toISOString();
19+
return `${prefix} ${timestamp}`;
20+
}
21+
622
/**
723
* Log info message
824
*/
925
function info(message: string, ...args: unknown[]): void {
10-
console.log(`${prefix} ℹ️ ${message}`, ...args);
26+
const fn = IS_STDIO ? console.error : console.log;
27+
fn(`${getPrefix()} ℹ️ ${message}`, ...args);
1128
}
1229

1330
/**
1431
* Log warning message
1532
*/
1633
function warn(message: string, ...args: unknown[]): void {
17-
console.warn(`${prefix} ⚠️ ${message}`, ...args);
34+
const fn = IS_STDIO ? console.warn : console.log;
35+
fn(`${getPrefix()} ⚠️ ${message}`, ...args);
1836
}
1937

2038
/**
2139
* Log error message
2240
*/
2341
function error(message: string, error?: unknown): void {
24-
console.error(`${prefix}${message}`, error || "");
42+
console.error(`${getPrefix()}${message}`, error || "");
2543
}
2644

2745
/**
2846
* Log success message
2947
*/
3048
function success(message: string, ...args: unknown[]): void {
31-
console.log(`${prefix}${message}`, ...args);
49+
const fn = IS_STDIO ? console.error : console.log;
50+
fn(`${getPrefix()}${message}`, ...args);
3251
}
3352

3453
/**
@@ -39,4 +58,5 @@ export const logger = {
3958
warn,
4059
error,
4160
success,
61+
setIsStdio,
4262
};

vitest.config.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { coverageConfigDefaults, defineConfig } from "vitest/config";
2+
3+
const enableCoverage = process.argv.includes("--coverage");
4+
5+
export default defineConfig({
6+
resolve: {},
7+
test: {
8+
testTimeout: 20_000,
9+
hookTimeout: 20_000,
10+
include: ["__tests__/**/*.{test,spec}.?(c|m)[jt]s?(x)"],
11+
...(enableCoverage
12+
? {
13+
coverage: {
14+
exclude: ["**/build/**", ...coverageConfigDefaults.exclude],
15+
},
16+
}
17+
: {}),
18+
},
19+
});

0 commit comments

Comments
 (0)