itemscore-helper 1.0.0 → 1.2.0

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
@@ -1,12 +1,24 @@
1
1
  # itemscore-helper
2
2
 
3
- Set up **any** AI assistant to build and edit custom Minecraft items for the [ItemsCore](https://www.coredevelopment.shop/plugins/items-core) plugin. Works with Claude, Codex, Cursor, Gemini, and anything else that supports MCP or custom instructions. You do not need to know how to code.
3
+ Set up **any** AI assistant to build and edit custom Minecraft items for the [ItemsCore](https://www.coredevelopment.shop/plugins/itemscore) plugin. Works with Claude, Codex, Cursor, Gemini, and anything else that supports MCP or custom instructions. You do not need to know how to code.
4
+
5
+ ## Easiest: let your AI set itself up
6
+
7
+ Run this, copy what it prints, and paste it into your AI (Claude, Cursor, Gemini, Codex, anything):
8
+
9
+ ```bash
10
+ npx itemscore-helper prompt
11
+ ```
12
+
13
+ Your AI reads the prompt, sets up the ItemsCore tools itself, then asks what item you want. No config files, no terminal knowledge needed.
14
+
15
+ ## Or set it up in one command
4
16
 
5
17
  ```bash
6
18
  npx itemscore-helper
7
19
  ```
8
20
 
9
- That command drops the ItemsCore skill into a folder and prints exactly what to paste into your AI tool. Then you can ask things like *"make me a sword that calls lightning on left-click"* and your AI produces a ready-to-import item file.
21
+ This auto-detects the AI tools on your machine and connects the local MCP server to each one (a backup of every file it changes is saved beside it). Then just ask your AI for an item.
10
22
 
11
23
  ## What it sets up
12
24
 
@@ -19,8 +31,9 @@ The MCP server is `npx -y itemscore-helper serve`. It speaks the standard stdio
19
31
 
20
32
  | Command | What it does |
21
33
  |---|---|
22
- | `npx itemscore-helper` | Install the skill files into `./itemscore-helper/` and print setup steps |
23
- | `npx itemscore-helper --dir DIR` | Install into a custom folder |
34
+ | `npx itemscore-helper` | Auto-detect your AI tools and connect the local MCP server |
35
+ | `npx itemscore-helper prompt` | Print a prompt to paste into your AI so it sets itself up |
36
+ | `npx itemscore-helper --dry-run` | Show what would change, without writing anything |
24
37
  | `npx itemscore-helper serve` | Run the local MCP server (this is what your AI runs) |
25
38
  | `npx itemscore-helper print` | Print the skill instructions to stdout |
26
39
  | `npx itemscore-helper mcp` | Print the MCP server config |
@@ -76,8 +89,8 @@ To edit an existing item, run `/ic export <name>`, share the exported file with
76
89
 
77
90
  ## Links
78
91
 
79
- - Documentation: https://www.coredevelopment.shop/docs/items-core
80
- - Plugin page: https://www.coredevelopment.shop/plugins/items-core
92
+ - Documentation: https://www.coredevelopment.shop/docs/itemscore
93
+ - Plugin page: https://www.coredevelopment.shop/plugins/itemscore
81
94
 
82
95
  ## License
83
96
 
package/bin/cli.js CHANGED
@@ -3,12 +3,26 @@
3
3
 
4
4
  const fs = require("fs")
5
5
  const path = require("path")
6
+ const { autoConfigure } = require("../lib/install.js")
6
7
 
7
8
  const HOSTED_URL = "https://www.coredevelopment.shop/api/mcp"
8
9
  const LLMS_URL = "https://www.coredevelopment.shop/llms.txt"
9
- const DOCS_URL = "https://www.coredevelopment.shop/docs/items-core"
10
+ const DOCS_URL = "https://www.coredevelopment.shop/docs/itemscore"
10
11
  const SKILL_DIR = path.join(__dirname, "..", "skill")
11
12
 
13
+ const SETUP_PROMPT = [
14
+ "Help me build a custom item for my Minecraft server with the ItemsCore plugin. Set yourself up first, then we'll build it together.",
15
+ "",
16
+ "1. Fetch and read " + LLMS_URL + " - it explains how ItemsCore items work, the item JSON format, and every method you can use.",
17
+ "",
18
+ "2. Set up the ItemsCore tools so you can look up methods and validate items for me. In my project folder, run:",
19
+ " npx -y itemscore-helper install",
20
+ ' Then reload your MCP servers (or restart this app) so the "itemscore" tools appear. If you cannot run commands, add this to your MCP config instead:',
21
+ ' {"mcpServers":{"itemscore":{"command":"npx","args":["-y","itemscore-helper","serve"]}}}',
22
+ "",
23
+ "3. Once you are set up, tell me you are ready and ask what item I want. Write a valid .item file, validate it, then tell me to drop it in plugins/ItemsCore/imports/ and run /ic import. The item stays fully editable in the in-game editor.",
24
+ ].join("\n")
25
+
12
26
  function copyDir(src, dest) {
13
27
  fs.mkdirSync(dest, { recursive: true })
14
28
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
@@ -20,12 +34,11 @@ function copyDir(src, dest) {
20
34
  }
21
35
 
22
36
  function parseArgs(argv) {
23
- const out = { cmd: "install", dir: "itemscore-helper" }
37
+ const out = { cmd: "install", dryRun: false }
24
38
  const rest = []
25
- for (let i = 0; i < argv.length; i++) {
26
- const a = argv[i]
27
- if (a === "--dir") out.dir = argv[++i]
28
- else if (a === "-h" || a === "--help") out.cmd = "help"
39
+ for (const a of argv) {
40
+ if (a === "-h" || a === "--help") out.cmd = "help"
41
+ else if (a === "--dry-run") out.dryRun = true
29
42
  else rest.push(a)
30
43
  }
31
44
  if (rest[0]) out.cmd = rest[0]
@@ -38,16 +51,16 @@ function printHelp() {
38
51
  "itemscore-helper - set up any AI to build ItemsCore items",
39
52
  "",
40
53
  "Usage",
41
- " npx itemscore-helper Install the skill files here and print setup steps",
42
- " npx itemscore-helper install Same as above",
43
- " npx itemscore-helper --dir DIR Install into a custom folder (default: itemscore-helper)",
54
+ " npx itemscore-helper Auto-detect your AI tools and connect the local MCP server",
55
+ " npx itemscore-helper prompt Print a prompt to paste into your AI so it sets itself up",
56
+ " npx itemscore-helper --dry-run Show what would be changed, without writing anything",
44
57
  " npx itemscore-helper serve Run the local MCP server (this is what your AI runs)",
45
58
  " npx itemscore-helper print Print the skill instructions (SKILL.md) to stdout",
46
59
  " npx itemscore-helper mcp Print the MCP server config",
47
60
  " npx itemscore-helper help Show this help",
48
61
  "",
49
- "The MCP server runs locally on your machine over stdio. Works with Claude, Codex, Cursor,",
50
- "Gemini, and any other AI that supports MCP.",
62
+ "Zero terminal? Run `npx itemscore-helper prompt`, copy it, and paste it into your AI - it sets itself up.",
63
+ "Supports Claude (Code & Desktop), Cursor, Gemini CLI, Codex, Windsurf and any MCP client.",
51
64
  "Docs: " + DOCS_URL,
52
65
  "",
53
66
  ].join("\n"))
@@ -55,11 +68,7 @@ function printHelp() {
55
68
 
56
69
  function printMcp() {
57
70
  console.log(
58
- JSON.stringify(
59
- { mcpServers: { itemscore: { command: "npx", args: ["-y", "itemscore-helper", "serve"] } } },
60
- null,
61
- 2
62
- )
71
+ JSON.stringify({ mcpServers: { itemscore: { command: "npx", args: ["-y", "itemscore-helper", "serve"] } } }, null, 2)
63
72
  )
64
73
  }
65
74
 
@@ -67,58 +76,59 @@ function printSkill() {
67
76
  process.stdout.write(fs.readFileSync(path.join(SKILL_DIR, "SKILL.md"), "utf8"))
68
77
  }
69
78
 
70
- function printGuide(targetDir) {
71
- const skillPath = path.join(targetDir, "SKILL.md")
72
- console.log([
73
- "",
74
- "ItemsCore helper installed.",
75
- "",
76
- "Files written to " + targetDir + ":",
77
- " SKILL.md the instructions to give your AI",
78
- " ITEM_FORMAT.md the full item format reference",
79
- " mcp.json the MCP server config",
80
- " examples/ ready-made example items",
81
- "",
82
- "Two things to set up in your AI:",
83
- "",
84
- "1) Add the local ItemsCore MCP server (runs on your machine over stdio)",
85
- " Same config for every client - command npx, args [-y, itemscore-helper, serve]:",
86
- "",
87
- " Cursor .cursor/mcp.json",
88
- ' {"mcpServers":{"itemscore":{"command":"npx","args":["-y","itemscore-helper","serve"]}}}',
89
- "",
90
- " Claude Code .mcp.json in your project (or claude_desktop_config.json for Desktop)",
91
- ' {"mcpServers":{"itemscore":{"command":"npx","args":["-y","itemscore-helper","serve"]}}}',
92
- "",
93
- " Gemini CLI ~/.gemini/settings.json",
94
- ' {"mcpServers":{"itemscore":{"command":"npx","args":["-y","itemscore-helper","serve"]}}}',
95
- "",
96
- " Codex ~/.codex/config.toml",
97
- " [mcp_servers.itemscore]",
98
- ' command = "npx"',
99
- ' args = ["-y","itemscore-helper","serve"]',
100
- "",
101
- " To match YOUR server's exact API (including addon methods), run /ic exportapi in-game",
102
- " and point the server at the generated file, either with the env var:",
103
- " ITEMSCORE_API=/path/to/plugins/ItemsCore/itemscore-api.json",
104
- ' or by adding "--manifest","/path/to/itemscore-api.json" to the args. Otherwise it uses',
105
- " a bundled snapshot of the standard API.",
106
- "",
107
- " No MCP support at all? An online copy also exists at " + HOSTED_URL,
108
- " and a plain-text guide at " + LLMS_URL,
109
- "",
110
- "2) Give your AI the skill",
111
- " Load " + skillPath + " as the AI's instructions / rules:",
112
- " Cursor copy SKILL.md into .cursor/rules/itemscore.md (or .cursorrules)",
113
- " Claude Code copy SKILL.md into .claude/skills/ or append it to CLAUDE.md",
114
- " Codex append SKILL.md to AGENTS.md",
115
- " Gemini CLI append SKILL.md to GEMINI.md",
116
- " Anything else paste SKILL.md into the chat or system prompt",
117
- "",
118
- 'Then just ask: "make me a sword that calls lightning on left-click".',
119
- "Your AI writes a .item file; drop it in plugins/ItemsCore/imports/ and run /ic import <name>.",
120
- "",
121
- ].join("\n"))
79
+ function printPrompt() {
80
+ console.log(SETUP_PROMPT)
81
+ }
82
+
83
+ function manualLines() {
84
+ return [
85
+ " Add this to your AI client's MCP config (same for Claude, Cursor, Gemini):",
86
+ ' {"mcpServers":{"itemscore":{"command":"npx","args":["-y","itemscore-helper","serve"]}}}',
87
+ " Codex (~/.codex/config.toml):",
88
+ " [mcp_servers.itemscore]",
89
+ ' command = "npx"',
90
+ ' args = ["-y","itemscore-helper","serve"]',
91
+ " No MCP client? A hosted copy is at " + HOSTED_URL + " (guide: " + LLMS_URL + ").",
92
+ ]
93
+ }
94
+
95
+ function runInstall(dryRun) {
96
+ const targetDir = path.resolve(process.cwd(), "itemscore-helper")
97
+ if (!dryRun) copyDir(SKILL_DIR, targetDir)
98
+
99
+ const results = autoConfigure({ dryRun })
100
+ const configured = results.filter((r) => r.ok)
101
+
102
+ const out = ["", dryRun ? "ItemsCore helper - dry run (nothing was changed):" : "ItemsCore helper installed.", ""]
103
+
104
+ if (configured.length > 0) {
105
+ out.push(dryRun ? "Would connect the ItemsCore MCP server to:" : "Connected the ItemsCore MCP server to:")
106
+ for (const r of results) {
107
+ if (r.ok) out.push(" + " + r.name + (r.already ? " (already set)" : "") + " -> " + r.file)
108
+ else out.push(" ! " + r.name + " skipped: " + r.reason)
109
+ }
110
+ if (!dryRun) {
111
+ out.push("")
112
+ out.push("Restart your AI app, then just ask it to build an ItemsCore item.")
113
+ out.push("A backup of each changed file was saved beside it (*.itemscore-bak).")
114
+ }
115
+ } else {
116
+ out.push("No AI tool configs were detected on this machine. Two easy options:")
117
+ out.push("")
118
+ out.push(" 1. Paste this prompt into your AI and it sets itself up:")
119
+ out.push("")
120
+ out.push(SETUP_PROMPT.split("\n").map((l) => " " + l).join("\n"))
121
+ out.push("")
122
+ out.push(" 2. Or add the MCP server to your AI client's config yourself:")
123
+ out.push(...manualLines())
124
+ }
125
+
126
+ if (!dryRun) {
127
+ out.push("")
128
+ out.push("Skill files written to " + targetDir + " - hand SKILL.md to your AI if it asks for guidance.")
129
+ }
130
+ out.push("")
131
+ console.log(out.join("\n"))
122
132
  }
123
133
 
124
134
  function main() {
@@ -129,15 +139,14 @@ function main() {
129
139
  }
130
140
  if (args.cmd === "help") return printHelp()
131
141
  if (args.cmd === "mcp") return printMcp()
142
+ if (args.cmd === "prompt") return printPrompt()
132
143
  if (args.cmd === "print") return printSkill()
133
144
  if (args.cmd !== "install") {
134
145
  console.error("Unknown command: " + args.cmd + "\nRun: npx itemscore-helper help")
135
146
  process.exitCode = 1
136
147
  return
137
148
  }
138
- const targetDir = path.resolve(process.cwd(), args.dir)
139
- copyDir(SKILL_DIR, targetDir)
140
- printGuide(targetDir)
149
+ runInstall(args.dryRun)
141
150
  }
142
151
 
143
152
  main()
package/lib/install.js ADDED
@@ -0,0 +1,113 @@
1
+ "use strict"
2
+
3
+ const fs = require("fs")
4
+ const path = require("path")
5
+ const os = require("os")
6
+
7
+ const ENTRY = { command: "npx", args: ["-y", "itemscore-helper", "serve"] }
8
+ const TOML_BLOCK = '\n[mcp_servers.itemscore]\ncommand = "npx"\nargs = ["-y", "itemscore-helper", "serve"]\n'
9
+
10
+ function homeDir() {
11
+ return process.env.ITEMSCORE_HOME_OVERRIDE || os.homedir()
12
+ }
13
+
14
+ function backup(file) {
15
+ const bak = file + ".itemscore-bak"
16
+ if (fs.existsSync(file) && !fs.existsSync(bak)) {
17
+ try {
18
+ fs.copyFileSync(file, bak)
19
+ } catch {
20
+ /* best effort */
21
+ }
22
+ }
23
+ }
24
+
25
+ function mergeJsonMcp(file, key) {
26
+ let data = {}
27
+ if (fs.existsSync(file)) {
28
+ const txt = fs.readFileSync(file, "utf8").trim()
29
+ if (txt) {
30
+ try {
31
+ data = JSON.parse(txt)
32
+ } catch {
33
+ return { ok: false, reason: "existing config is not valid JSON; left untouched" }
34
+ }
35
+ }
36
+ }
37
+ if (typeof data !== "object" || data === null || Array.isArray(data)) {
38
+ return { ok: false, reason: "existing config is not a JSON object; left untouched" }
39
+ }
40
+ if (!data[key] || typeof data[key] !== "object") data[key] = {}
41
+ const already = JSON.stringify(data[key].itemscore) === JSON.stringify(ENTRY)
42
+ data[key].itemscore = ENTRY
43
+ backup(file)
44
+ fs.mkdirSync(path.dirname(file), { recursive: true })
45
+ fs.writeFileSync(file, JSON.stringify(data, null, 2) + "\n")
46
+ return { ok: true, already }
47
+ }
48
+
49
+ function appendTomlMcp(file) {
50
+ const txt = fs.existsSync(file) ? fs.readFileSync(file, "utf8") : ""
51
+ if (txt.includes("[mcp_servers.itemscore]")) return { ok: true, already: true }
52
+ backup(file)
53
+ fs.mkdirSync(path.dirname(file), { recursive: true })
54
+ const next = txt.trim() ? txt.trimEnd() + "\n" + TOML_BLOCK : TOML_BLOCK.replace(/^\n/, "")
55
+ fs.writeFileSync(file, next)
56
+ return { ok: true, already: false }
57
+ }
58
+
59
+ function globalTargets() {
60
+ const h = homeDir()
61
+ const list = [
62
+ { name: "Cursor", dir: path.join(h, ".cursor"), file: path.join(h, ".cursor", "mcp.json"), kind: "json", key: "mcpServers" },
63
+ { name: "Codex", dir: path.join(h, ".codex"), file: path.join(h, ".codex", "config.toml"), kind: "toml" },
64
+ { name: "Gemini CLI", dir: path.join(h, ".gemini"), file: path.join(h, ".gemini", "settings.json"), kind: "json", key: "mcpServers" },
65
+ { name: "Windsurf", dir: path.join(h, ".codeium", "windsurf"), file: path.join(h, ".codeium", "windsurf", "mcp_config.json"), kind: "json", key: "mcpServers" },
66
+ ]
67
+ if (process.platform === "win32") {
68
+ const appData = process.env.APPDATA || path.join(h, "AppData", "Roaming")
69
+ list.push({ name: "Claude Desktop", dir: path.join(appData, "Claude"), file: path.join(appData, "Claude", "claude_desktop_config.json"), kind: "json", key: "mcpServers" })
70
+ } else if (process.platform === "darwin") {
71
+ list.push({ name: "Claude Desktop", dir: path.join(h, "Library", "Application Support", "Claude"), file: path.join(h, "Library", "Application Support", "Claude", "claude_desktop_config.json"), kind: "json", key: "mcpServers" })
72
+ } else {
73
+ list.push({ name: "Claude Desktop", dir: path.join(h, ".config", "Claude"), file: path.join(h, ".config", "Claude", "claude_desktop_config.json"), kind: "json", key: "mcpServers" })
74
+ }
75
+ return list
76
+ }
77
+
78
+ function isProjectDir(cwd) {
79
+ return [".git", "package.json", ".cursor", ".claude", ".vscode"].some((m) => fs.existsSync(path.join(cwd, m)))
80
+ }
81
+
82
+ function applyTarget(t, dryRun) {
83
+ if (dryRun) return { name: t.name, file: t.file, ok: true, already: false, dry: true }
84
+ const r = t.kind === "json" ? mergeJsonMcp(t.file, t.key) : appendTomlMcp(t.file)
85
+ return { name: t.name, file: t.file, ...r }
86
+ }
87
+
88
+ /**
89
+ * Detects installed AI tools and writes the itemscore MCP server into each one's
90
+ * config (creating a backup first). Returns a list describing what happened.
91
+ */
92
+ function autoConfigure(opts) {
93
+ opts = opts || {}
94
+ const dryRun = !!opts.dryRun
95
+ const cwd = opts.cwd || process.cwd()
96
+ const results = []
97
+
98
+ for (const t of globalTargets()) {
99
+ const present = fs.existsSync(t.dir) || fs.existsSync(t.file)
100
+ if (!present) continue
101
+ results.push({ scope: "global", ...applyTarget(t, dryRun) })
102
+ }
103
+
104
+ // Project-scoped .mcp.json for Claude Code, VS Code and project-level Cursor.
105
+ if (isProjectDir(cwd)) {
106
+ const file = path.join(cwd, ".mcp.json")
107
+ results.push({ scope: "project", name: "Project (.mcp.json)", file, ...(dryRun ? { ok: true, dry: true } : mergeJsonMcp(file, "mcpServers")) })
108
+ }
109
+
110
+ return results
111
+ }
112
+
113
+ module.exports = { autoConfigure, globalTargets, isProjectDir, ENTRY }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "itemscore-helper",
3
- "version": "1.0.0",
4
- "description": "Local MCP server + skill that lets any AI (Claude, Codex, Cursor, Gemini, and others) build and edit custom Minecraft items for the ItemsCore plugin. Runs entirely on your machine.",
3
+ "version": "1.2.0",
4
+ "description": "One command sets up any AI (Claude, Codex, Cursor, Gemini, and others) to build and edit custom Minecraft items for the ItemsCore plugin. Auto-detects your AI tools and connects a local MCP server that runs entirely on your machine.",
5
5
  "bin": {
6
6
  "itemscore-helper": "bin/cli.js",
7
7
  "itemscore-mcp": "bin/mcp.js"
@@ -28,7 +28,7 @@
28
28
  "codex",
29
29
  "gemini"
30
30
  ],
31
- "homepage": "https://www.coredevelopment.shop/docs/items-core",
31
+ "homepage": "https://www.coredevelopment.shop/docs/itemscore",
32
32
  "repository": {
33
33
  "type": "git",
34
34
  "url": "https://github.com/Tc554/itemscore-helper.git"