smart-web-mcp 0.35.1 → 0.37.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/CHANGELOG.md CHANGED
@@ -8,6 +8,7 @@ The format is based on Keep a Changelog[^1] and this project uses SemVer.
8
8
 
9
9
  ### Added
10
10
 
11
+ - `kr_place_search` now provides Korean map-style local recommendations by merging Kakao Local, Google Places, and Naver Local candidates with distance/rating/review-count ranking for 맛집, 카페, 산책, and dog-walk use cases.
11
12
  - Removed hosted API-key provider lanes (Firecrawl, Exa, Tavily, Browserless) from the smart-web runtime/benchmark surface so the default product remains no-secret/local-first.
12
13
  - `smartfetch` now accepts an MCP `output_budget` preset (`compact`, `balanced`, or `full`) and `fetch.outputBudget.preset` settings, so token-sensitive hosts can request smaller structured payloads without hand-tuning every numeric cap.
13
14
  - Added MCP host-profile guidance for Hermes/Raon, Codex, OpenCode, and Claude Code, including budget-control precedence and compact/balanced/full follow-up retrieval guidance.
@@ -76,6 +77,8 @@ The format is based on Keep a Changelog[^1] and this project uses SemVer.
76
77
  - Added compact/balanced/full MCP budget controls for `smartsearch` and `smartcrawl` summary outputs so search/crawl structuredContent is token-bounded by default, not only the rendered text channel.
77
78
  - Added `smartfetch` `pipeline.acquire.attempt_map` so default structured output shows provider seed, direct/impit, Jina Reader, archive, and browser fallback phases with succeeded/failed/skipped status.
78
79
  - Added compact `smartfetch.research_handoff` metadata for blocked, partial, or low-confidence results so downstream research workers and editable report renderers can consume the source URL plus projected `structuredContent` evidence without a new smart-web mode.
80
+ - Added an opt-in local adaptive scraper fallback for Scrapling-compatible `scrapling extract get` commands, recorded as `adaptive_scraper` in `pipeline.acquire.attempt_map` before the browser fallback.
81
+ - Added provider-benchmark coverage for the optional adaptive scraper lane so no-secret local candidates such as Scrapling can be compared against current smartfetch baselines without API keys.
79
82
 
80
83
  ### Changed
81
84
 
@@ -156,6 +159,20 @@ The format is based on Keep a Changelog[^1] and this project uses SemVer.
156
159
  - Korean public API helpers now validate outbound URLs and redirects before fetching, blocking localhost, private, and reserved targets unless `network.allowPrivateHosts` is explicitly enabled.
157
160
  - CI now declares read-only default repository permissions, Dependabot auto-merge pins the reusable workflow without forwarding all caller secrets, and the workflow check enforces those guards.
158
161
 
