@iamjameslennon/ddb-mcp 2.8.0 → 2.9.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.
Files changed (88) hide show
  1. package/dist/browser.d.ts.map +1 -1
  2. package/dist/browser.js +19 -4
  3. package/dist/browser.js.map +1 -1
  4. package/dist/index.js +10 -18
  5. package/dist/index.js.map +1 -1
  6. package/dist/tools/campaign.js +1 -1
  7. package/dist/tools/campaign.js.map +1 -1
  8. package/dist/tools/character/ac.d.ts +20 -0
  9. package/dist/tools/character/ac.d.ts.map +1 -0
  10. package/dist/tools/character/ac.js +83 -0
  11. package/dist/tools/character/ac.js.map +1 -0
  12. package/dist/tools/character/actions.d.ts +22 -0
  13. package/dist/tools/character/actions.d.ts.map +1 -0
  14. package/dist/tools/character/actions.js +110 -0
  15. package/dist/tools/character/actions.js.map +1 -0
  16. package/dist/tools/character/core.d.ts +15 -0
  17. package/dist/tools/character/core.d.ts.map +1 -0
  18. package/dist/tools/character/core.js +129 -0
  19. package/dist/tools/character/core.js.map +1 -0
  20. package/dist/tools/character/defenses.d.ts +16 -0
  21. package/dist/tools/character/defenses.d.ts.map +1 -0
  22. package/dist/tools/character/defenses.js +27 -0
  23. package/dist/tools/character/defenses.js.map +1 -0
  24. package/dist/tools/character/definition.d.ts +14 -0
  25. package/dist/tools/character/definition.d.ts.map +1 -0
  26. package/dist/tools/character/definition.js +205 -0
  27. package/dist/tools/character/definition.js.map +1 -0
  28. package/dist/tools/character/features.d.ts +26 -0
  29. package/dist/tools/character/features.d.ts.map +1 -0
  30. package/dist/tools/character/features.js +107 -0
  31. package/dist/tools/character/features.js.map +1 -0
  32. package/dist/tools/character/helpers.d.ts +57 -0
  33. package/dist/tools/character/helpers.d.ts.map +1 -0
  34. package/dist/tools/character/helpers.js +80 -0
  35. package/dist/tools/character/helpers.js.map +1 -0
  36. package/dist/tools/character/identity.d.ts +19 -0
  37. package/dist/tools/character/identity.d.ts.map +1 -0
  38. package/dist/tools/character/identity.js +84 -0
  39. package/dist/tools/character/identity.js.map +1 -0
  40. package/dist/tools/character/inventory.d.ts +21 -0
  41. package/dist/tools/character/inventory.d.ts.map +1 -0
  42. package/dist/tools/character/inventory.js +61 -0
  43. package/dist/tools/character/inventory.js.map +1 -0
  44. package/dist/tools/character/notes.d.ts +20 -0
  45. package/dist/tools/character/notes.d.ts.map +1 -0
  46. package/dist/tools/character/notes.js +63 -0
  47. package/dist/tools/character/notes.js.map +1 -0
  48. package/dist/tools/character/parse.d.ts +13 -0
  49. package/dist/tools/character/parse.d.ts.map +1 -0
  50. package/dist/tools/character/parse.js +82 -0
  51. package/dist/tools/character/parse.js.map +1 -0
  52. package/dist/tools/character/spells.d.ts +26 -0
  53. package/dist/tools/character/spells.d.ts.map +1 -0
  54. package/dist/tools/character/spells.js +237 -0
  55. package/dist/tools/character/spells.js.map +1 -0
  56. package/dist/tools/character/stats.d.ts +33 -0
  57. package/dist/tools/character/stats.d.ts.map +1 -0
  58. package/dist/tools/character/stats.js +372 -0
  59. package/dist/tools/character/stats.js.map +1 -0
  60. package/dist/tools/character/templates.d.ts +22 -0
  61. package/dist/tools/character/templates.d.ts.map +1 -0
  62. package/dist/tools/character/templates.js +61 -0
  63. package/dist/tools/character/templates.js.map +1 -0
  64. package/dist/tools/character/types.d.ts +133 -0
  65. package/dist/tools/character/types.d.ts.map +1 -0
  66. package/dist/tools/character/types.js +12 -0
  67. package/dist/tools/character/types.js.map +1 -0
  68. package/dist/tools/character/vitals.d.ts +34 -0
  69. package/dist/tools/character/vitals.d.ts.map +1 -0
  70. package/dist/tools/character/vitals.js +198 -0
  71. package/dist/tools/character/vitals.js.map +1 -0
  72. package/dist/tools/character/weapons.d.ts +13 -0
  73. package/dist/tools/character/weapons.d.ts.map +1 -0
  74. package/dist/tools/character/weapons.js +79 -0
  75. package/dist/tools/character/weapons.js.map +1 -0
  76. package/dist/tools/character.d.ts +13 -3
  77. package/dist/tools/character.d.ts.map +1 -1
  78. package/dist/tools/character.js +18 -1181
  79. package/dist/tools/character.js.map +1 -1
  80. package/dist/tools/library.d.ts +32 -4
  81. package/dist/tools/library.d.ts.map +1 -1
  82. package/dist/tools/library.js +181 -86
  83. package/dist/tools/library.js.map +1 -1
  84. package/dist/tools/search.d.ts +1 -2
  85. package/dist/tools/search.d.ts.map +1 -1
  86. package/dist/tools/search.js +36 -59
  87. package/dist/tools/search.js.map +1 -1
  88. package/package.json +2 -1
