@@ -20,12 +20,17 @@ import (
2020
2121// session holds the active WebKit client and collectors.
2222type session struct {
23- mu sync.Mutex
24- client * webkit.Client
25- networkMonitor * tools.NetworkMonitor
26- consoleCollector * tools.ConsoleCollector
27- timelineCollector * tools.TimelineCollector
28- interceptionCollector * tools.InterceptionCollector
23+ mu sync.Mutex
24+ client * webkit.Client
25+ networkMonitor * tools.NetworkMonitor
26+ consoleCollector * tools.ConsoleCollector
27+ timelineCollector * tools.TimelineCollector
28+ interceptionCollector * tools.InterceptionCollector
29+ cpuProfilerCollector * tools.CPUProfilerCollector
30+ scriptProfilerCollector * tools.ScriptProfilerCollector
31+ memoryTrackingCollector * tools.MemoryTrackingCollector
32+ heapTrackingCollector * tools.HeapTrackingCollector
33+ animationTrackingCollector * tools.AnimationTrackingCollector
2934}
3035
3136var sess session
@@ -58,7 +63,7 @@ func lookupInterceptStage(requestID string) string {
5863func main () {
5964 server := mcp .NewServer (& mcp.Implementation {
6065 Name : "iwdp-mcp" ,
61- Version : "0.3.5 " ,
66+ Version : "0.4.0 " ,
6267 }, nil )
6368
6469 registerTools (server )
@@ -236,8 +241,7 @@ type InterceptWithResponseInput struct {
236241}
237242
238243type SetEmulatedConditionsInput struct {
239- BytesPerSecondLimit int `json:"bytes_per_second_limit" jsonschema:"bytes per second limit"`
240- LatencyMs float64 `json:"latency_ms" jsonschema:"latency in milliseconds"`
244+ BytesPerSecondLimit int `json:"bytes_per_second_limit" jsonschema:"bytes per second limit"`
241245}
242246
243247type SetResourceCachingDisabledInput struct {
@@ -330,7 +334,8 @@ type DOMBreakpointInput struct {
330334}
331335
332336type EventBreakpointInput struct {
333- EventName string `json:"event_name"`
337+ BreakpointType string `json:"breakpoint_type" jsonschema:"required,breakpoint type: animation-frame, interval, listener, or timeout"`
338+ EventName string `json:"event_name"`
334339}
335340
336341type URLBreakpointInput struct {
@@ -358,8 +363,8 @@ type AnimationIDInput struct {
358363}
359364
360365type CanvasIDInput struct {
361- CanvasID string `json:"canvas_id"`
362- SingleFrame bool `json:"single_frame ,omitempty"`
366+ CanvasID string `json:"canvas_id"`
367+ FrameCount int `json:"frame_count ,omitempty" jsonschema:"number of frames to record (0 for unlimited) "`
363368}
364369
365370type ShaderSourceInput struct {
@@ -1126,7 +1131,7 @@ func registerTools(server *mcp.Server) {
11261131 if err != nil {
11271132 return nil , OKOutput {}, err
11281133 }
1129- return nil , ok (), tools .SetEmulatedConditions (ctx , c , input .BytesPerSecondLimit , input . LatencyMs )
1134+ return nil , ok (), tools .SetEmulatedConditions (ctx , c , input .BytesPerSecondLimit )
11301135 })
11311136
11321137 mcp .AddTool (server , & mcp.Tool {
@@ -1568,7 +1573,7 @@ func registerTools(server *mcp.Server) {
15681573 if err != nil {
15691574 return nil , OKOutput {}, err
15701575 }
1571- return nil , ok (), tools .SetEventBreakpoint (ctx , c , input .EventName )
1576+ return nil , ok (), tools .SetEventBreakpoint (ctx , c , input .BreakpointType , input . EventName )
15721577 })
15731578
15741579 mcp .AddTool (server , & mcp.Tool {
@@ -1578,7 +1583,7 @@ func registerTools(server *mcp.Server) {
15781583 if err != nil {
15791584 return nil , OKOutput {}, err
15801585 }
1581- return nil , ok (), tools .RemoveEventBreakpoint (ctx , c , input .EventName )
1586+ return nil , ok (), tools .RemoveEventBreakpoint (ctx , c , input .BreakpointType , input . EventName )
15821587 })
15831588
15841589 mcp .AddTool (server , & mcp.Tool {
@@ -1652,23 +1657,43 @@ func registerTools(server *mcp.Server) {
16521657
16531658 // --- Memory & Heap ---
16541659 mcp .AddTool (server , & mcp.Tool {
1655- Name : "memory_start_tracking" , Description : "Start tracking memory usage" ,
1660+ Name : "memory_start_tracking" , Description : "Start tracking memory usage — collects memory category events " ,
16561661 }, func (ctx context.Context , req * mcp.CallToolRequest , _ EmptyInput ) (* mcp.CallToolResult , any , error ) {
16571662 c , err := getClient (ctx )
16581663 if err != nil {
16591664 return nil , OKOutput {}, err
16601665 }
1661- return nil , ok (), tools .MemoryStartTracking (ctx , c )
1666+ sess .mu .Lock ()
1667+ if sess .memoryTrackingCollector == nil {
1668+ sess .memoryTrackingCollector = tools .NewMemoryTrackingCollector ()
1669+ }
1670+ collector := sess .memoryTrackingCollector
1671+ sess .mu .Unlock ()
1672+ return nil , ok (), collector .Start (ctx , c )
16621673 })
16631674
16641675 mcp .AddTool (server , & mcp.Tool {
1665- Name : "memory_stop_tracking" , Description : "Stop tracking memory usage" ,
1676+ Name : "memory_stop_tracking" , Description : "Stop tracking memory usage and get collected memory events " ,
16661677 }, func (ctx context.Context , req * mcp.CallToolRequest , _ EmptyInput ) (* mcp.CallToolResult , any , error ) {
16671678 c , err := getClient (ctx )
16681679 if err != nil {
1669- return nil , OKOutput {}, err
1680+ return nil , RawOutput {}, err
1681+ }
1682+ sess .mu .Lock ()
1683+ collector := sess .memoryTrackingCollector
1684+ sess .mu .Unlock ()
1685+ if collector == nil {
1686+ return nil , RawOutput {}, fmt .Errorf ("memory tracking not started — use memory_start_tracking first" )
16701687 }
1671- return nil , ok (), tools .MemoryStopTracking (ctx , c )
1688+ result , err := collector .Stop (ctx , c )
1689+ if err != nil {
1690+ return nil , RawOutput {}, err
1691+ }
1692+ if fileResult , ferr := largeResultToFile (result , "memory-tracking" ); fileResult != nil {
1693+ return fileResult , nil , ferr
1694+ }
1695+ data , _ := json .Marshal (result )
1696+ return nil , RawOutput {Result : data }, nil
16721697 })
16731698
16741699 mcp .AddTool (server , & mcp.Tool {
@@ -1690,23 +1715,43 @@ func registerTools(server *mcp.Server) {
16901715 })
16911716
16921717 mcp .AddTool (server , & mcp.Tool {
1693- Name : "heap_start_tracking" , Description : "Start tracking heap allocations" ,
1718+ Name : "heap_start_tracking" , Description : "Start tracking heap allocations — collects heap snapshot events " ,
16941719 }, func (ctx context.Context , req * mcp.CallToolRequest , _ EmptyInput ) (* mcp.CallToolResult , any , error ) {
16951720 c , err := getClient (ctx )
16961721 if err != nil {
16971722 return nil , OKOutput {}, err
16981723 }
1699- return nil , ok (), tools .HeapStartTracking (ctx , c )
1724+ sess .mu .Lock ()
1725+ if sess .heapTrackingCollector == nil {
1726+ sess .heapTrackingCollector = tools .NewHeapTrackingCollector ()
1727+ }
1728+ collector := sess .heapTrackingCollector
1729+ sess .mu .Unlock ()
1730+ return nil , ok (), collector .Start (ctx , c )
17001731 })
17011732
17021733 mcp .AddTool (server , & mcp.Tool {
1703- Name : "heap_stop_tracking" , Description : "Stop tracking heap allocations" ,
1734+ Name : "heap_stop_tracking" , Description : "Stop tracking heap allocations and get collected heap events " ,
17041735 }, func (ctx context.Context , req * mcp.CallToolRequest , _ EmptyInput ) (* mcp.CallToolResult , any , error ) {
17051736 c , err := getClient (ctx )
17061737 if err != nil {
1707- return nil , OKOutput {}, err
1738+ return nil , RawOutput {}, err
1739+ }
1740+ sess .mu .Lock ()
1741+ collector := sess .heapTrackingCollector
1742+ sess .mu .Unlock ()
1743+ if collector == nil {
1744+ return nil , RawOutput {}, fmt .Errorf ("heap tracking not started — use heap_start_tracking first" )
1745+ }
1746+ result , err := collector .Stop (ctx , c )
1747+ if err != nil {
1748+ return nil , RawOutput {}, err
1749+ }
1750+ if fileResult , ferr := largeResultToFile (result , "heap-tracking" ); fileResult != nil {
1751+ return fileResult , nil , ferr
17081752 }
1709- return nil , ok (), tools .HeapStopTracking (ctx , c )
1753+ data , _ := json .Marshal (result )
1754+ return nil , RawOutput {Result : data }, nil
17101755 })
17111756
17121757 mcp .AddTool (server , & mcp.Tool {
@@ -1721,51 +1766,83 @@ func registerTools(server *mcp.Server) {
17211766
17221767 // --- Profiler ---
17231768 mcp .AddTool (server , & mcp.Tool {
1724- Name : "cpu_start_profiling" , Description : "Start CPU profiling" ,
1769+ Name : "cpu_start_profiling" , Description : "Start CPU profiling — collects CPU usage samples via events " ,
17251770 }, func (ctx context.Context , req * mcp.CallToolRequest , _ EmptyInput ) (* mcp.CallToolResult , any , error ) {
17261771 c , err := getClient (ctx )
17271772 if err != nil {
17281773 return nil , OKOutput {}, err
17291774 }
1730- return nil , ok (), tools .CPUStartProfiling (ctx , c )
1775+ sess .mu .Lock ()
1776+ if sess .cpuProfilerCollector == nil {
1777+ sess .cpuProfilerCollector = tools .NewCPUProfilerCollector ()
1778+ }
1779+ collector := sess .cpuProfilerCollector
1780+ sess .mu .Unlock ()
1781+ return nil , ok (), collector .Start (ctx , c )
17311782 })
17321783
17331784 mcp .AddTool (server , & mcp.Tool {
1734- Name : "cpu_stop_profiling" , Description : "Stop CPU profiling and get results " ,
1785+ Name : "cpu_stop_profiling" , Description : "Stop CPU profiling and get collected CPU usage events " ,
17351786 }, func (ctx context.Context , req * mcp.CallToolRequest , _ EmptyInput ) (* mcp.CallToolResult , any , error ) {
17361787 c , err := getClient (ctx )
17371788 if err != nil {
17381789 return nil , RawOutput {}, err
17391790 }
1740- result , err := tools .CPUStopProfiling (ctx , c )
1791+ sess .mu .Lock ()
1792+ collector := sess .cpuProfilerCollector
1793+ sess .mu .Unlock ()
1794+ if collector == nil {
1795+ return nil , RawOutput {}, fmt .Errorf ("CPU profiling not started — use cpu_start_profiling first" )
1796+ }
1797+ result , err := collector .Stop (ctx , c )
17411798 if err != nil {
17421799 return nil , RawOutput {}, err
17431800 }
1744- return nil , RawOutput {Result : result }, nil
1801+ if fileResult , ferr := largeResultToFile (result , "cpu-profile" ); fileResult != nil {
1802+ return fileResult , nil , ferr
1803+ }
1804+ data , _ := json .Marshal (result )
1805+ return nil , RawOutput {Result : data }, nil
17451806 })
17461807
17471808 mcp .AddTool (server , & mcp.Tool {
1748- Name : "script_start_profiling" , Description : "Start script execution profiling" ,
1809+ Name : "script_start_profiling" , Description : "Start script execution profiling with stack sampling " ,
17491810 }, func (ctx context.Context , req * mcp.CallToolRequest , _ EmptyInput ) (* mcp.CallToolResult , any , error ) {
17501811 c , err := getClient (ctx )
17511812 if err != nil {
17521813 return nil , OKOutput {}, err
17531814 }
1754- return nil , ok (), tools .ScriptStartProfiling (ctx , c )
1815+ sess .mu .Lock ()
1816+ if sess .scriptProfilerCollector == nil {
1817+ sess .scriptProfilerCollector = tools .NewScriptProfilerCollector ()
1818+ }
1819+ collector := sess .scriptProfilerCollector
1820+ sess .mu .Unlock ()
1821+ return nil , ok (), collector .Start (ctx , c )
17551822 })
17561823
17571824 mcp .AddTool (server , & mcp.Tool {
1758- Name : "script_stop_profiling" , Description : "Stop script profiling and get results " ,
1825+ Name : "script_stop_profiling" , Description : "Stop script profiling and get execution events + stack samples " ,
17591826 }, func (ctx context.Context , req * mcp.CallToolRequest , _ EmptyInput ) (* mcp.CallToolResult , any , error ) {
17601827 c , err := getClient (ctx )
17611828 if err != nil {
17621829 return nil , RawOutput {}, err
17631830 }
1764- result , err := tools .ScriptStopProfiling (ctx , c )
1831+ sess .mu .Lock ()
1832+ collector := sess .scriptProfilerCollector
1833+ sess .mu .Unlock ()
1834+ if collector == nil {
1835+ return nil , RawOutput {}, fmt .Errorf ("script profiling not started — use script_start_profiling first" )
1836+ }
1837+ result , err := collector .Stop (ctx , c )
17651838 if err != nil {
17661839 return nil , RawOutput {}, err
17671840 }
1768- return nil , RawOutput {Result : result }, nil
1841+ if fileResult , ferr := largeResultToFile (result , "script-profile" ); fileResult != nil {
1842+ return fileResult , nil , ferr
1843+ }
1844+ data , _ := json .Marshal (result )
1845+ return nil , RawOutput {Result : data }, nil
17691846 })
17701847
17711848 // --- Animation ---
@@ -1790,23 +1867,43 @@ func registerTools(server *mcp.Server) {
17901867 })
17911868
17921869 mcp .AddTool (server , & mcp.Tool {
1793- Name : "animation_start_tracking" , Description : "Start animation profiling" ,
1870+ Name : "animation_start_tracking" , Description : "Start animation profiling — collects animation events " ,
17941871 }, func (ctx context.Context , req * mcp.CallToolRequest , _ EmptyInput ) (* mcp.CallToolResult , any , error ) {
17951872 c , err := getClient (ctx )
17961873 if err != nil {
17971874 return nil , OKOutput {}, err
17981875 }
1799- return nil , ok (), tools .AnimationStartTracking (ctx , c )
1876+ sess .mu .Lock ()
1877+ if sess .animationTrackingCollector == nil {
1878+ sess .animationTrackingCollector = tools .NewAnimationTrackingCollector ()
1879+ }
1880+ collector := sess .animationTrackingCollector
1881+ sess .mu .Unlock ()
1882+ return nil , ok (), collector .Start (ctx , c )
18001883 })
18011884
18021885 mcp .AddTool (server , & mcp.Tool {
1803- Name : "animation_stop_tracking" , Description : "Stop animation profiling" ,
1886+ Name : "animation_stop_tracking" , Description : "Stop animation profiling and get collected animation events " ,
18041887 }, func (ctx context.Context , req * mcp.CallToolRequest , _ EmptyInput ) (* mcp.CallToolResult , any , error ) {
18051888 c , err := getClient (ctx )
18061889 if err != nil {
1807- return nil , OKOutput {}, err
1890+ return nil , RawOutput {}, err
1891+ }
1892+ sess .mu .Lock ()
1893+ collector := sess .animationTrackingCollector
1894+ sess .mu .Unlock ()
1895+ if collector == nil {
1896+ return nil , RawOutput {}, fmt .Errorf ("animation tracking not started — use animation_start_tracking first" )
18081897 }
1809- return nil , ok (), tools .AnimationStopTracking (ctx , c )
1898+ result , err := collector .Stop (ctx , c )
1899+ if err != nil {
1900+ return nil , RawOutput {}, err
1901+ }
1902+ if fileResult , ferr := largeResultToFile (result , "animation-tracking" ); fileResult != nil {
1903+ return fileResult , nil , ferr
1904+ }
1905+ data , _ := json .Marshal (result )
1906+ return nil , RawOutput {Result : data }, nil
18101907 })
18111908
18121909 mcp .AddTool (server , & mcp.Tool {
@@ -1879,7 +1976,7 @@ func registerTools(server *mcp.Server) {
18791976 if err != nil {
18801977 return nil , OKOutput {}, err
18811978 }
1882- return nil , ok (), tools .StartCanvasRecording (ctx , c , input .CanvasID , input .SingleFrame )
1979+ return nil , ok (), tools .StartCanvasRecording (ctx , c , input .CanvasID , input .FrameCount )
18831980 })
18841981
18851982 mcp .AddTool (server , & mcp.Tool {
@@ -1935,20 +2032,6 @@ func registerTools(server *mcp.Server) {
19352032 return nil , RawOutput {Result : result }, nil
19362033 })
19372034
1938- mcp .AddTool (server , & mcp.Tool {
1939- Name : "get_layer_content" , Description : "Get layer snapshot as image" ,
1940- }, func (ctx context.Context , req * mcp.CallToolRequest , input LayerIDInput ) (* mcp.CallToolResult , any , error ) {
1941- c , err := getClient (ctx )
1942- if err != nil {
1943- return nil , RawOutput {}, err
1944- }
1945- content , err := tools .GetLayerContent (ctx , c , input .LayerID )
1946- if err != nil {
1947- return nil , RawOutput {}, err
1948- }
1949- return nil , RawOutput {Result : content }, nil
1950- })
1951-
19522035 // --- Workers ---
19532036 mcp .AddTool (server , & mcp.Tool {
19542037 Name : "worker_enable" , Description : "Enable web worker tracking" ,
0 commit comments