@xiaou66/vite-plugin-vue-mcp-next 1.1.0 → 1.2.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/README.md CHANGED
@@ -15,6 +15,7 @@
15
15
  | Console 日志 | Runtime Hook | CDP 优先,Hook 兜底 | 采集 `log/info/warn/error/debug` 和运行时日志 |
16
16
  | Evaluate 控制台执行 | Runtime Hook | CDP 优先,Hook 兜底 | 默认关闭,必须显式开启 |
17
17
  | Network 请求 | Runtime Hook | CDP 优先,Hook 兜底 | 返回请求 URL、query、body、status、headers、response body |
18
+ | 浏览器存储 | Runtime Hook | CDP 优先,Hook 兜底 | 访问同源 Web Storage、IndexedDB;Cookie 在无 CDP 时回退到 `document.cookie` |
18
19
  | Vue 组件树 | Vue Runtime Bridge | Vue Runtime Bridge | Vue 专属语义不走 CDP |
19
20
  | Vue 组件状态 | Vue Runtime Bridge | Vue Runtime Bridge | 读取和编辑组件状态 |
20
21
  | Router 信息 | Vue Runtime Bridge | Vue Runtime Bridge | 返回当前路由和路由表 |
@@ -548,6 +549,25 @@ interface NetworkRecord {
548
549
 
549
550
  Vue 组件、Router、Pinia 是应用层语义,固定走 Vue Runtime Bridge,不用 CDP 替代。
550
551
 
552
+ ### 浏览器存储
553
+
554
+ 浏览器存储工具组面向调试当前页面的运行时数据。`localStorage`、`sessionStorage` 和 `IndexedDB` 只作用于当前选中页面同源,避免跨站误操作。Cookie 在无 CDP 时通过 `document.cookie` 访问当前页面可见的同源条目;配置 CDP 后可查询浏览器级 Cookie,并能读取 `HttpOnly` 条目,但删除和清空时会跳过 `HttpOnly` 并返回跳过数量。
555
+
556
+ | 资源 | Runtime Hook | CDP |
557
+ | --- | --- | --- |
558
+ | `localStorage` | 读 / 写 / 删 | 读 / 写 / 删 |
559
+ | `sessionStorage` | 读 / 写 / 删 | 读 / 写 / 删 |
560
+ | `IndexedDB` | 同源库和记录操作 | 同源库和记录操作 |
561
+ | `Cookie` | 查询 / 写入 / 删除当前页面可见条目 | 查询 / 写入 / 删除非 `HttpOnly` 条目,`HttpOnly` 仅可查询 |
562
+
563
+ 相关 MCP 工具:
564
+
565
+ - `list_storage`:列出当前页面同源存储和 Cookie;有 CDP 时补充浏览器级 Cookie
566
+ - `get_storage_item`:读取指定 key、IndexedDB 记录或 Cookie
567
+ - `set_storage_item`:写入 Web Storage、IndexedDB 记录或 Cookie
568
+ - `delete_storage_item`:删除 Web Storage、IndexedDB 记录或 Cookie;`HttpOnly` Cookie 仅在 CDP 下可见且删除时会跳过
569
+ - `clear_storage`:清空指定范围,Cookie 清空会跳过 `HttpOnly`
570
+
551
571
  ## 本地验证
552
572
 
553
573
  ### 自动化检查
package/dist/index.cjs CHANGED
@@ -72,6 +72,11 @@ var MCP_TOOL_NAMES = {
72
72
  getNetworkRequests: "get_network_requests",
73
73
  getNetworkRequestDetail: "get_network_request_detail",
74
74
  clearNetworkRequests: "clear_network_requests",
75
+ listStorage: "list_storage",
76
+ getStorageItem: "get_storage_item",
77
+ setStorageItem: "set_storage_item",
78
+ deleteStorageItem: "delete_storage_item",
79
+ clearStorage: "clear_storage",
75
80
  recordPerformance: "record_performance",
76
81
  startPerformanceRecording: "start_performance_recording",
77
82
  stopPerformanceRecording: "stop_performance_recording",
@@ -1543,9 +1548,431 @@ function getPathname(url) {
1543
1548
  }
1544
1549
  }
1545
1550
 
1546
- // src/mcp/tools/screenshot.ts
1551
+ // src/mcp/tools/storage.ts
1547
1552
  var import_zod7 = require("zod");
1548
1553
 
1554
+ // src/cdp/cdpStorage.ts
1555
+ function createCdpStorageAdapter(client) {
1556
+ return {
1557
+ async manageStorage(request) {
1558
+ try {
1559
+ return await manageCdpStorage(client, request);
1560
+ } catch (error) {
1561
+ return createCdpStorageError(
1562
+ request,
1563
+ error instanceof Error ? error.message : String(error)
1564
+ );
1565
+ }
1566
+ }
1567
+ };
1568
+ }
1569
+ async function manageCdpStorage(client, request) {
1570
+ if (request.scope === "cookie") {
1571
+ return manageCdpCookies(client, request);
1572
+ }
1573
+ if (request.scope === "indexedDB") {
1574
+ return manageCdpIndexedDb(client, request);
1575
+ }
1576
+ return manageCdpDomStorage(client, request);
1577
+ }
1578
+ async function manageCdpCookies(client, request) {
1579
+ if (request.action === "list" || request.action === "get") {
1580
+ const result2 = await client.Storage.getCookies();
1581
+ const cookies2 = result2.cookies.filter(
1582
+ (cookie) => isCookieInOrigin(cookie, request.origin)
1583
+ );
1584
+ return createCdpStorageSuccess(request, {
1585
+ origin: request.origin,
1586
+ cookies: request.action === "get" && request.cookie?.name ? cookies2.filter((cookie) => cookie.name === request.cookie?.name) : cookies2
1587
+ });
1588
+ }
1589
+ if (request.action === "set") {
1590
+ if (!request.cookie?.name) {
1591
+ throw new Error("Cookie name is required for set operation");
1592
+ }
1593
+ await client.Storage.setCookies({
1594
+ cookies: [
1595
+ {
1596
+ name: request.cookie.name,
1597
+ value: request.cookie.value ?? request.value ?? "",
1598
+ url: request.cookie.url ?? request.origin,
1599
+ domain: request.cookie.domain,
1600
+ path: request.cookie.path,
1601
+ httpOnly: request.cookie.httpOnly,
1602
+ secure: request.cookie.secure,
1603
+ sameSite: normalizeCookieSameSite(request.cookie.sameSite),
1604
+ expires: request.cookie.expires
1605
+ }
1606
+ ]
1607
+ });
1608
+ return createCdpStorageSuccess(request, { ok: true });
1609
+ }
1610
+ const result = await client.Storage.getCookies();
1611
+ const cookies = result.cookies.filter(
1612
+ (cookie) => isCookieInOrigin(cookie, request.origin)
1613
+ );
1614
+ const candidates = request.action === "delete" && request.cookie?.name ? cookies.filter((cookie) => cookie.name === request.cookie?.name) : cookies;
1615
+ const deletable = candidates.filter((cookie) => !cookie.httpOnly);
1616
+ const skippedHttpOnlyCount = candidates.length - deletable.length;
1617
+ for (const cookie of deletable) {
1618
+ await client.Network.deleteCookies({
1619
+ name: cookie.name,
1620
+ domain: cookie.domain,
1621
+ path: cookie.path
1622
+ });
1623
+ }
1624
+ return createCdpStorageSuccess(request, {
1625
+ deletedCount: deletable.length,
1626
+ skippedHttpOnlyCount
1627
+ });
1628
+ }
1629
+ async function manageCdpDomStorage(client, request) {
1630
+ const storageId = {
1631
+ securityOrigin: request.origin,
1632
+ isLocalStorage: request.scope === "localStorage"
1633
+ };
1634
+ if (request.action === "list") {
1635
+ const result2 = await client.DOMStorage.getDOMStorageItems({ storageId });
1636
+ return createCdpStorageSuccess(request, {
1637
+ origin: request.origin,
1638
+ scope: request.scope,
1639
+ entries: result2.entries.map(([key, value]) => ({ key, value }))
1640
+ });
1641
+ }
1642
+ if (request.action === "get") {
1643
+ assertStorageKey(request);
1644
+ const result2 = await client.DOMStorage.getDOMStorageItems({ storageId });
1645
+ const entry = result2.entries.find(([key]) => key === request.key);
1646
+ return createCdpStorageSuccess(request, {
1647
+ key: request.key,
1648
+ value: entry?.[1] ?? null
1649
+ });
1650
+ }
1651
+ if (request.action === "set") {
1652
+ assertStorageKey(request);
1653
+ await client.DOMStorage.setDOMStorageItem({
1654
+ storageId,
1655
+ key: request.key,
1656
+ value: request.value ?? ""
1657
+ });
1658
+ return createCdpStorageSuccess(request, { ok: true });
1659
+ }
1660
+ if (request.action === "delete") {
1661
+ assertStorageKey(request);
1662
+ await client.DOMStorage.removeDOMStorageItem({
1663
+ storageId,
1664
+ key: request.key
1665
+ });
1666
+ return createCdpStorageSuccess(request, { ok: true });
1667
+ }
1668
+ const result = await client.DOMStorage.getDOMStorageItems({ storageId });
1669
+ for (const [key] of result.entries) {
1670
+ await client.DOMStorage.removeDOMStorageItem({ storageId, key });
1671
+ }
1672
+ return createCdpStorageSuccess(request, { deletedCount: result.entries.length });
1673
+ }
1674
+ async function manageCdpIndexedDb(client, request) {
1675
+ if (request.action === "list") {
1676
+ const result = await client.IndexedDB.requestDatabaseNames({
1677
+ securityOrigin: request.origin
1678
+ });
1679
+ return createCdpStorageSuccess(request, {
1680
+ origin: request.origin,
1681
+ databases: result.databaseNames
1682
+ });
1683
+ }
1684
+ assertIndexedDbTarget(request);
1685
+ if (request.action === "get") {
1686
+ const result = await client.IndexedDB.requestData({
1687
+ securityOrigin: request.origin,
1688
+ databaseName: request.databaseName,
1689
+ objectStoreName: request.objectStoreName,
1690
+ indexName: request.indexName ?? "",
1691
+ skipCount: 0,
1692
+ pageSize: 100
1693
+ });
1694
+ return createCdpStorageSuccess(request, {
1695
+ entries: result.objectStoreDataEntries,
1696
+ hasMore: result.hasMore
1697
+ });
1698
+ }
1699
+ if (request.action === "delete") {
1700
+ assertStorageKey(request);
1701
+ await client.IndexedDB.deleteObjectStoreEntries({
1702
+ securityOrigin: request.origin,
1703
+ databaseName: request.databaseName,
1704
+ objectStoreName: request.objectStoreName,
1705
+ keyRange: createExactCdpKeyRange(request.key)
1706
+ });
1707
+ return createCdpStorageSuccess(request, { ok: true });
1708
+ }
1709
+ if (request.action === "clear") {
1710
+ if (request.objectStoreName) {
1711
+ await client.IndexedDB.clearObjectStore({
1712
+ securityOrigin: request.origin,
1713
+ databaseName: request.databaseName,
1714
+ objectStoreName: request.objectStoreName
1715
+ });
1716
+ return createCdpStorageSuccess(request, { ok: true });
1717
+ }
1718
+ await client.IndexedDB.deleteDatabase({
1719
+ securityOrigin: request.origin,
1720
+ databaseName: request.databaseName
1721
+ });
1722
+ return createCdpStorageSuccess(request, { ok: true });
1723
+ }
1724
+ return createCdpStorageError(
1725
+ request,
1726
+ "IndexedDB set operation requires runtime bridge"
1727
+ );
1728
+ }
1729
+ function isCookieInOrigin(cookie, origin) {
1730
+ const hostname = new URL(origin).hostname;
1731
+ const domain = cookie.domain?.replace(/^\./, "");
1732
+ return Boolean(domain && (hostname === domain || hostname.endsWith(`.${domain}`)));
1733
+ }
1734
+ function normalizeCookieSameSite(sameSite) {
1735
+ if (!sameSite) {
1736
+ return void 0;
1737
+ }
1738
+ if (sameSite === "strict") {
1739
+ return "Strict";
1740
+ }
1741
+ if (sameSite === "lax") {
1742
+ return "Lax";
1743
+ }
1744
+ return "None";
1745
+ }
1746
+ function createExactCdpKeyRange(key) {
1747
+ const parsedKey = parseJsonValue(key);
1748
+ return {
1749
+ lower: parsedKey,
1750
+ upper: parsedKey,
1751
+ lowerOpen: false,
1752
+ upperOpen: false
1753
+ };
1754
+ }
1755
+ function parseJsonValue(value) {
1756
+ try {
1757
+ return JSON.parse(value);
1758
+ } catch {
1759
+ return value;
1760
+ }
1761
+ }
1762
+ function assertStorageKey(request) {
1763
+ if (!request.key) {
1764
+ throw new Error("Storage key is required for this operation");
1765
+ }
1766
+ }
1767
+ function assertIndexedDbTarget(request) {
1768
+ if (!request.databaseName || !request.objectStoreName) {
1769
+ throw new Error("IndexedDB databaseName and objectStoreName are required");
1770
+ }
1771
+ }
1772
+ function createCdpStorageSuccess(request, data) {
1773
+ return {
1774
+ ok: true,
1775
+ source: "cdp",
1776
+ action: request.action,
1777
+ scope: request.scope,
1778
+ data
1779
+ };
1780
+ }
1781
+ function createCdpStorageError(request, error) {
1782
+ return {
1783
+ ok: false,
1784
+ source: "cdp",
1785
+ action: request.action,
1786
+ scope: request.scope,
1787
+ error
1788
+ };
1789
+ }
1790
+
1791
+ // src/mcp/tools/storage.ts
1792
+ function registerStorageTools(server, ctx) {
1793
+ registerStorageTool(server, MCP_TOOL_NAMES.listStorage, {
1794
+ description: "List same-origin storage and CDP cookies when available.",
1795
+ inputSchema: {
1796
+ pageId: import_zod7.z.string().optional()
1797
+ },
1798
+ action: "list",
1799
+ handler: (input) => handleListStorage(ctx, input.pageId)
1800
+ });
1801
+ registerStorageTool(server, MCP_TOOL_NAMES.getStorageItem, {
1802
+ description: "Read one storage entry.",
1803
+ inputSchema: createStorageInputSchema(),
1804
+ action: "get",
1805
+ handler: (input) => handleStorageAction(ctx, { ...input, action: "get" })
1806
+ });
1807
+ registerStorageTool(server, MCP_TOOL_NAMES.setStorageItem, {
1808
+ description: "Write one storage entry.",
1809
+ inputSchema: createStorageInputSchema(),
1810
+ action: "set",
1811
+ handler: (input) => handleStorageAction(ctx, { ...input, action: "set" })
1812
+ });
1813
+ registerStorageTool(server, MCP_TOOL_NAMES.deleteStorageItem, {
1814
+ description: "Delete one storage entry.",
1815
+ inputSchema: createStorageInputSchema(),
1816
+ action: "delete",
1817
+ handler: (input) => handleStorageAction(ctx, { ...input, action: "delete" })
1818
+ });
1819
+ registerStorageTool(server, MCP_TOOL_NAMES.clearStorage, {
1820
+ description: "Clear one storage scope.",
1821
+ inputSchema: createStorageInputSchema(),
1822
+ action: "clear",
1823
+ handler: (input) => handleStorageAction(ctx, { ...input, action: "clear" })
1824
+ });
1825
+ }
1826
+ function registerStorageTool(server, name, options) {
1827
+ server.registerTool(
1828
+ name,
1829
+ {
1830
+ description: options.description,
1831
+ inputSchema: options.inputSchema
1832
+ },
1833
+ (async (input) => options.handler(
1834
+ input
1835
+ ))
1836
+ );
1837
+ }
1838
+ function createStorageInputSchema() {
1839
+ return {
1840
+ pageId: import_zod7.z.string().optional(),
1841
+ scope: import_zod7.z.enum(["localStorage", "sessionStorage", "indexedDB", "cookie"]).optional(),
1842
+ key: import_zod7.z.string().optional(),
1843
+ value: import_zod7.z.string().optional(),
1844
+ databaseName: import_zod7.z.string().optional(),
1845
+ objectStoreName: import_zod7.z.string().optional(),
1846
+ indexName: import_zod7.z.string().optional(),
1847
+ cookie: import_zod7.z.object({
1848
+ name: import_zod7.z.string(),
1849
+ value: import_zod7.z.string().optional(),
1850
+ domain: import_zod7.z.string().optional(),
1851
+ path: import_zod7.z.string().optional(),
1852
+ url: import_zod7.z.string().optional(),
1853
+ httpOnly: import_zod7.z.boolean().optional(),
1854
+ secure: import_zod7.z.boolean().optional(),
1855
+ sameSite: import_zod7.z.enum(["strict", "lax", "none"]).optional(),
1856
+ expires: import_zod7.z.number().optional()
1857
+ }).optional()
1858
+ };
1859
+ }
1860
+ async function handleListStorage(ctx, pageId) {
1861
+ let baseRequest;
1862
+ try {
1863
+ baseRequest = createStorageRequest(ctx, {
1864
+ pageId,
1865
+ action: "list",
1866
+ scope: "localStorage"
1867
+ });
1868
+ } catch (error) {
1869
+ return createToolError(error instanceof Error ? error.message : String(error));
1870
+ }
1871
+ const [localStorage, sessionStorage, indexedDB] = await Promise.all([
1872
+ requestRuntimeStorage(ctx, { ...baseRequest, scope: "localStorage" }),
1873
+ requestRuntimeStorage(ctx, { ...baseRequest, scope: "sessionStorage" }),
1874
+ requestRuntimeStorage(ctx, { ...baseRequest, scope: "indexedDB" })
1875
+ ]);
1876
+ const cookie = await listCookiesIfCdpAvailable(ctx, baseRequest, pageId);
1877
+ return createToolResponse({
1878
+ ok: true,
1879
+ origin: baseRequest.origin,
1880
+ localStorage: extractStorageData(localStorage),
1881
+ sessionStorage: extractStorageData(sessionStorage),
1882
+ indexedDB: extractStorageData(indexedDB),
1883
+ cookie
1884
+ });
1885
+ }
1886
+ async function handleStorageAction(ctx, input) {
1887
+ let request;
1888
+ try {
1889
+ request = createStorageRequest(ctx, input);
1890
+ } catch (error) {
1891
+ return createToolError(error instanceof Error ? error.message : String(error));
1892
+ }
1893
+ const cdp = await connectCdpForPage(ctx, input.pageId);
1894
+ if (cdp && shouldUseCdpStorage(request)) {
1895
+ try {
1896
+ const result2 = await createCdpStorageAdapter(cdp.client).manageStorage(
1897
+ request
1898
+ );
1899
+ return createToolResponse(result2);
1900
+ } finally {
1901
+ await closeCdpClient(cdp.client);
1902
+ }
1903
+ }
1904
+ const result = await requestRuntimeStorage(ctx, request);
1905
+ return createToolResponse(result);
1906
+ }
1907
+ async function requestRuntimeStorage(ctx, request) {
1908
+ return requestRuntimeData(ctx, (event) => {
1909
+ void ctx.rpcServer?.manageStorage({
1910
+ ...request,
1911
+ event
1912
+ });
1913
+ });
1914
+ }
1915
+ async function listCookiesIfCdpAvailable(ctx, request, pageId) {
1916
+ if (!hasCdpConfig2(ctx)) {
1917
+ return extractStorageData(
1918
+ await requestRuntimeStorage(ctx, { ...request, scope: "cookie" })
1919
+ );
1920
+ }
1921
+ const cdp = await connectCdpForPage(ctx, pageId);
1922
+ if (!cdp) {
1923
+ return extractStorageData(
1924
+ await requestRuntimeStorage(ctx, { ...request, scope: "cookie" })
1925
+ );
1926
+ }
1927
+ try {
1928
+ const result = await createCdpStorageAdapter(cdp.client).manageStorage({
1929
+ ...request,
1930
+ scope: "cookie"
1931
+ });
1932
+ return extractStorageData(result);
1933
+ } finally {
1934
+ await closeCdpClient(cdp.client);
1935
+ }
1936
+ }
1937
+ function extractStorageData(result) {
1938
+ if (!isStorageResultRecord(result)) {
1939
+ return result;
1940
+ }
1941
+ return result.data ?? result;
1942
+ }
1943
+ function isStorageResultRecord(value) {
1944
+ return typeof value === "object" && value !== null && "ok" in value;
1945
+ }
1946
+ function shouldUseCdpStorage(request) {
1947
+ return request.scope === "cookie";
1948
+ }
1949
+ function createStorageRequest(ctx, input) {
1950
+ const page = resolvePageTarget(ctx, input.pageId);
1951
+ const origin = new URL(page.url).origin;
1952
+ return {
1953
+ event: "",
1954
+ pageId: page.pageId,
1955
+ origin,
1956
+ action: input.action,
1957
+ scope: normalizeScope(input.scope),
1958
+ key: input.key,
1959
+ value: input.value,
1960
+ databaseName: input.databaseName,
1961
+ objectStoreName: input.objectStoreName,
1962
+ indexName: input.indexName,
1963
+ cookie: input.cookie
1964
+ };
1965
+ }
1966
+ function normalizeScope(scope) {
1967
+ return scope ?? "localStorage";
1968
+ }
1969
+ function hasCdpConfig2(ctx) {
1970
+ return Boolean(ctx.options.cdp.browserUrl || ctx.options.cdp.wsEndpoint);
1971
+ }
1972
+
1973
+ // src/mcp/tools/screenshot.ts
1974
+ var import_zod8 = require("zod");
1975
+
1549
1976
  // src/cdp/cdpScreenshot.ts
1550
1977
  async function cdpCaptureScreenshot(options) {
1551
1978
  if (options.target === "element") {
@@ -1704,14 +2131,14 @@ function createProjectRelativePath(ctx, filePath) {
1704
2131
  var DEFAULT_SCREENSHOT_TARGET = "viewport";
1705
2132
  var DEFAULT_SCREENSHOT_FORMAT = "png";
1706
2133
  var screenshotInputSchema = {
1707
- pageId: import_zod7.z.string().optional(),
1708
- target: import_zod7.z.enum(["viewport", "fullPage", "element"]).optional(),
1709
- selector: import_zod7.z.string().optional(),
1710
- format: import_zod7.z.enum(["png", "jpeg", "webp"]).optional(),
1711
- prefer: import_zod7.z.enum(["auto", "cdp", "runtime"]).optional(),
1712
- quality: import_zod7.z.number().optional(),
1713
- scale: import_zod7.z.number().optional(),
1714
- snapdom: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.unknown()).optional()
2134
+ pageId: import_zod8.z.string().optional(),
2135
+ target: import_zod8.z.enum(["viewport", "fullPage", "element"]).optional(),
2136
+ selector: import_zod8.z.string().optional(),
2137
+ format: import_zod8.z.enum(["png", "jpeg", "webp"]).optional(),
2138
+ prefer: import_zod8.z.enum(["auto", "cdp", "runtime"]).optional(),
2139
+ quality: import_zod8.z.number().optional(),
2140
+ scale: import_zod8.z.number().optional(),
2141
+ snapdom: import_zod8.z.record(import_zod8.z.string(), import_zod8.z.unknown()).optional()
1715
2142
  };
1716
2143
  function registerScreenshotTools(server, ctx) {
1717
2144
  server.registerTool(
@@ -1831,7 +2258,7 @@ function isScreenshotImagePayload(result) {
1831
2258
 
1832
2259
  // src/mcp/tools/vue.ts
1833
2260
  var import_nanoid3 = require("nanoid");
1834
- var import_zod8 = require("zod");
2261
+ var import_zod9 = require("zod");
1835
2262
  function registerVueTools(server, ctx) {
1836
2263
  server.registerTool(
1837
2264
  MCP_TOOL_NAMES.getComponentTree,
@@ -1844,7 +2271,7 @@ function registerVueTools(server, ctx) {
1844
2271
  MCP_TOOL_NAMES.getComponentState,
1845
2272
  {
1846
2273
  description: "Get Vue component state.",
1847
- inputSchema: { componentName: import_zod8.z.string() }
2274
+ inputSchema: { componentName: import_zod9.z.string() }
1848
2275
  },
1849
2276
  async ({ componentName }) => requestVueData(ctx, (event) => {
1850
2277
  void ctx.rpcServer?.getInspectorState({ event, componentName });
@@ -1855,10 +2282,10 @@ function registerVueTools(server, ctx) {
1855
2282
  {
1856
2283
  description: "Edit Vue component state.",
1857
2284
  inputSchema: {
1858
- componentName: import_zod8.z.string(),
1859
- path: import_zod8.z.array(import_zod8.z.string()),
1860
- value: import_zod8.z.string(),
1861
- valueType: import_zod8.z.enum(["string", "number", "boolean", "object", "array"])
2285
+ componentName: import_zod9.z.string(),
2286
+ path: import_zod9.z.array(import_zod9.z.string()),
2287
+ value: import_zod9.z.string(),
2288
+ valueType: import_zod9.z.enum(["string", "number", "boolean", "object", "array"])
1862
2289
  }
1863
2290
  },
1864
2291
  ({ componentName, path: path8, value, valueType }) => {
@@ -1878,7 +2305,7 @@ function registerVueTools(server, ctx) {
1878
2305
  MCP_TOOL_NAMES.highlightComponent,
1879
2306
  {
1880
2307
  description: "Highlight a Vue component.",
1881
- inputSchema: { componentName: import_zod8.z.string() }
2308
+ inputSchema: { componentName: import_zod9.z.string() }
1882
2309
  },
1883
2310
  ({ componentName }) => {
1884
2311
  if (!ctx.rpcServer) {
@@ -1906,7 +2333,7 @@ function registerVueTools(server, ctx) {
1906
2333
  MCP_TOOL_NAMES.getPiniaState,
1907
2334
  {
1908
2335
  description: "Get Pinia store state.",
1909
- inputSchema: { storeName: import_zod8.z.string() }
2336
+ inputSchema: { storeName: import_zod9.z.string() }
1910
2337
  },
1911
2338
  async ({ storeName }) => requestVueData(ctx, (event) => {
1912
2339
  void ctx.rpcServer?.getPiniaState({ event, storeName });
@@ -1953,6 +2380,7 @@ function createMcpServer(ctx, vite) {
1953
2380
  registerConsoleTools(server, ctx);
1954
2381
  registerEvaluateTools(server, ctx);
1955
2382
  registerNetworkTools(server, ctx);
2383
+ registerStorageTools(server, ctx);
1956
2384
  registerPerformanceTools(server, ctx);
1957
2385
  registerVueTools(server, ctx);
1958
2386
  return server;
@@ -2041,6 +2469,10 @@ function createServerVueRuntimeRpc(ctx) {
2041
2469
  onScreenshotTaken: (event, data) => {
2042
2470
  void ctx.hooks.callHook(event, data);
2043
2471
  },
2472
+ manageStorage: () => void 0,
2473
+ onStorageUpdated: (event, data) => {
2474
+ void ctx.hooks.callHook(event, data);
2475
+ },
2044
2476
  recordPerformance: () => void 0,
2045
2477
  onPerformanceRecorded: (event, data) => {
2046
2478
  void ctx.hooks.callHook(event, data);