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 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 run this server directly using `npx` or by installing it globally.
13
+ You can setup this server automatically or configure it manually.
14
14
 
15
- #### Option 1: Run directly (Recommended)
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 for Asian markets. 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.
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**: Always respect the user's preferred language or the context of the conversation.
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規制について詳しく知りたい" (Fetch `zh` news or search related topics)
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(path) {
3234
- let input = path;
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 [path, query] = wsComponent.resourceName.split("?");
3434
- wsComponent.path = path && path !== "/" ? path : void 0;
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, fs, exportName) {
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, fs[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 fs = __require("fs");
6872
- var path = __require("path");
6873
- var os = __require("os");
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 (fs.existsSync(filepath)) {
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 = path.resolve(process.cwd(), ".env.vault");
6988
+ possibleVaultPath = path2.resolve(process.cwd(), ".env.vault");
6989
6989
  }
6990
- if (fs.existsSync(possibleVaultPath)) {
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] === "~" ? path.join(os.homedir(), envPath.slice(1)) : envPath;
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 = path.resolve(process.cwd(), ".env");
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 path2 of optionPaths) {
7037
+ for (const path3 of optionPaths) {
7038
7038
  try {
7039
- const parsed = DotenvModule.parse(fs.readFileSync(path2, { encoding }));
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 ${path2} ${e.message}`);
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 = path.relative(process.cwd(), filePath);
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 = [...path, ...issueData.path || []];
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, path, key) {
7633
+ constructor(parent, value, path2, key) {
7634
7634
  this._cachedPath = [];
7635
7635
  this.parent = parent;
7636
7636
  this.data = value;
7637
- this._path = 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, path) {
11561
- if (!path)
11560
+ function getElementAtPath(obj, path2) {
11561
+ if (!path2)
11562
11562
  return obj;
11563
- return path.reduce((acc, key) => acc?.[key], obj);
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(path, issues) {
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(path);
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, path = []) => {
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 = [...path, ...issue2.path];
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 path = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
12176
- for (const seg of path) {
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 path = ref.slice(1).split("/").filter(Boolean);
24583
- if (path.length === 0) {
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 (path[0] === defsKey) {
24588
- const key = path[1];
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 transport = new StdioServerTransport();
30560
- await server.connect(transport);
30561
- console.error("Genjo MCP Server running on stdio");
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genjo-mcp-server",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "MCP Server for Genjo AI News System - Asian Market Intelligence",
5
5
  "type": "module",
6
6
  "main": "index.js",