sf-docs-agent 0.1.1 → 0.1.2

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
@@ -36,27 +36,39 @@ copies the lines. Every quote is copied word for word from the page, not written
36
36
  check it with one `grep` against the cached copy, which saves curly quotes as straight ones and drops image links and
37
37
  the padding in table rows.
38
38
 
39
- ## 84% less in your context, 63% fewer tokens overall
39
+ ## Why not use Salesforce Docs MCP
40
+
41
+ Salesforce's [salesforce-docs-mcp](https://labs.agentforce.com/docs/salesforce-docs-mcp) works, and behind a
42
+ subagent it was faster and cheaper than sf-docs-agent in my tests. But it searches a closed index you can't see into, with
43
+ no date on its results.
44
+
45
+ I wanted an alternative I control and can validate against the live sites. sf-docs-agent is open source, reads the page
46
+ Salesforce publishes today, and every quote can be checked against that page with one `grep`. If you're fine
47
+ trusting the index, the MCP in a subagent is a good choice. [The comparison](#compared-with-salesforce-docs-mcp) has
48
+ the numbers and the trade-offs.
49
+
50
+ ## 84% less in your context, 38% fewer tokens than platform-docs-get
40
51
 
41
52
  On 10 questions against Salesforce's own platform-docs-get skill, the agent
42
- added 84% fewer tokens to your context and used 63% fewer tokens over the whole session, with the right answer on
43
- 10 of 10.
53
+ added 84% fewer tokens to your context and used 38% fewer tokens over the whole session, with the right answer on
54
+ 39 of 40 runs for each. In the second of four rounds, platform-docs-get missed question 5 and sf-docs-agent missed
55
+ question 4.
44
56
 
45
- Below are the measurements, each read as platform-docs-get → sf-docs.
57
+ Below are the medians of those four rounds, each read as platform-docs-get → sf-docs-agent.
46
58
 
47
59
  | Question | Site | Tokens added to context | Saved | Session token usage | Saved |
48
60
  |---|---|---|---|---|---|
49
- | 1. Scratch org editions | developer | 2,178 → **289** | **86.7%** | 338,852 → **119,355** | **64.8%** |
50
- | 2. Platform event allocation | developer | 4,107 → **490** | **88.1%** | 387,598 → **120,396** | **68.9%** |
51
- | 3. QueryLocator batch limits | developer | 2,568 → **581** | **77.4%** | 406,878 → **113,611** | **72.1%** |
52
- | 4. Integration patterns | architect | 1,104 → **484** | **56.2%** | 154,068 → **125,540** | **18.5%** |
53
- | 5. Salesforce Connect editions | help | 1,948 → **322** | **83.5%** | 382,751 → **157,746** | **58.8%** |
54
- | 6. Flow version limits | help | 4,578 → **290** | **93.7%** | 339,464 → **164,888** | **51.4%** |
55
- | 7. Headless 360 | admin | 3,772 → **380** | **89.9%** | 427,542 → **117,258** | **72.6%** |
56
- | 8. SLDS tooltips | lightningdesignsystem | 3,876 → **414** | **89.3%** | 340,914 → **112,252** | **67.1%** |
57
- | 9. Bulk API batch size | developer | 2,134 → **411** | **80.7%** | 506,340 → **125,870** | **75.1%** |
58
- | 10. Pub/Sub fetch limit | developer | 1,199 → **716** | **40.3%** | 236,766 → **130,110** | **45.0%** |
59
- | **All** | | 27,464 → **4,377** | **84.1%** | 3,521,173 → **1,287,026** | **63.4%** |
61
+ | 1. Scratch org editions | developer | 2,178 → **289** | **86.7%** | 186,768 → **119,355** | **36.1%** |
62
+ | 2. Platform event allocation | developer | 4,107 → **490** | **88.1%** | 245,482 → **120,396** | **51.0%** |
63
+ | 3. QueryLocator batch limits | developer | 2,568 → **581** | **77.4%** | 217,691 → **113,611** | **47.8%** |
64
+ | 4. Integration patterns | architect | 1,104 → **484** | **56.2%** | 127,043 → **125,540** | **1.2%** |
65
+ | 5. Salesforce Connect editions | help | 1,948 → **322** | **83.5%** | 201,770 → **157,746** | **21.8%** |
66
+ | 6. Flow version limits | help | 4,578 → **290** | **93.7%** | 217,138 → **164,888** | **24.1%** |
67
+ | 7. Headless 360 | admin | 3,772 → **380** | **89.9%** | 250,200 → **105,388** | **57.9%** |
68
+ | 8. SLDS tooltips | lightningdesignsystem | 3,876 → **414** | **89.3%** | 201,906 → **112,252** | **44.4%** |
69
+ | 9. Bulk API batch size | developer | 2,134 → **411** | **80.7%** | 255,340 → **125,870** | **50.7%** |
70
+ | 10. Pub/Sub fetch limit | developer | 1,199 → **716** | **40.3%** | 141,826 → **130,110** | **8.3%** |
71
+ | **All** | | 27,464 → **4,377** | **84.1%** | 2,045,164 → **1,275,156** | **37.7%** |
60
72
 
61
73
  <details>
62
74
  <summary>The 10 questions</summary>
@@ -74,6 +86,68 @@ Below are the measurements, each read as platform-docs-get → sf-docs.
74
86
 
75
87
  </details>
76
88
 
89
+ ## Compared with Salesforce Docs MCP
90
+
91
+ Aside from the platform-docs-get skill, Salesforce also has
92
+ [salesforce-docs-mcp](https://labs.agentforce.com/docs/salesforce-docs-mcp), a closed-source public MCP server that
93
+ searches an index of Help articles, developer guides and release notes. I ran the same 10 questions through it in two
94
+ setups:
95
+
96
+ a. MCP in main session: the main agent calls the MCP tools directly
97
+
98
+ b. MCP in a subagent: a subagent whose only tools are the MCP's, with the same report format as sf-docs-agent
99
+
100
+ Three rounds each, medians, same model.
101
+
102
+ | | sf-docs-agent | a. MCP in main session | b. MCP in a subagent |
103
+ |---|---|---|---|
104
+ | Tokens added to context | **4,470** | 45,636 | 5,327 |
105
+ | Session token usage | 1,291,504 | 1,052,673 | **937,229** |
106
+ | Seconds, all 10 | 433 | 239 | **218** |
107
+ | Right answers, of 30 | **30** | 28 | 24 |
108
+ | Quotes that match the text the tools returned, all runs | **113 of 113** | 173 of 188 | 172 of 177 |
109
+ | Quotes on today's page, checked with sf-docs-agent's fetcher, all runs | **113 of 113** | 159 of 188 | 135 of 177 |
110
+
111
+ The MCP in a subagent is faster and uses 27% fewer session tokens than sf-docs-agent, and a. MCP in main session uses
112
+ 18% fewer. Its results come back as markdown excerpts, so I suspect Salesforce keeps a `.md` snapshot of the docs taken
113
+ at some point. Because the index is closed, you can't see what it holds or when it was taken, and that has some costs:
114
+
115
+ - **Coverage.** Across 91 searches it returned no admin.salesforce.com page and no SLDS 2 content page. The
116
+ subagent answered "not found" or wrong on Headless 360 and SLDS tooltips in all three rounds, and those two
117
+ questions hold all 8 wrong MCP answers. In the main session, the model also reached for web search or fetch on 27
118
+ of 30 runs and skipped the MCP on 4; its Headless 360 answers came from admin.salesforce.com through web fetch, not
119
+ the index.
120
+ - **Freshness.** Results carry no date, and some come from the old atlas copy of a page. On question 2 the quotes were
121
+ exact, but the source URL now opens a page without them. On question 1 the wording is older than today's page, with
122
+ the same values. On both questions the values matched the answer key in every MCP run.
123
+ - **Open vs closed.** The index has no published source or refresh schedule. sf-docs-agent reads the live page every time,
124
+ and every quote can be checked with one `grep`.
125
+
126
+ Most of the speed gap is page rendering. Of sf-docs-agent's 30 runs, the 18 that read at least one `.md` page took a
127
+ median 26.5 seconds, against 20.5 for the MCP subagent on the same questions and rounds. Help, admin and the
128
+ Apex Developer Guide had no `.md` copy, so sf-docs-agent rendered them in a headless browser, and the 12 runs that
129
+ rendered every page took a median 68.5 seconds, against 20 for the MCP subagent. The Apex Developer Guide and Apex
130
+ Reference had `.md` copies by 2026-10-31, after these runs; Help, admin, Metadata API and Object Reference still have
131
+ none.
132
+
133
+ <details>
134
+ <summary>Per question, sf-docs-agent / a. MCP in main session / b. MCP in a subagent</summary>
135
+
136
+ | Question | Tokens added to context | Seconds | Right answers, of 3 |
137
+ |---|---|---|---|
138
+ | 1. Scratch org editions | 248 / 5,011 / 421 | 23 / 22 / 18 | 3 / 3 / 3 |
139
+ | 2. Platform event allocation | 526 / 6,177 / 713 | 29 / 28 / 21 | 3 / 3 / 3 |
140
+ | 3. QueryLocator batch limits | 728 / 8,304 / 531 | 68 / 18 / 20 | 3 / 3 / 3 |
141
+ | 4. Integration patterns | 463 / 4,863 / 788 | 25 / 21 / 22 | 3 / 3 / 3 |
142
+ | 5. Salesforce Connect editions | 300 / 3,556 / 381 | 84 / 17 / 18 | 3 / 3 / 3 |
143
+ | 6. Flow version limits | 307 / 2,817 / 291 | 59 / 20 / 19 | 3 / 3 / 3 |
144
+ | 7. Headless 360 | 374 / 4,232 / 772 | 60 / 31 / 31 | 3 / 3 / 0 |
145
+ | 8. SLDS tooltips | 403 / 1,231 / 617 | 32 / 40 / 33 | 3 / 1 / 0 |
146
+ | 9. Bulk API batch size | 489 / 6,284 / 529 | 27 / 22 / 20 | 3 / 3 / 3 |
147
+ | 10. Pub/Sub fetch limit | 632 / 3,161 / 284 | 26 / 20 / 16 | 3 / 3 / 3 |
148
+
149
+ </details>
150
+
77
151
  ## How sf-docs-agent reads each site
78
152
 
79
153
  The agent reads the `.md` copy of a page where the site publishes one. Not every Salesforce docs site does yet.
@@ -86,7 +160,8 @@ The agent finds pages through the site's `llms.txt` index or its sitemaps.
86
160
  | Site | How | Where it finds pages |
87
161
  |---|---|---|
88
162
  | developer.salesforce.com, new docs | the `.md` copy Salesforce publishes | `/docs/llms.txt` and one index per product |
89
- | developer.salesforce.com, atlas docs (Apex, Apex Reference, Metadata API, Object Reference) | renders the page, code samples included | `/docs/llms-product-docs.txt` |
163
+ | developer.salesforce.com, Apex Developer Guide and Apex Reference | the `.md` copy (atlas URLs redirect to the new docs, by 2026-10-31) | `/docs/llms-product-docs.txt` |
164
+ | developer.salesforce.com, atlas docs (Metadata API, Object Reference) | renders the page, code samples included | `/docs/llms-product-docs.txt` |
90
165
  | developer.salesforce.com, API reference pages (`?meta=<operation>`) | renders the page | the product's index |
91
166
  | architect.salesforce.com | the `.md` copy | `/llms.txt` |
92
167
  | help.salesforce.com, articles and knowledge articles | renders the page | links in other docs and articles, and Help's product sitemaps |
@@ -107,7 +182,7 @@ Name the site or product if you know it, and say what you want to know.
107
182
 
108
183
  The sample prompt is broad on purpose: I wanted to see the agent decide what "governors and limits" covers, and whether it could find everything in a broad question.
109
184
 
110
- Here are the results of that prompt, one run each on Opus 5.5 and Sonnet 5.5 at effort high. Each session called the sf-docs agent, which returned quotes with their
185
+ Here are the results of that prompt, one run each on Opus 5.5 and Sonnet 5.5 at effort high. Each session called sf-docs-agent, which returned quotes with their
111
186
  official URLs, and the session turned them into the answer.
112
187
 
113
188
  <details>
@@ -291,9 +366,10 @@ live in `~/.claude/sf-docs/` for every scope, so delete that folder last, once n
291
366
 
292
367
  ## Limitations
293
368
 
294
- - On help, admin, SLDS 1, API reference pages and the atlas guides, the agent finds the article text by where it sits on
295
- the page. If Salesforce changes a layout, it reads the largest block of text instead, which can be one section of the
296
- article, and an article under 1,500 characters can't be read. A daily check in this repo flags the change.
369
+ - On help, admin, SLDS 1, API reference pages and the atlas guides that still render (Metadata API, Object Reference and
370
+ more), the agent finds the article text by where it sits on the page. If Salesforce changes a layout, it reads the
371
+ largest block of text instead, which can be one section of the article, and an article under 1,500 characters can't
372
+ be read. A daily check in this repo flags the change.
297
373
  - A rendered page can take up to 80 seconds before the agent gives up on it (45 s to load, 20 s for content, 15 s for the
298
374
  `.md` copy of a page it redirected to).
299
375
  - No Help search. Help's `robots.txt` disallows it. Help's sitemaps list article ids but not titles.
package/agents/sf-docs.md CHANGED
@@ -43,8 +43,8 @@ that, the printed output is the limit, not time.
43
43
  `duplicate-of <url>` means the body matches an earlier URL: read only the first copy. `same <url> as <url>` means
44
44
  two arguments are one page, fetched once. `(cached)` means it came from disk. Status `0` carries the error.
45
45
  `[redirected <url>]` means the page moved and the Source line names where: check that it is the page you asked for,
46
- since a mistyped atlas topic redirects to its guide's landing page, which is not evidence. That rule also decides a
47
- line that adds `[twin <path>]` (the redirected page read as its `.md`) or `[twin failed: <reason>]` (its rendered
46
+ since a mistyped atlas topic redirects to its guide's landing page, which is not evidence; in the Apex Developer
47
+ Guide, which moved to the new docs, it answers 404 and nothing is saved. That rule also decides a line that adds `[twin <path>]` (the redirected page read as its `.md`) or `[twin failed: <reason>]` (its rendered
48
48
  text kept); a cached run shows `(cached) [redirected <url>]` and no `[twin]`. `not saved` means a shell, login wall or missing page (Help
49
49
  answers 200 for a missing article), or `[api docs did not load]` on an API reference page: not evidence, but a rerun
50
50
  may work. `not saved: <code>` means the page loaded but the cache write failed: rerun. `not saved: left the doc
package/fetch-docs.mjs CHANGED
@@ -451,8 +451,8 @@ try {
451
451
  if (got.sel === 'body') got = await page.evaluate(extract, [CONTENT, true])
452
452
  .catch(e => { console.error(`fallback failed on ${u.href}: ${e.message.split('\n')[0]}`); return got; });
453
453
  const { sel, text, links, hold } = got;
454
- // A redirect is shown and cited: a mistyped atlas topic lands on its guide's landing page with status 200, and a
455
- // Help article can move to another ?id= on the same path.
454
+ // A redirect is shown and cited: a mistyped atlas topic lands on its guide's landing page with status 200 (a 404 in
455
+ // a guide that moved to the new docs), and a Help article can move to another ?id= on the same path.
456
456
  const to = new URL(page.url()), hop = sameDoc(to, u) ? '' : ` [redirected ${to.href}]`;
457
457
  // Old atlas URLs (and the LDS home) redirect to pages that have a .md twin: keep the rendered links, read the twin.
458
458
  const moved = hop && twinOf(to);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sf-docs-agent",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "Claude Code subagent that answers from official Salesforce docs (developer, architect, help, admin, lightningdesignsystem.com) with grep-checked quotes",
6
6
  "devDependencies": {