goalplanner-share-mcp

goalplanner-share-mcp

An MCP server that generates RuneLite Goal Planner import strings from natural language goal descriptions, enabling assistants to create paste-ready share codes for Old School RuneScape goal planning.

Category
访问服务器

README

goalplanner-share-mcp

An MCP server that crafts RuneLite Goal Planner import strings (GPSHARE1: codes) from a structured, natural-language-friendly goal spec — so an assistant can turn "plan my Inferno prep: 90 Ranged, 70 Defence, then beat the Inferno" into a paste-ready code, confirming your intent before it emits anything.

Pure string generator — no plugin changes required. Verified byte-compatible with the plugin's own com.goalplanner.share.ShareCodec in both directions (the plugin decodes codes this tool produces, and this tool decodes codes the plugin produces).

What it does

  • Two modes: import as a new named section, or as loose goals (which land in a "Shared goals" section).

  • Multi-section codes (GPSHARE2): pass sections[] and ONE code carries several sections — each imports as its own section, in one undo. A section with targetDefault: true lands in the recipient's Default plan instead, REUSING existing equivalent goals (the in-game add dedup), so re-importing never duplicates. Single-section codes still emit the GPSHARE1: wire, which every plugin build imports; multi-section/default-target codes need a recent plugin build.

  • Cross-section dependencies: in the sections[] form, a goal may requires/ orRequires a goal in a different section by its explicit id. The edge rides the bundle-level crossEdges wire field (mirroring the plugin's CrossEdgeDto) and is rewired on import. Section-local ids always win; an id found in several other sections is ambiguous and dropped with a warning; cycles are checked across the whole bundle. The preview marks the link on the dependent goal:

    ═══ Section 2/2: "Inferno prep" ═══
    Ranged - Level 90   [Skill · Level 90 (5,346,332 xp)]  ✓ auto-tracks
      ↪ needs "Imbued heart" — from section 1 "Slayer"
      TzKal-Zuk   [Boss · TzKal-Zuk · 1 KC]  ✓ auto-tracks   ◀ final goal
    
  • Simple goals or complex trees: goals are wired into prerequisite trees (AND via requires, OR via orRequires) by stable id. Diamonds and OR-groups are supported.

  • Hybrid typing: recognized kinds become typed, auto-tracking goals; anything else falls back to a CUSTOM goal (imports fine, manual check-off). Every fallback, dropped edge, or cycle is reported as a warning.

  • Confirm-first, preview by default: craft_import_string renders the goal list as it will import — section header, each goal with its type/target, prerequisites nested as a guide tree, and per-goal tracking badges — with no code emitted. The user eyeballs it and adjusts; the code is produced only on a follow-up call with confirm: true.

    The list is rendered in the same order and nesting the plugin shows — do-first prerequisites flush-left at the top; the dependent goal indented beneath them, with the final goal at the bottom:

    ┌─ Goal Planner import preview ─────────────────
    │ Section: "Inferno prep"  (created fresh on import; completed goals kept inline)
    │ 4 goal(s) · 4 auto-track · 0 manual/unverified
    │ Order: do-first at top → final goal at bottom (as shown in-game)
    └───────────────────────────────────────────────
    
    Ranged - Level 90   [Skill · Level 90 (5,346,332 xp)]  ✓ auto-tracks
    Defence - Level 70   [Skill · Level 70 (737,627 xp)]  ✓ auto-tracks
    Beat the Fight Caves   [Boss · TzTok-Jad · 1 KC]  ✓ auto-tracks
      Beat the Inferno   [Boss · TzKal-Zuk · 1 KC]  ✓ auto-tracks   ◀ final goal
    

Goal coverage

Status Types Notes
✅ Typed core (auto-tracks) SKILL, BOSS, ITEM_GRIND, DIARY, QUEST, ACCOUNT, COMBAT_ACHIEVEMENT, CUSTOM SKILL by level or XP (all 23 skills); BOSS by name (all 89 tracked bosses + aliases), KC target defaults to 1; ITEM_GRIND by item name against the full OSRS item table (or explicit itemId); DIARY by "<Area> <Tier>" name across 12 areas × 4 tiers (or explicit known varbitId); QUEST by display name/abbreviation (209 quests+miniquests, wire carries the RuneLite Quest enum constant); ACCOUNT by metric name/shorthand (16 plugin AccountMetrics incl. Collection Log Slots and Diary Tiers; phrases like "maintain quest cape" imply metric AND milestone — quest-point max is 335 as of The Red Reef; out-of-range targets warn but emit, matching the plugin's allow-over-max behaviour; missing target = max); COMBAT_ACHIEVEMENT by exact task name (637 tasks, wire carries caTaskId 0–639, tier sprite + description match in-game-created goals)
🧩 Group expansion (one phrase → many goals) item sets/loadouts, boss & diary groups full torva → 3, maxed melee setup → 9; GWD → 4 bosses, Dagannoth Kings → 3, all bosses → 89; all elite diaries → 12, all Ardougne diaries → 4, all diaries → 48
🔶 Passthrough (unverified) unknown questName / accountMetric / caTaskId / varbitId / itemId identifiers emitted as supplied with an UNVERIFIED warning; unresolvable names fall back to CUSTOM with did-you-mean suggestions
🗺️ Roadmap CA tier groups (all easy CAs), quest groups (all f2p quests)

Boss names are generated from the plugin's BossKillData via npm run gen:bosses (reads $GOAL_PLANNER_REPO). The item table is generated from the OSRS cache objtypes.txt (JayArrowz mcp-osrs) via npm run gen:items (auto-discovers the mcp-osrs data dir, or set $OSRS_DATA_DIR) — placeholder_/cert_ variants filtered out since the plugin tracks an exact itemId. Item names that diverge from their internal codename (potions, Cannonball, …) resolve via a curated alias map or by you passing an itemId you looked up on the OSRS Wiki. A second generated layer (npm run gen:item-names, wiki prices mapping) adds authoritative display names for ~4.5k tradeables — so the codename-divergent tail (Armadyl crossbow, Amulet of torture, Voidwaker pieces) resolves without curation. Community nicknames (tbow, bp, shadow, scythe, zcb, dhcb, fero, rancour, blorva, fang kit, …) resolve by NAME REFERENCE through the generated tables (never hand-typed ids) and armour sets (full torva, fortified masori) are recognised too; loadout presets (maxed melee setup, maxed ranged, maxed mage) expand to a full BiS-ish kit; and a +/and-joined phrase (full masori + tbow, maxed melee + shadow) fans out into one auto-tracking item goal per piece (visible in the preview before you confirm).

The diary table is generated via npm run gen:diaries, which joins two sources: the plugin's AchievementDiaryData (area/tier structure + required values) with the numeric varbit ids from the OSRS cache varbittypes.txt — the symbolic VarbitID.<AREA>_DIARY_<TIER>_COMPLETE constants are matched by name to their cache ids (the runtime varbit the recipient reads).

The loadout presets are generated via npm run gen:loadouts (needs network), a hybrid: armour slots come from the OSRS Wiki Armour/Highest bonuses tables (so they stay current — e.g. Amulet of rancour), resolved to ids via the wiki's prices-mapping API; the weapon + cape are curated because the wiki ranks weapons by raw bonus, which picks slow non-DPS weapons (Zombie axe, Kodai wand). Loadout member ids can be newer than the objtypes snapshot, so they're treated as known.

The quest table is generated via npm run gen:quests, which runs the real RuneLite Quest enum (values()/name()/getName()) from the version-matched runelite-api jar in the local gradle cache — the recipient's QuestTracker does Quest.valueOf(questName), so the wire must carry the enum constant (DRAGON_SLAYER_II), and running the enum keeps the constant↔display pairing from ever drifting. The account-metric table (npm run gen:accounts) parses the plugin's AccountMetric.java (the tracker's AccountMetric.valueOf constants + each metric's sensible target range + leagues flags). The CA table (npm run gen:cas, needs network) fetches the OSRS Wiki combat_achievement bucket — the same table the plugin's WikiCaRepository loads — where the bucket id is the bit index (0–639) into the CA_TASK_COMPLETED varplayers.

Cross-language parity for all three Phase-2 types is proven the same way as Phase 1: the plugin's real ShareCodec decoded a TS-crafted code and Quest.valueOf / AccountMetric.valueOf / the caTaskId range check resolved on the Java side (throwaway JUnit test, removed after the run).

Real-world corpus test

test/clan-corpus.test.ts runs ~140 labeled goals collected from a clan Discord (test/fixtures/clan-discord-goals-raw.txt, verbatim) through the full builder — community shorthand, KC goals, account milestones ("Elite CAs" → CA points @ 1064), and the lines that legitimately fall to CUSTOM (greenlogs, outfits, minigames). Add new community examples there; the test names each line so a regression reads as English.

Tools

  • craft_import_string{ mode?, sectionName?, sectionColorRgb?, sharedBy?, goals[]?, sections[]?, confirm? } (sections[] = multi-section/default-target form; each entry is { name?, sectionColorRgb?, targetDefault?, goals[] }). Without confirm: human-readable preview + warnings, no code. With confirm: true: the paste-ready code (GPSHARE1: single-section, GPSHARE2: multi-section).

  • decode_import_string{ code }. Decodes any GPSHARE1:/GPSHARE2: code (even embedded in surrounding text) into a readable breakdown for verification — sections, identifiers, prerequisite tree, per-goal desc:/tooltip: echo, and a Cross-section dependencies list with resolved goal names:

    ── Cross-section dependencies (1) ──
      • "TzKal-Zuk" (section 2 "Inferno prep") requires "Imbued heart" (section 1 "Slayer")
    
  • list_supported_goals — what auto-tracks vs. falls back, plus the skill names.

Goal spec fields

id, type ("skill" / "custom" / a GoalType name), name, description, requires[], orRequires[], and per kind: skills use skill + level or xp; CUSTOM uses colorRgb, tooltip; ITEM_GRIND uses name (resolved to an itemId) or an explicit itemId, plus targetValue (quantity); QUEST uses name (resolved) or explicit questName (enum constant); ACCOUNT uses name or explicit accountMetric plus targetValue; COMBAT_ACHIEVEMENT uses name (exact task) or explicit caTaskId.

Develop

npm install
npm test        # vitest unit + codec/build tests
npm run build   # tsc → dist/
node test/smoke.mjs   # end-to-end MCP stdio smoke test (after build)

Register in Claude

After npm run build, register the server. Project scope — a .mcp.json at a project root (committable; activates when Claude Code runs in that project):

{
  "mcpServers": {
    "goalplanner-share": { "type": "stdio", "command": "node", "args": ["dist/index.js"] }
  }
}

Use a relative dist/index.js only in this repo's own .mcp.json (cwd = repo root). For a .mcp.json in any other project, or for user scope (~/.claude.json → top-level mcpServers, available everywhere), use the absolute path:

{
  "mcpServers": {
    "goalplanner-share": {
      "type": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/goalplanner-share-mcp/dist/index.js"]
    }
  }
}

The server loads at Claude Code startup, so a newly-registered server appears in the next session. Claude Desktop uses the same block in claude_desktop_config.json.

Format

GPSHARE1:<base64url-nopad( gzip( JSON of ShareBundle ) )>

Mirrors the plugin's ShareBundle / GoalShareDto / TagShareDto. The importer is tolerant: unknown goal types are skipped, strings are length-clamped, edges pointing outside the bundle are dropped, and every import lands in a new user section.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选