@@ -1,64 +1,41 @@
1
- import { getPage } from "../browser.js";
2
- export async function search(context, query, category = "all") {
3
- const page = await getPage(context);
4
- const categoryPaths = {
5
- spells: "spells",
6
- monsters: "monsters",
7
- items: "magic-items",
8
- races: "races",
9
- classes: "classes",
10
- feats: "feats",
11
- all: "search",
12
- };
13
- const path = categoryPaths[category];
14
- const encodedQuery = encodeURIComponent(query);
15
- let searchUrl;
16
- if (category === "all") {
17
- searchUrl = `https://www.dndbeyond.com/search?q=${encodedQuery}`;
1
+ import { searchSpells, searchItems, searchRaces, searchClasses, searchFeats } from "./reference.js";
2
+ import { searchMonsters } from "./monster.js";
3
+ const ALL_CATEGORIES = ["spells", "monsters", "items", "races", "classes", "feats"];
4
+ const CATEGORY_LABELS = {
5
+ spells: "Spells",
6
+ monsters: "Monsters",
7
+ items: "Items",
8
+ races: "Races",
9
+ classes: "Classes",
10
+ feats: "Feats",
11
+ };
12
+ // Each underlying search returns its own "no results" sentence. Detect them so
13
+ // we can omit empty sections in the "all" rollup.
14
+ const EMPTY_RESULT_PATTERN = /^no\s+\w+\s+found/i;
15
+ export async function search(query, category = "all") {
16
+ if (category !== "all") {
17
+ return runCategory(category, query);
18
18
  }
19
- else {
20
- searchUrl = `https://www.dndbeyond.com/${path}?filter-search=${encodedQuery}`;
19
+ const results = await Promise.all(ALL_CATEGORIES.map(c => runCategory(c, query).catch(err => `_${err instanceof Error ? err.message : String(err)}_`)));
20
+ const sections = [];
21
+ for (let i = 0; i < ALL_CATEGORIES.length; i++) {
22
+ const body = results[i].trim();
23
+ if (!body || EMPTY_RESULT_PATTERN.test(body))
24
+ continue;
25
+ sections.push(`## ${CATEGORY_LABELS[ALL_CATEGORIES[i]]}\n\n${body}`);
21
26
  }
22
- await page.goto(searchUrl, { waitUntil: "domcontentloaded", timeout: 30000 });
23
- await page.waitForSelector(".listing-body, .search-result, .results-item", { timeout: 15000 }).catch(() => { });
24
- const results = await page.evaluate((cat) => {
25
- const items = [];
26
- if (cat === "all") {
27
- // General search results page
28
- document.querySelectorAll(".search-result, .results-item").forEach((el) => {
29
- const nameLink = el.querySelector("a.result-title, a.listing-name, h2 a, h3 a");
30
- const name = nameLink?.textContent?.trim() ?? el.querySelector("h2, h3")?.textContent?.trim() ?? "";
31
- const type = el.querySelector(".result-category, .result-type, .listing-tag")?.textContent?.trim() ?? "";
32
- const link = (nameLink ?? el.querySelector("a"))?.href ?? "";
33
- const path = link ? new URL(link).pathname : "";
34
- if (name)
35
- items.push({ name, type, url: path });
36
- });
37
- }
38
- else {
39
- // Category listing page — items are in div.info[data-slug] containers
40
- document.querySelectorAll(".listing-body div.info[data-slug]").forEach((el) => {
41
- // Use a.link for the name — avoids picking up child tags like <i class="i-concentration">
42
- const nameLink = el.querySelector("a.link");
43
- const name = nameLink?.textContent?.trim() ?? "";
44
- const url = nameLink?.href ?? "";
45
- const path = url ? new URL(url).pathname : "";
46
- // Pull level/CR/rarity from typed rows (avoids the noisy name row)
47
- const levelEl = el.querySelector(".row.spell-level span, .row.monster-challenge span, .row.item-rarity span, .row.class-level span, .row.feat-prerequisite span");
48
- const schoolEl = el.querySelector(".row.spell-school .school");
49
- const schoolName = schoolEl
50
- ? (schoolEl.className.replace("school", "").trim() || "")
51
- : "";
52
- const extras = [levelEl?.textContent?.trim(), schoolName].filter(Boolean).join(" | ");
53
- if (name)
54
- items.push({ name, type: extras, url: path });
55
- });
56
- }
57
- return items;
58
- }, category);
59
- if (results.length === 0) {
60
- return `No results found for "${query}" in category "${category}". The page URL was: ${searchUrl}`;
27
+ if (sections.length === 0)
28
+ return `No results found for "${query}".`;
29
+ return [`# Search results for "${query}"`, ...sections].join("\n\n");
30
+ }
31
+ async function runCategory(category, query) {
32
+ switch (category) {
33
+ case "spells": return searchSpells({ name: query, limit: 10 });
34
+ case "monsters": return searchMonsters({ name: query });
35
+ case "items": return searchItems({ name: query });
36
+ case "races": return searchRaces(query, 10, 0);
37
+ case "classes": return searchClasses(query, 10, 0);
38
+ case "feats": return searchFeats({ name: query, limit: 10, offset: 0 });
61
39
  }
62
- return JSON.stringify({ query, category, count: results.length, results });
63
40
  }
64
41
  //# sourceMappingURL=search.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACpG,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI9C,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAU,CAAC;AAG7F,MAAM,eAAe,GAAqC;IACxD,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;CACf,CAAC;AAEF,+EAA+E;AAC/E,kDAAkD;AAClD,MAAM,oBAAoB,GAAG,oBAAoB,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAa,EAAE,WAA2B,KAAK;IAC1E,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACvB,OAAO,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CACrB,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAC5F,CACF,CAAC;IAEF,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QACvD,QAAQ,CAAC,IAAI,CAAC,MAAM,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,yBAAyB,KAAK,IAAI,CAAC;IACrE,OAAO,CAAC,yBAAyB,KAAK,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACvE,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,QAA0B,EAAE,KAAa;IAClE,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ,CAAC,CAAG,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QACjE,KAAK,UAAU,CAAC,CAAC,OAAO,cAAc,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACxD,KAAK,OAAO,CAAC,CAAI,OAAO,WAAW,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,KAAK,OAAO,CAAC,CAAI,OAAO,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAClD,KAAK,SAAS,CAAC,CAAE,OAAO,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACpD,KAAK,OAAO,CAAC,CAAI,OAAO,WAAW,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iamjameslennon/ddb-mcp",
3
- "version": "2.8.0",
3
+ "version": "2.9.0",
4
4
  "description": "D&D Beyond MCP Server with Google Auth",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -32,6 +32,7 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@modelcontextprotocol/sdk": "^1.0.0",
35
+ "cheerio": "^1.2.0",
35
36
  "playwright": "^1.49.0"
36
37
  },
37
38
  "devDependencies": {