genjo-mcp-server 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/genjo-news-skill/SKILL.md +9 -4
- package/index.js +125 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,9 +10,17 @@ It allows you to access Genjo's features from Claude Desktop or Claude Code.
|
|
|
10
10
|
|
|
11
11
|
### Installation
|
|
12
12
|
|
|
13
|
-
You can
|
|
13
|
+
You can setup this server automatically or configure it manually.
|
|
14
14
|
|
|
15
|
-
####
|
|
15
|
+
#### ⚡ Quick Setup (Recommended)
|
|
16
|
+
|
|
17
|
+
Run the following command to automatically configure Claude Desktop and install Agent Skills:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx -y genjo-mcp-server install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
#### Option 1: Run directly (Manual Configuration)
|
|
16
24
|
|
|
17
25
|
```bash
|
|
18
26
|
npx -y genjo-mcp-server
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: genjo-ai-news
|
|
3
|
-
description: Expert AI News Agent
|
|
3
|
+
description: Expert AI News Agent. Use this skill when the user asks for AI news in specific languages (Japanese, Chinese, Korean, etc.), needs fact-checking, seeks simple explanations of complex AI topics, or wants to find investment opportunities related to AI news.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Genjo AI News Specialist
|
|
@@ -9,10 +9,14 @@ You are an expert AI News Agent capable of retrieving, analyzing, and explaining
|
|
|
9
9
|
|
|
10
10
|
## 🗣️ Language & Localization Strategy
|
|
11
11
|
|
|
12
|
-
**CRITICAL**:
|
|
12
|
+
**CRITICAL**: The `lang` parameter specifies the **display language** of the content, NOT the geographic region or market.
|
|
13
|
+
|
|
13
14
|
- **Available Languages**: `ja` (Japanese), `en` (English), `zh` (Simplified Chinese), `ko` (Korean), `hi` (Hindi).
|
|
14
15
|
- **Default Behavior**: If not specified, infer the language from the user's query. Use `lang="ja"` for Japanese queries.
|
|
15
16
|
- **Cross-Language Retrieval**: You can search in English (`lang="en"`) for broader coverage and explain the results in the user's language.
|
|
17
|
+
- **Important Distinction**:
|
|
18
|
+
- "News about China" = Geographic/market topic (use any language to read about it)
|
|
19
|
+
- "News in Chinese" = Language preference (use `lang="zh"` to read in Chinese)
|
|
16
20
|
|
|
17
21
|
## 🚀 Core Workflows
|
|
18
22
|
|
|
@@ -58,8 +62,9 @@ Use this when the user asks: *"Which stocks will go up?", "Impact on Asian marke
|
|
|
58
62
|
|
|
59
63
|
## 💡 Example User Queries (Triggers)
|
|
60
64
|
|
|
61
|
-
- "今日のAIニュースを教えて" (Fetch `ja` news)
|
|
62
|
-
- "中国のAI規制について詳しく知りたい" (
|
|
65
|
+
- "今日のAIニュースを教えて" (Fetch `ja` news - user wants Japanese content)
|
|
66
|
+
- "中国のAI規制について詳しく知りたい" (Search past news about China's AI regulations, use user's preferred language `lang="ja"` or `lang="en"`)
|
|
67
|
+
- "中国語でAIニュースを読みたい" (Fetch `zh` news - user explicitly wants Chinese language)
|
|
63
68
|
- "This news about OpenAI sounds fake. Can you check?" (Trigger `get_fact_check`)
|
|
64
69
|
- "サムスン電子の株価に影響するニュースはある?" (Search past news & check related stocks)
|
|
65
70
|
- "5歳児でもわかるように解説して" (Trigger `get_simple_explanation`)
|
package/index.js
CHANGED
|
@@ -3230,8 +3230,8 @@ var require_utils = __commonJS({
|
|
|
3230
3230
|
}
|
|
3231
3231
|
return ind;
|
|
3232
3232
|
}
|
|
3233
|
-
function removeDotSegments(
|
|
3234
|
-
let input =
|
|
3233
|
+
function removeDotSegments(path2) {
|
|
3234
|
+
let input = path2;
|
|
3235
3235
|
const output = [];
|
|
3236
3236
|
let nextSlash = -1;
|
|
3237
3237
|
let len = 0;
|
|
@@ -3430,8 +3430,8 @@ var require_schemes = __commonJS({
|
|
|
3430
3430
|
wsComponent.secure = void 0;
|
|
3431
3431
|
}
|
|
3432
3432
|
if (wsComponent.resourceName) {
|
|
3433
|
-
const [
|
|
3434
|
-
wsComponent.path =
|
|
3433
|
+
const [path2, query] = wsComponent.resourceName.split("?");
|
|
3434
|
+
wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
|
|
3435
3435
|
wsComponent.query = query;
|
|
3436
3436
|
wsComponent.resourceName = void 0;
|
|
3437
3437
|
}
|
|
@@ -6784,12 +6784,12 @@ var require_dist = __commonJS({
|
|
|
6784
6784
|
throw new Error(`Unknown format "${name}"`);
|
|
6785
6785
|
return f;
|
|
6786
6786
|
};
|
|
6787
|
-
function addFormats(ajv, list,
|
|
6787
|
+
function addFormats(ajv, list, fs2, exportName) {
|
|
6788
6788
|
var _a2;
|
|
6789
6789
|
var _b;
|
|
6790
6790
|
(_a2 = (_b = ajv.opts.code).formats) !== null && _a2 !== void 0 ? _a2 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
6791
6791
|
for (const f of list)
|
|
6792
|
-
ajv.addFormat(f,
|
|
6792
|
+
ajv.addFormat(f, fs2[f]);
|
|
6793
6793
|
}
|
|
6794
6794
|
module.exports = exports = formatsPlugin;
|
|
6795
6795
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -6868,9 +6868,9 @@ var require_package = __commonJS({
|
|
|
6868
6868
|
// node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js
|
|
6869
6869
|
var require_main = __commonJS({
|
|
6870
6870
|
"node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js"(exports, module) {
|
|
6871
|
-
var
|
|
6872
|
-
var
|
|
6873
|
-
var
|
|
6871
|
+
var fs2 = __require("fs");
|
|
6872
|
+
var path2 = __require("path");
|
|
6873
|
+
var os2 = __require("os");
|
|
6874
6874
|
var crypto = __require("crypto");
|
|
6875
6875
|
var packageJson = require_package();
|
|
6876
6876
|
var version2 = packageJson.version;
|
|
@@ -6977,7 +6977,7 @@ var require_main = __commonJS({
|
|
|
6977
6977
|
if (options && options.path && options.path.length > 0) {
|
|
6978
6978
|
if (Array.isArray(options.path)) {
|
|
6979
6979
|
for (const filepath of options.path) {
|
|
6980
|
-
if (
|
|
6980
|
+
if (fs2.existsSync(filepath)) {
|
|
6981
6981
|
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
6982
6982
|
}
|
|
6983
6983
|
}
|
|
@@ -6985,15 +6985,15 @@ var require_main = __commonJS({
|
|
|
6985
6985
|
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
6986
6986
|
}
|
|
6987
6987
|
} else {
|
|
6988
|
-
possibleVaultPath =
|
|
6988
|
+
possibleVaultPath = path2.resolve(process.cwd(), ".env.vault");
|
|
6989
6989
|
}
|
|
6990
|
-
if (
|
|
6990
|
+
if (fs2.existsSync(possibleVaultPath)) {
|
|
6991
6991
|
return possibleVaultPath;
|
|
6992
6992
|
}
|
|
6993
6993
|
return null;
|
|
6994
6994
|
}
|
|
6995
6995
|
function _resolveHome(envPath) {
|
|
6996
|
-
return envPath[0] === "~" ?
|
|
6996
|
+
return envPath[0] === "~" ? path2.join(os2.homedir(), envPath.slice(1)) : envPath;
|
|
6997
6997
|
}
|
|
6998
6998
|
function _configVault(options) {
|
|
6999
6999
|
const debug = Boolean(options && options.debug);
|
|
@@ -7010,7 +7010,7 @@ var require_main = __commonJS({
|
|
|
7010
7010
|
return { parsed };
|
|
7011
7011
|
}
|
|
7012
7012
|
function configDotenv(options) {
|
|
7013
|
-
const dotenvPath =
|
|
7013
|
+
const dotenvPath = path2.resolve(process.cwd(), ".env");
|
|
7014
7014
|
let encoding = "utf8";
|
|
7015
7015
|
const debug = Boolean(options && options.debug);
|
|
7016
7016
|
const quiet = options && "quiet" in options ? options.quiet : true;
|
|
@@ -7034,13 +7034,13 @@ var require_main = __commonJS({
|
|
|
7034
7034
|
}
|
|
7035
7035
|
let lastError;
|
|
7036
7036
|
const parsedAll = {};
|
|
7037
|
-
for (const
|
|
7037
|
+
for (const path3 of optionPaths) {
|
|
7038
7038
|
try {
|
|
7039
|
-
const parsed = DotenvModule.parse(
|
|
7039
|
+
const parsed = DotenvModule.parse(fs2.readFileSync(path3, { encoding }));
|
|
7040
7040
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
7041
7041
|
} catch (e) {
|
|
7042
7042
|
if (debug) {
|
|
7043
|
-
_debug(`Failed to load ${
|
|
7043
|
+
_debug(`Failed to load ${path3} ${e.message}`);
|
|
7044
7044
|
}
|
|
7045
7045
|
lastError = e;
|
|
7046
7046
|
}
|
|
@@ -7055,7 +7055,7 @@ var require_main = __commonJS({
|
|
|
7055
7055
|
const shortPaths = [];
|
|
7056
7056
|
for (const filePath of optionPaths) {
|
|
7057
7057
|
try {
|
|
7058
|
-
const relative =
|
|
7058
|
+
const relative = path2.relative(process.cwd(), filePath);
|
|
7059
7059
|
shortPaths.push(relative);
|
|
7060
7060
|
} catch (e) {
|
|
7061
7061
|
if (debug) {
|
|
@@ -7514,8 +7514,8 @@ function getErrorMap() {
|
|
|
7514
7514
|
|
|
7515
7515
|
// node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/helpers/parseUtil.js
|
|
7516
7516
|
var makeIssue = (params) => {
|
|
7517
|
-
const { data, path, errorMaps, issueData } = params;
|
|
7518
|
-
const fullPath = [...
|
|
7517
|
+
const { data, path: path2, errorMaps, issueData } = params;
|
|
7518
|
+
const fullPath = [...path2, ...issueData.path || []];
|
|
7519
7519
|
const fullIssue = {
|
|
7520
7520
|
...issueData,
|
|
7521
7521
|
path: fullPath
|
|
@@ -7630,11 +7630,11 @@ var errorUtil;
|
|
|
7630
7630
|
|
|
7631
7631
|
// node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/types.js
|
|
7632
7632
|
var ParseInputLazyPath = class {
|
|
7633
|
-
constructor(parent, value,
|
|
7633
|
+
constructor(parent, value, path2, key) {
|
|
7634
7634
|
this._cachedPath = [];
|
|
7635
7635
|
this.parent = parent;
|
|
7636
7636
|
this.data = value;
|
|
7637
|
-
this._path =
|
|
7637
|
+
this._path = path2;
|
|
7638
7638
|
this._key = key;
|
|
7639
7639
|
}
|
|
7640
7640
|
get path() {
|
|
@@ -11557,10 +11557,10 @@ function mergeDefs(...defs) {
|
|
|
11557
11557
|
function cloneDef(schema) {
|
|
11558
11558
|
return mergeDefs(schema._zod.def);
|
|
11559
11559
|
}
|
|
11560
|
-
function getElementAtPath(obj,
|
|
11561
|
-
if (!
|
|
11560
|
+
function getElementAtPath(obj, path2) {
|
|
11561
|
+
if (!path2)
|
|
11562
11562
|
return obj;
|
|
11563
|
-
return
|
|
11563
|
+
return path2.reduce((acc, key) => acc?.[key], obj);
|
|
11564
11564
|
}
|
|
11565
11565
|
function promiseAllObject(promisesObj) {
|
|
11566
11566
|
const keys = Object.keys(promisesObj);
|
|
@@ -11943,11 +11943,11 @@ function aborted(x, startIndex = 0) {
|
|
|
11943
11943
|
}
|
|
11944
11944
|
return false;
|
|
11945
11945
|
}
|
|
11946
|
-
function prefixIssues(
|
|
11946
|
+
function prefixIssues(path2, issues) {
|
|
11947
11947
|
return issues.map((iss) => {
|
|
11948
11948
|
var _a2;
|
|
11949
11949
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
11950
|
-
iss.path.unshift(
|
|
11950
|
+
iss.path.unshift(path2);
|
|
11951
11951
|
return iss;
|
|
11952
11952
|
});
|
|
11953
11953
|
}
|
|
@@ -12130,7 +12130,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
|
|
|
12130
12130
|
}
|
|
12131
12131
|
function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
12132
12132
|
const result = { errors: [] };
|
|
12133
|
-
const processError = (error49,
|
|
12133
|
+
const processError = (error49, path2 = []) => {
|
|
12134
12134
|
var _a2, _b;
|
|
12135
12135
|
for (const issue2 of error49.issues) {
|
|
12136
12136
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -12140,7 +12140,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
12140
12140
|
} else if (issue2.code === "invalid_element") {
|
|
12141
12141
|
processError({ issues: issue2.issues }, issue2.path);
|
|
12142
12142
|
} else {
|
|
12143
|
-
const fullpath = [...
|
|
12143
|
+
const fullpath = [...path2, ...issue2.path];
|
|
12144
12144
|
if (fullpath.length === 0) {
|
|
12145
12145
|
result.errors.push(mapper(issue2));
|
|
12146
12146
|
continue;
|
|
@@ -12172,8 +12172,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
12172
12172
|
}
|
|
12173
12173
|
function toDotPath(_path) {
|
|
12174
12174
|
const segs = [];
|
|
12175
|
-
const
|
|
12176
|
-
for (const seg of
|
|
12175
|
+
const path2 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
12176
|
+
for (const seg of path2) {
|
|
12177
12177
|
if (typeof seg === "number")
|
|
12178
12178
|
segs.push(`[${seg}]`);
|
|
12179
12179
|
else if (typeof seg === "symbol")
|
|
@@ -24579,13 +24579,13 @@ function resolveRef(ref, ctx) {
|
|
|
24579
24579
|
if (!ref.startsWith("#")) {
|
|
24580
24580
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
24581
24581
|
}
|
|
24582
|
-
const
|
|
24583
|
-
if (
|
|
24582
|
+
const path2 = ref.slice(1).split("/").filter(Boolean);
|
|
24583
|
+
if (path2.length === 0) {
|
|
24584
24584
|
return ctx.rootSchema;
|
|
24585
24585
|
}
|
|
24586
24586
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
24587
|
-
if (
|
|
24588
|
-
const key =
|
|
24587
|
+
if (path2[0] === defsKey) {
|
|
24588
|
+
const key = path2[1];
|
|
24589
24589
|
if (!key || !ctx.defs[key]) {
|
|
24590
24590
|
throw new Error(`Reference not found: ${ref}`);
|
|
24591
24591
|
}
|
|
@@ -30306,6 +30306,10 @@ var StdioServerTransport = class {
|
|
|
30306
30306
|
|
|
30307
30307
|
// src/mcp/index.ts
|
|
30308
30308
|
var import_dotenv = __toESM(require_main(), 1);
|
|
30309
|
+
import fs from "fs";
|
|
30310
|
+
import path from "path";
|
|
30311
|
+
import os from "os";
|
|
30312
|
+
import { fileURLToPath } from "url";
|
|
30309
30313
|
import_dotenv.default.config();
|
|
30310
30314
|
var API_BASE_URL = process.env.GENJO_API_BASE_URL || "https://api.gen-jo.com";
|
|
30311
30315
|
var API_KEY = process.env.GENJO_API_KEY;
|
|
@@ -30555,10 +30559,93 @@ server.tool(
|
|
|
30555
30559
|
}
|
|
30556
30560
|
}
|
|
30557
30561
|
);
|
|
30562
|
+
async function install() {
|
|
30563
|
+
console.log("\x1B[36m%s\x1B[0m", "\u{1F916} Genjo MCP Server Installer");
|
|
30564
|
+
console.log("--------------------------------");
|
|
30565
|
+
const homeDir = os.homedir();
|
|
30566
|
+
const platform = os.platform();
|
|
30567
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
30568
|
+
const __dirname = path.dirname(__filename);
|
|
30569
|
+
let configDir = "";
|
|
30570
|
+
if (platform === "darwin") {
|
|
30571
|
+
configDir = path.join(homeDir, "Library", "Application Support", "Claude");
|
|
30572
|
+
} else if (platform === "win32") {
|
|
30573
|
+
configDir = path.join(process.env.APPDATA || "", "Claude");
|
|
30574
|
+
} else {
|
|
30575
|
+
configDir = path.join(homeDir, ".config", "Claude");
|
|
30576
|
+
}
|
|
30577
|
+
const configPath = path.join(configDir, "claude_desktop_config.json");
|
|
30578
|
+
console.log(`Checking Claude Desktop configuration at: ${configPath}`);
|
|
30579
|
+
if (fs.existsSync(configDir)) {
|
|
30580
|
+
try {
|
|
30581
|
+
let config2 = {};
|
|
30582
|
+
if (fs.existsSync(configPath)) {
|
|
30583
|
+
const content = fs.readFileSync(configPath, "utf-8");
|
|
30584
|
+
try {
|
|
30585
|
+
config2 = JSON.parse(content);
|
|
30586
|
+
} catch (e) {
|
|
30587
|
+
console.warn(" \u26A0\uFE0F Existing config is invalid JSON. Creating new config.");
|
|
30588
|
+
}
|
|
30589
|
+
}
|
|
30590
|
+
config2.mcpServers = config2.mcpServers || {};
|
|
30591
|
+
const newConfig = {
|
|
30592
|
+
command: "npx",
|
|
30593
|
+
args: ["-y", "genjo-mcp-server"],
|
|
30594
|
+
env: {
|
|
30595
|
+
GENJO_API_BASE_URL: process.env.GENJO_API_BASE_URL || "https://api.gen-jo.com"
|
|
30596
|
+
}
|
|
30597
|
+
};
|
|
30598
|
+
if (process.env.GENJO_API_KEY) {
|
|
30599
|
+
newConfig.env["GENJO_API_KEY"] = process.env.GENJO_API_KEY;
|
|
30600
|
+
}
|
|
30601
|
+
config2.mcpServers["genjo"] = newConfig;
|
|
30602
|
+
fs.writeFileSync(configPath, JSON.stringify(config2, null, 2));
|
|
30603
|
+
console.log(" \u2705 Successfully updated Claude Desktop configuration.");
|
|
30604
|
+
} catch (error48) {
|
|
30605
|
+
console.error(` \u274C Failed to update config: ${error48.message}`);
|
|
30606
|
+
}
|
|
30607
|
+
} else {
|
|
30608
|
+
console.warn(` \u26A0\uFE0F Claude Desktop configuration directory not found.`);
|
|
30609
|
+
console.warn(` Expected path: ${configDir}`);
|
|
30610
|
+
}
|
|
30611
|
+
let sourceSkillsDir = path.join(__dirname, "genjo-news-skill");
|
|
30612
|
+
if (!fs.existsSync(sourceSkillsDir)) {
|
|
30613
|
+
sourceSkillsDir = path.join(process.cwd(), "src", "mcp", "genjo-news-skill");
|
|
30614
|
+
}
|
|
30615
|
+
const targetSkillsDir = path.join(process.cwd(), ".claude", "skills", "genjo-news-skill");
|
|
30616
|
+
console.log(`
|
|
30617
|
+
Installing Agent Skills to: ${targetSkillsDir}`);
|
|
30618
|
+
if (fs.existsSync(sourceSkillsDir)) {
|
|
30619
|
+
try {
|
|
30620
|
+
if (fs.existsSync(targetSkillsDir)) {
|
|
30621
|
+
console.log(" \u2139\uFE0F Skills already installed (skipping copy).");
|
|
30622
|
+
} else {
|
|
30623
|
+
fs.mkdirSync(path.dirname(targetSkillsDir), { recursive: true });
|
|
30624
|
+
fs.cpSync(sourceSkillsDir, targetSkillsDir, { recursive: true });
|
|
30625
|
+
console.log(" \u2705 Successfully installed Agent Skills.");
|
|
30626
|
+
}
|
|
30627
|
+
} catch (error48) {
|
|
30628
|
+
console.error(` \u274C Failed to copy skills: ${error48.message}`);
|
|
30629
|
+
}
|
|
30630
|
+
} else {
|
|
30631
|
+
console.warn(" \u26A0\uFE0F Could not locate source skills directory.");
|
|
30632
|
+
console.warn(` Checked: ${sourceSkillsDir}`);
|
|
30633
|
+
}
|
|
30634
|
+
console.log("\n--------------------------------");
|
|
30635
|
+
console.log("\u{1F389} Setup complete!");
|
|
30636
|
+
console.log("1. Restart Claude Desktop to apply MCP settings.");
|
|
30637
|
+
console.log("2. Use 'Genjo' tools in Claude Desktop.");
|
|
30638
|
+
console.log("3. For Claude Code, skills are ready in .claude/skills/.");
|
|
30639
|
+
}
|
|
30558
30640
|
async function main() {
|
|
30559
|
-
const
|
|
30560
|
-
|
|
30561
|
-
|
|
30641
|
+
const args = process.argv.slice(2);
|
|
30642
|
+
if (args.includes("install") || args.includes("--install")) {
|
|
30643
|
+
await install();
|
|
30644
|
+
} else {
|
|
30645
|
+
const transport = new StdioServerTransport();
|
|
30646
|
+
await server.connect(transport);
|
|
30647
|
+
console.error("Genjo MCP Server running on stdio");
|
|
30648
|
+
}
|
|
30562
30649
|
}
|
|
30563
30650
|
main().catch((error48) => {
|
|
30564
30651
|
console.error("Fatal error in main():", error48);
|