goalplanner-share-mcp
This server generates and decodes RuneLite Goal Planner import codes (GPSHARE1:/GPSHARE2:) from structured goal specifications, enabling natural-language goal planning and verification.
Craft import strings: Convert goal descriptions into import codes, with a preview mode that shows a human-readable breakdown before confirming.
Multi-section support: Create one code with multiple named sections, targeting a default plan with deduplication.
Cross-section dependencies: Wire goals across sections via explicit IDs, with cycle detection and ambiguous ID handling.
Complex prerequisite trees: Support
requires(AND) andorRequires(OR) logic, including diamond and OR‑group structures.Typed auto‑tracking goals: Recognize SKILL, BOSS, QUEST, DIARY, ITEM_GRIND, ACCOUNT, COMBAT_ACHIEVEMENT, and CUSTOM types, with fallback warnings.
Group expansion: Automatically expand phrases like "full torva" or "all elite diaries" into multiple goals.
Repeatable goals: Set
repeatEvery(DAILY/WEEKLY/MONTHLY) for recurring tasks.Decode import strings: Decode any GPSHARE1/2 code (even embedded in text) into a detailed breakdown for verification.
List supported goals: Report auto‑tracked goal types and recognized skill names to help users decide goal handling.
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 withtargetDefault: truelands 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 theGPSHARE1: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 mayrequires/orRequiresa goal in a different section by its explicitid. The edge rides the bundle-levelcrossEdgeswire field (mirroring the plugin'sCrossEdgeDto) 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 goalSimple goals or complex trees: goals are wired into prerequisite trees (AND via
requires, OR viaorRequires) by stableid. 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_stringrenders 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 withconfirm: 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 by level or XP (all 24 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 |
🧩 Group expansion (one phrase → many goals) | item sets/loadouts, boss & diary groups |
|
🔁 Repeatable |
|
|
🔶 Passthrough (unverified) | unknown | emitted as supplied with an UNVERIFIED warning; unresolvable names fall back to CUSTOM with did-you-mean suggestions |
🗺️ Roadmap | CA tier groups ( |
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.
Related MCP server: superpowers-mcp
Tools
craft_import_string—{ mode?, sectionName?, sectionColorRgb?, sharedBy?, goals[]?, sections[]?, confirm? }(sections[]= multi-section/default-target form; each entry is{ name?, sectionColorRgb?, targetDefault?, goals[] }). Withoutconfirm: human-readable preview + warnings, no code. Withconfirm: true: the paste-ready code (GPSHARE1:single-section,GPSHARE2:multi-section).decode_import_string—{ code }. Decodes anyGPSHARE1:/GPSHARE2:code (even embedded in surrounding text) into a readable breakdown for verification — sections, identifiers, prerequisite tree, per-goaldesc:/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.
Deploying changes
There is no hosted or remote deployment — this is a local stdio MCP server. Each user runs
it from dist/index.js on their own machine (the mcpServers block above); the client spawns
it over stdio at startup.
Because the client runs the built dist/, not the TypeScript source, changes only take
effect after a rebuild:
Pull / make your edits (source lives in
src/; reference data insrc/refdata/).npm run build—dist/is gitignored, so this is always a fresh local build, never committed.Restart the client (or reconnect the server) so the new
dist/is loaded — it's read once at startup.
Skipping the rebuild is the usual cause of a stale server serving old data (e.g. regenerated
refdata/ that hasn't been compiled into dist/ yet). If you regenerate reference data with any
npm run gen:* script, follow it with npm run build before the change reaches the running server.
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.
Available Tools
3 toolscraft_import_stringCraft a Goal Planner import stringA
Build a RuneLite Goal Planner import code from a structured goal spec — either ONE section (goals[], GPSHARE1 wire, imports on every plugin build) or MULTIPLE sections at once (sections[], GPSHARE2 wire, including default-plan targeting with reuse-dedup). By DEFAULT (no confirm) it returns a rendering of the goal list as it will appear — section header, each goal with its type/target, prerequisites nested as a guide tree, and per-goal tracking badges — plus warnings, and NO code. Show that to the user so they can adjust the goals; re-run for an updated preview. Only once they confirm it matches their intent, call again with the same goals and confirm:true to receive the paste-ready code. Supports simple goals and complex prerequisite trees (wire via id + requires/orRequires). CRAFTING CONVENTIONS: (1) Keep sections FLAT — never invent parent/summary CUSTOM goals (e.g. an "X log complete" goal requiring the items) unless the user explicitly asks for that structure; a list of items is just the item goals. (2) Prefer typed goals over CUSTOM with a narrative name — account-shaped goals ("maintain quest cape", "reach elite combat achievements", "2100 total level") should be type ACCOUNT with the PHRASE as name: the resolver implies the metric AND milestone, and the goal displays the canonical metric name. Only pass an explicit accountMetric constant when you need a custom display name — usually you don't.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | "section" = import as a new named section; "goals" = loose goals (land in a "Shared goals" section). Ignored when sections[] is used. | |
| sectionName | No | Name for the new section (mode "section"). | |
| sectionColorRgb | No | Section colour 0xRRGGBB; -1 = default. | |
| sharedBy | No | Attribution shown in the import prompt. | |
| goals | No | Single-section form: the goals to encode (GPSHARE1 wire — every plugin build imports it). Relations are wired by id via requires/orRequires. | |
| sections | No | Multi-section form: several sections in ONE code (GPSHARE2 wire — recipients need a recent plugin build). Each entry imports as its own section; an entry with targetDefault:true lands in the recipient's Default plan with reuse-dedup. Goals may require goals in OTHER sections by their explicit id (emitted as cross-section edges). Use this OR goals, not both. | |
| confirm | No | Omit/false to get a preview ONLY (no code). Set true to emit the import code after the user confirms the preview. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: default returns preview with rendering and warnings, confirm:true returns paste-ready code; explains GPSHARE1 vs GPSHARE2 wires, reuse-dedup for multi-section, and crafting conventions. This is comprehensive and compensates for lack of annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is verbose with multiple paragraphs and detailed crafting conventions. While well-structured, it could be more concise. The essential information is front-loaded, but the crafting conventions might be better placed elsewhere.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (two modes, nested parameters, two-phase workflow), the description covers all necessary context: preview vs confirm behavior, wire formats, dedup rules, and crafting guidelines. No output schema exists, but return values are clearly described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by explaining the workflow implications (e.g., confirm flag behavior, dedup with targetDefault) and contextual details like wire formats, exceeding mere parameter explanations.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Build a RuneLite Goal Planner import code from a structured goal spec'. It distinguishes two modes (single section vs multiple sections) and the confirm workflow, making it distinct from sibling tools (decode_import_string and list_supported_goals).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: when to use single-section vs multi-section, the preview-then-confirm flow, and crafting conventions. It lacks explicit 'when not to use' statements but effectively differentiates from siblings through context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
decode_import_stringDecode a Goal Planner import stringA
Decode a GPSHARE1:/GPSHARE2: code back into a readable breakdown (sections, goals, identifiers, descriptions/tooltips, prerequisite tree, cross-section dependencies) for verification. Tolerates surrounding text — paste the whole message containing the code.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | A GPSHARE1: or GPSHARE2: import code (may be embedded in other text). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries full burden. It discloses that the tool decodes codes, tolerates embedded text, and returns a breakdown of various elements. It does not mention side effects or error behavior, but for a read-only decoding tool this is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence followed by a short tip, both front-loaded and concise. Every part adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description thoroughly explains the output format (readable breakdown with sections, goals, etc.) and input tolerance. It covers key behavioral aspects for a single-parameter decoding tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and describes the 'code' parameter. The description adds practical context: 'Tolerates surrounding text — paste the whole message containing the code,' which aids agent understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Decode' and the resource 'GPSHARE1:/GPSHARE2: code', and specifies the output as a readable breakdown with components like sections, goals, and dependencies. It implicitly distinguishes from siblings: craft_import_string (encoding) and list_supported_goals (listing goals).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a specific usage tip: 'Tolerates surrounding text — paste the whole message containing the code.' It provides clear context but does not explicitly state when not to use or name alternatives, though sibling differentiation is implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_supported_goalsList supported goal typesA
Report which goal kinds the crafter auto-tracks (typed core) vs. emits as CUSTOM, plus the recognized skill names. Use this to decide whether a requested goal will track on the recipient's account.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It transparently discloses that the tool reports two types of goals and skill names, implying a read-only, informational operation with no side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the purpose, and contains no unnecessary words. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description fully explains what the tool returns (goal types and skill names) and its decision-support purpose, making it complete for a simple listing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters are defined in the input schema, so the description need not add parameter info. Baseline score of 4 applies as no param details are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'report' and the resource 'goal kinds' with specific details (auto-tracked vs. CUSTOM, plus skill names), and distinguishes from sibling tools like craft_import_string by its use case of deciding tracking.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool ('Use this to decide whether a requested goal will track on the recipient's account'), providing clear context for usage without naming alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool serves a distinct purpose: craft builds import strings, decode reverses them, and list_supported_goals provides metadata. There is no functional overlap.
All tool names follow a verb_noun snake_case pattern (craft_import_string, decode_import_string, list_supported_goals), consistent across the set.
Three tools is an appropriate scope for a share utility: create, decode, and introspect. No unnecessary tools, and no obvious missing ones.
The tool surface covers the full workflow: constructing an import string, decoding an existing string, and checking supported goal types. No gaps for the stated purpose.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for generating rough-draft project plans from natural-language prompts.
MCP server for RiverScript, an AI transcription platform - fetches transcripts shared via a link.
Capability registry for the agentic economy. Semantic search over verified MCP server listings.
Related MCP Servers
- FlicenseAqualityCmaintenanceAn MCP server for Path of Exile 2 build analysis that loads builds from Path of Building export codes and allows natural language interrogation via any MCP-compatible client.82
- AlicenseNot gradedqualityDmaintenanceAn MCP server that makes superpowers skills available to any LLM that supports the Model Context Protocol.1,40017MIT
- AlicenseNot gradedqualityAmaintenanceAn unofficial MCP server that connects AI assistants to Microsoft Planner, enabling natural language task management such as creating tasks, organizing plans, and managing buckets.11MIT
- FlicenseAqualityDmaintenanceAn MCP server that gives AI assistants direct access to Atlassian Goals and Atlassian Projects via the Townsquare / Atlas GraphQL API.4
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/AKAddons/goalplanner-share-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server