mcp-scraper 0.29.0 → 0.29.1

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
@@ -88,7 +88,7 @@ Build the branded one-click bundle:
88
88
  npm run build:mcpb
89
89
  ```
90
90
 
91
- The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.29.0`, SHA-256 `382bed0ad851500a9aada6b9d4b30d5c9a2da4c33faffa1b6415a18f14d6c7c0`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, and API-key configuration field from the bundle manifest.
91
+ The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.29.1`, SHA-256 `837b6d05ce5bd0d7f104616d4781c3b33216bd4901887995e62a8e456c2b8804`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, and API-key configuration field from the bundle manifest.
92
92
 
93
93
  The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
94
94
 
@@ -29723,7 +29723,7 @@ var PACKAGE_VERSION;
29723
29723
  var init_version = __esm({
29724
29724
  "src/version.ts"() {
29725
29725
  "use strict";
29726
- PACKAGE_VERSION = "0.29.0";
29726
+ PACKAGE_VERSION = "0.29.1";
29727
29727
  }
29728
29728
  });
29729
29729
 
@@ -29850,8 +29850,8 @@ vaults \u2014 call **list-vaults** to see what exists before creating anything n
29850
29850
  matches the content: **Ideas** (unvalidated concepts), **Knowledge** (distilled lessons/how-tos),
29851
29851
  **Library** (raw source material \u2014 articles, transcripts), **People** (one durable note per person/org),
29852
29852
  **Deals** (commercial opportunities tied to a known person or organization), **Communications** (individual
29853
- conversation records and drafts), **Calendar** (time-anchored entries), **Tasks** (action items linked to a
29854
- known Project), **Projects** (only codebases, known client projects, personal projects, or ongoing siloed
29853
+ conversation records and drafts), **Calendar** (time-anchored entries), **Tasks** (independent Inbox action items
29854
+ that may link to a known Project), **Projects** (only codebases, known client projects, personal projects, or ongoing siloed
29855
29855
  workstreams), **Issues** (something broken),
29856
29856
  **Improvement Log** (receipts of changes made and whether they worked), **Experiments** (hypothesis +
29857
29857
  measured result), **Sprint** (current cycle's scope), **Inspiration** (other people's work worth
@@ -29867,11 +29867,16 @@ they'll filter/sort by exact value. **memory-search** is meaning-based over full
29867
29867
  **memory-list** filters one vault by kind/tags (fast, exact).
29868
29868
 
29869
29869
  For People, Deals, Projects, Tasks, and Communications, use the returned contract rather than guessing:
29870
- People only holds a real person or organization hub; Deals need a known party; Projects need
29871
- \`project_kind\`; every Task needs a verified \`project_ref\` and matching project name; and email drafts
29872
- awaiting human review need \`direction:"draft"\` with \`approval_state:"pending"\`. Link a known person,
29873
- project, deal, or communication when verified. If a required relationship is not clear, ask the user rather
29874
- than creating a free-floating record. Overview is the review queue: editing leaves a draft pending, and
29870
+ People only holds a real person or organization hub. Its contact card uses \`phone\`, \`text_phone\`, and
29871
+ \`email\` for Call/Text/Email; \`memories\` for durable person context; and linked Deals, Projects,
29872
+ Communications, and Calendar records for the other sections. Deals need a known party; Projects need
29873
+ \`project_kind\`; Tasks can be independent Inbox todos or link a verified \`project_ref\` and matching
29874
+ project name; and email drafts awaiting human review need \`direction:"draft"\` with
29875
+ \`approval_state:"pending"\`. Link a known person, project, deal, or communication only when verified.
29876
+ When the user asks to add Gmail or Google Calendar evidence from a connected account, first resolve the
29877
+ existing People hub. Persist Gmail as one linked **Communications** email and Calendar as one linked
29878
+ **Calendar** event, each with the provider's stable reference and \`person_refs\`; do not create a person
29879
+ from a subject line, infer attendees, or silently bulk-import a mailbox/calendar. If a relationship is requested but not clear, ask the user rather than inventing one. Overview is the review queue: editing leaves a draft pending, and
29875
29880
  approval or denial records a state only\u2014it does not send email.
29876
29881
 
29877
29882
  Treat every memory create or update as a graph operation. **prepare-memory-write** supplies the initial
@@ -32326,7 +32331,7 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
32326
32331
  }, async (input) => buildMetaAdCreativeMediaResult(executor, input));
32327
32332
  server.registerTool("import_service_connection_to_memory", {
32328
32333
  title: "Import Connected Service Snapshot to Memory",
32329
- description: "Run exactly one bounded, approved read on a tenant-owned connected service and upsert the redacted result into an existing ordinary Memory vault at a server-generated stable path. The saved document is embedded for RAG and marked as untrusted provider data, never instructions. This is a one-result snapshot: it does not paginate, bulk-import an account, continuously sync changes, propagate deletions, or create normalized tables. Use list_service_connections first and supply an exact current readTools entry; action and admin tools are rejected.",
32334
+ description: "Run exactly one bounded, approved read on a tenant-owned connected service and upsert the redacted result into an existing ordinary Memory vault at a server-generated stable path. The saved document is embedded for RAG and marked as untrusted provider data, never instructions. This is a one-result snapshot: it does not paginate, bulk-import an account, continuously sync changes, propagate deletions, or create normalized tables. It is not a People contact-card activity importer: when the user asks to add verified Gmail or Calendar activity to a person, resolve the People hub and create a linked Communications or Calendar record with stable provider references instead. Use list_service_connections first and supply an exact current readTools entry; action and admin tools are rejected.",
32330
32335
  inputSchema: ImportServiceConnectionToMemoryInputSchema,
32331
32336
  outputSchema: recordOutputSchema("import_service_connection_to_memory", ImportServiceConnectionToMemoryOutputSchema),
32332
32337
  annotations: { title: "Import Connected Service Snapshot to Memory", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true }
@@ -34949,7 +34954,7 @@ var init_memory_tool_schemas = __esm({
34949
34954
  MemoryCaptureSchema = {
34950
34955
  id: "memory-capture",
34951
34956
  upstreamName: "memoryCaptureTool",
34952
- description: "Strict normal-create path for durable memory. Before capture, list the complete tag vocabulary, call prepare-memory-write, run hybrid memory-search for related notes, and read the strongest link candidates. This tool refuses incomplete notes and invalid relationship-domain writes: projects need a project kind, tasks need a verified project, deals need a known party, and draft emails need a pending approval state. It writes through memory-put, registers canonical tags, and verifies persisted content and props. Reserve memory-put for low-level migrations or deliberate edits.",
34957
+ description: "Strict normal-create path for durable memory. Before capture, list the complete tag vocabulary, call prepare-memory-write, run hybrid memory-search for related notes, and read the strongest link candidates. This tool refuses incomplete notes and invalid relationship-domain writes: projects need a project kind, tasks can be independent Inbox todos or link a verified project, deals need a known party, and draft emails need a pending approval state. It writes through memory-put, registers canonical tags, and verifies persisted content and props. Reserve memory-put for low-level migrations or deliberate edits.",
34953
34958
  input: {
34954
34959
  vault: import_zod37.z.string(),
34955
34960
  folder: import_zod37.z.string().optional(),
@@ -35007,7 +35012,7 @@ var init_memory_tool_schemas = __esm({
35007
35012
  PrepareMemoryWriteSchema = {
35008
35013
  id: "prepare-memory-write",
35009
35014
  upstreamName: "prepareMemoryWriteTool",
35010
- description: "Mandatory planning pass for a normal new memory. First inspect the complete tag vocabulary with list-memory-tags; then this pass routes the note, returns the live template and natural vault relationships, resolves proposed tags, and shortlists interlinks. For People, Deals, Projects, Tasks, and Communications, it also returns required relationship and approval guidance: search existing records first and ask rather than inventing a missing project or party. Use hybrid memory-search (3 focused queries, 50 fused candidates, bounded graph expansion, rerank to 30 by default) and read strong related notes before capture. This is an explicit AI workflow directive, not a claim of persisted call-order enforcement.",
35015
+ description: "Mandatory planning pass for a normal new memory. First inspect the complete tag vocabulary with list-memory-tags; then this pass routes the note, returns the live template and natural vault relationships, resolves proposed tags, and shortlists interlinks. For People, Deals, Projects, Tasks, and Communications, it also returns relationship and approval guidance: a Task may be an independent Inbox todo, so search existing records only before adding a requested project or party link and never invent one. Use hybrid memory-search (3 focused queries, 50 fused candidates, bounded graph expansion, rerank to 30 by default) and read strong related notes before capture. This is an explicit AI workflow directive, not a claim of persisted call-order enforcement.",
35011
35016
  input: {
35012
35017
  title: import_zod37.z.string().min(1),
35013
35018
  content: import_zod37.z.string().min(1),
@@ -35714,7 +35719,7 @@ var init_memory_tool_schemas = __esm({
35714
35719
  PutSchema = {
35715
35720
  id: "memory-put",
35716
35721
  upstreamName: "putTool",
35717
- description: "Create or deliberately edit one note at a path in a memory vault; content is persisted and indexed for search. For normal new People, Deals, Projects, Tasks, or Communications records, use prepare-memory-write then memory-capture: People must be real people or organizations, Deals need a known party, Projects need a supported kind, Tasks need a verified Project, and draft emails need pending approval. For row-shaped datasets you'll filter/sort by exact value, use table-create/table-insert-rows/table-query instead. Ordinary vaults are indexed and shareable \u2014 never store real secrets there; use a secure vault (create-secure-vault) instead, which is never indexed or shareable and is encrypted at rest. Requires write scope.",
35722
+ description: "Create or deliberately edit one note at a path in a memory vault; content is persisted and indexed for search. For normal new People, Deals, Projects, Tasks, or Communications records, use prepare-memory-write then memory-capture: People must be real people or organizations, Deals need a known party, Projects need a supported kind, Tasks may be independent Inbox todos or use a verified Project link when requested, and draft emails need pending approval. For row-shaped datasets you'll filter/sort by exact value, use table-create/table-insert-rows/table-query instead. Ordinary vaults are indexed and shareable \u2014 never store real secrets there; use a secure vault (create-secure-vault) instead, which is never indexed or shareable and is encrypted at rest. Requires write scope.",
35718
35723
  input: {
35719
35724
  vault: import_zod37.z.string().optional().describe(
35720
35725
  "Vault to write to. Optional; defaults to the session active vault, then the first vault the caller is entitled to. On a default-provisioned account, pick the vault whose job matches the content (see the server instructions for the full 15-vault guide) rather than defaulting blindly \u2014 e.g. a lesson learned goes in Knowledge, the raw source it came from goes in Library, a broken feature goes in Issues, a named real-world initiative goes in Projects. Do not use this low-level tool to create ordinary People, Deals, Projects, Tasks, or Communications records: first use prepare-memory-write then memory-capture so relationships and approval state are validated."
@@ -41231,6 +41236,7 @@ function defaultType(vault) {
41231
41236
  if (vault === "Deals") return "deal";
41232
41237
  if (vault === "Projects") return "project";
41233
41238
  if (vault === "Tasks") return "task";
41239
+ if (vault === "Calendar") return "event";
41234
41240
  return "unclassified";
41235
41241
  }
41236
41242
  function defaultStatus(vault) {
@@ -41238,6 +41244,7 @@ function defaultStatus(vault) {
41238
41244
  if (vault === "Deals") return "lead";
41239
41245
  if (vault === "Projects") return "active";
41240
41246
  if (vault === "Tasks") return "to_do";
41247
+ if (vault === "Calendar") return "scheduled";
41241
41248
  return "inbox";
41242
41249
  }
41243
41250
  function nonEmptyStrings(value) {
@@ -41260,9 +41267,9 @@ function validateNewRecord(vault, props) {
41260
41267
  }
41261
41268
  if (vault === "Tasks") {
41262
41269
  if (!["task", "milestone"].includes(type)) return "Tasks records must have type task or milestone";
41263
- if (typeof props.project_ref !== "string" || !props.project_ref.trim() || typeof props.project !== "string" || !props.project.trim()) {
41264
- return "Tasks must be linked to an existing project";
41265
- }
41270
+ const hasProjectRef = typeof props.project_ref === "string" && props.project_ref.trim().length > 0;
41271
+ const hasProjectTitle = typeof props.project === "string" && props.project.trim().length > 0;
41272
+ if (hasProjectRef !== hasProjectTitle) return "Tasks project_ref and project must be supplied together when a task is linked to a project";
41266
41273
  }
41267
41274
  if (vault === "Communications") {
41268
41275
  if (!["email", "slack", "message", "call", "meeting", "social_media", "thread", "decision"].includes(type)) return "Communications records need a valid communication type";
@@ -41321,7 +41328,7 @@ var init_vault_routes = __esm({
41321
41328
  "use strict";
41322
41329
  import_hono22 = require("hono");
41323
41330
  init_memory();
41324
- VAULTS = ["People", "Deals", "Projects", "Tasks", "Communications"];
41331
+ VAULTS = ["People", "Deals", "Projects", "Tasks", "Communications", "Calendar"];
41325
41332
  MAX_VAULT_RECORDS = 200;
41326
41333
  MAX_MEMORY_READ_CONCURRENCY = 4;
41327
41334
  MAX_MEMORY_READ_ATTEMPTS = 3;
@@ -41397,12 +41404,15 @@ var init_vault_routes = __esm({
41397
41404
  }
41398
41405
  const current = await readMemory("getTool", { vault, path: path6 }, token);
41399
41406
  if (!current.ok || !current.note) return c.json(current, current.ok ? 404 : 502);
41407
+ const nextProps = { ...current.note.props ?? {}, ...props ?? {} };
41408
+ const validationError = validateNewRecord(vault, nextProps);
41409
+ if (validationError) return c.json({ ok: false, error: validationError }, 400);
41400
41410
  const result = await memoryCall("putTool", {
41401
41411
  vault,
41402
41412
  path: path6,
41403
41413
  title: title ?? current.note.title,
41404
41414
  content: content ?? current.note.content,
41405
- props: { ...current.note.props ?? {}, ...props ?? {} },
41415
+ props: nextProps,
41406
41416
  baseRevision: baseRevision ?? current.note.revision
41407
41417
  }, token);
41408
41418
  return c.json(result, result.ok ? 200 : result.conflict ? 409 : 502);