162
+ ## [0.37.0](https://github.com/jojo-labs/smart-web/compare/v0.36.0...v0.37.0) (2026-06-27)
163
+
164
+
165
+ ### Features
166
+
167
+ * add Korean place search MCP tool ([#401](https://github.com/jojo-labs/smart-web/issues/401)) ([6c8e3ec](https://github.com/jojo-labs/smart-web/commit/6c8e3ec8f9152a0146313efa3e5079456e785bbf))
168
+
169
+ ## [0.36.0](https://github.com/jojo-labs/smart-web/compare/v0.35.1...v0.36.0) (2026-06-25)
170
+
171
+
172
+ ### Features
173
+
174
+ * add adaptive scraper fallback ([#399](https://github.com/jojo-labs/smart-web/issues/399)) ([2e46b7d](https://github.com/jojo-labs/smart-web/commit/2e46b7d29e950f9a7b81b2b6fa5858e76663bc01))
175
+
159
176
  ## [0.35.1](https://github.com/jojo-labs/smart-web/compare/v0.35.0...v0.35.1) (2026-06-24)
160
177
 
161
178
 
package/README.md CHANGED
@@ -30,6 +30,7 @@ If `smart-web` returns reproducible incorrect or misleading output, open a GitHu
30
30
  - docs export manifests are versioned and include per-document SHA-256 hashes plus resource-handle manifests for stable local Markdown mirrors; resource-handle manifests include both exported documents and metadata handles for the summary/manifest files, and successful export `structuredContent` embeds the same handle manifest for host follow-up calls
31
31
  - budgeted `smartfetch` projection records explicit truncation metadata instead of scattering silent hardcoded caps; MCP calls default to the compact preset for token-sensitive agent hosts
32
32
  - weak generic pages can recover through JSON-LD or Next.js payload extraction and same-origin RSS/Atom feed discovery before falling back to a handoff
33
+ - optional local adaptive scraper fallback can call a Scrapling-compatible `scrapling` command for AI-targeted extraction on weak JavaScript shells before spending a full Playwright browser pass
33
34
  - paywalled article pages prefer lawful archive recovery and search-indexed reference previews before telling the host to escalate elsewhere
34
35
  - LinkedIn authwall handling prefers compliant public fallbacks such as archives and search-indexed reference metadata before giving up
35
36
  - legal paper fallback for academic URLs: DOI-aware OpenAlex, Unpaywall, Semantic Scholar, CORE discovery, and Europe PMC enrichment plus bioRxiv/medRxiv API fallback when a direct paper page is thin or blocked
@@ -280,6 +281,13 @@ npx -y smart-web-mcp --init-settings
280
281
  "enableArchiveFallback": true,
281
282
  "enableWayback": true,
282
283
  "enableArchiveMd": true,
284
+ // Optional local adaptive scraper fallback. This is disabled by default;
285
+ // install Scrapling separately and opt in only on deployments that want an
286
+ // extra no-secret local shell/bot-challenge extraction attempt before the
287
+ // built-in Playwright fallback.
288
+ "enableAdaptiveScraper": false,
289
+ "adaptiveScraperCommand": "scrapling",
290
+ "adaptiveScraperTimeoutMs": 20000,
283
291
  // Output projection budget for smartfetch responses. MCP calls use compact
284
292
  // by default unless the caller passes a budget control explicitly; this setting
285
293
  // controls core/CLI defaults and custom deployments.
@@ -363,6 +371,20 @@ This stays opt-in because it is a third-party relay path. When enabled, it only
363
371
 
364
372
  Relay eligibility is provider-policy based. Generic and document-like providers can opt in, while browser/auth/social/commerce providers stay off unless their provider declares support. `pipeline.policy.relay_style_allowed` and `pipeline.policy.relay_style_used` tell hosts whether a relay path was allowed and whether it was used.
365
373
 
374
+ #### Opt in to a local adaptive scraper command
375
+
376
+ ```json
377
+ {
378
+ "fetch": {
379
+ "enableAdaptiveScraper": true,
380
+ "adaptiveScraperCommand": "scrapling",
381
+ "adaptiveScraperTimeoutMs": 20000
382
+ }
383
+ }
384
+ ```
385
+
386
+ This lane is for local, no-secret deployments that install Scrapling or a compatible CLI themselves. It runs only after direct retrieval still looks weak, blocked, or shell-like and before the built-in browser fallback. The attempt is recorded as `adaptive_scraper` in `pipeline.acquire.attempt_map`; if the command is missing, times out, returns empty text, or does not improve the active result, smartfetch keeps the existing result and continues through the normal fallback chain.
387
+
366
388
  #### Tune smartfetch output budgets
367
389
 
368
390
  ```json
@@ -13,4 +13,5 @@ export { runCoupang, renderCoupang } from "./coupang.js";
13
13
  export { runSpellCheck, renderSpellCheck } from "./spellcheck.js";
14
14
  export { runZipcode, renderZipcode } from "./zipcode.js";
15
15
  export { runLaw, renderLaw } from "./law.js";
16
+ export { runPlaceSearch, renderPlaceSearch } from "./place-search.js";
16
17
  export { runPublicRestroom, renderPublicRestroom } from "./public-restroom.js";
@@ -13,5 +13,6 @@ export { runCoupang, renderCoupang } from "./coupang.js";
13
13
  export { runSpellCheck, renderSpellCheck } from "./spellcheck.js";
14
14
  export { runZipcode, renderZipcode } from "./zipcode.js";
15
15
  export { runLaw, renderLaw } from "./law.js";
16
+ export { runPlaceSearch, renderPlaceSearch } from "./place-search.js";
16
17
  export { runPublicRestroom, renderPublicRestroom } from "./public-restroom.js";
17
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/korea/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC3E,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/korea/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC3E,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrE,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,67 @@
1
+ export type PlaceIntent = "auto" | "food" | "cafe" | "walk" | "dog_walk" | "errand" | "date" | "work";
2
+ export type PlaceSort = "blended" | "relevance" | "distance" | "rating" | "review_count";
3
+ export type PlaceProvider = "kakao" | "google" | "naver";
4
+ export type PlaceSearchOptions = {
5
+ query?: string;
6
+ location?: string;
7
+ lat?: number;
8
+ lon?: number;
9
+ radiusM?: number;
10
+ limit?: number;
11
+ intent?: PlaceIntent;
12
+ sort?: PlaceSort;
13
+ providers?: PlaceProvider[];
14
+ timeoutMs?: number;
15
+ };
16
+ export type PlaceSearchAnchor = {
17
+ label: string;
18
+ lat: number;
19
+ lon: number;
20
+ provider: "input" | "kakao" | "google";
21
+ };
22
+ export type ProviderError = {
23
+ provider: PlaceProvider | "anchor";
24
+ code: string;
25
+ status: number;
26
+ message: string;
27
+ };
28
+ export type PlaceItem = {
29
+ name: string;
30
+ category?: string;
31
+ address?: string;
32
+ road_address?: string;
33
+ lat?: number;
34
+ lon?: number;
35
+ distance_m?: number;
36
+ phone?: string;
37
+ rating?: number;
38
+ review_count?: number;
39
+ blog_review_count?: number;
40
+ open_now?: boolean;
41
+ business_status?: string;
42
+ google_place_id?: string;
43
+ kakao_place_id?: string;
44
+ naver_mapx?: string;
45
+ naver_mapy?: string;
46
+ links: Partial<Record<PlaceProvider, string>>;
47
+ providers: PlaceProvider[];
48
+ score: number;
49
+ score_reasons: string[];
50
+ };
51
+ export type PlaceSearchResult = {
52
+ source: "kr-place-search";
53
+ query: string;
54
+ intent: PlaceIntent;
55
+ sort: PlaceSort;
56
+ location_hint?: string;
57
+ anchor?: PlaceSearchAnchor;
58
+ radius_m: number;
59
+ providers_requested: PlaceProvider[];
60
+ providers_used: PlaceProvider[];
61
+ provider_errors: ProviderError[];
62
+ total: number;
63
+ items: PlaceItem[];
64
+ warning?: string;
65
+ };
66
+ export declare function runPlaceSearch(options: PlaceSearchOptions): Promise<PlaceSearchResult>;
67
+ export declare function renderPlaceSearch(result: PlaceSearchResult): string;