@perfbase/mcp 1.0.0 → 1.0.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 +19 -5
- package/dist/decoder/decompress.d.ts +15 -3
- package/dist/decoder/decompress.d.ts.map +1 -1
- package/dist/decoder/decompress.js +31 -22
- package/dist/decoder/decompress.js.map +1 -1
- package/dist/decoder/trie-walker.d.ts +5 -0
- package/dist/decoder/trie-walker.d.ts.map +1 -1
- package/dist/decoder/trie-walker.js +42 -36
- package/dist/decoder/trie-walker.js.map +1 -1
- package/dist/decoder/types.d.ts +3 -3
- package/dist/decoder/types.d.ts.map +1 -1
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -1
- package/dist/tools/run-profiled.d.ts +41 -0
- package/dist/tools/run-profiled.d.ts.map +1 -0
- package/dist/tools/run-profiled.js +166 -0
- package/dist/tools/run-profiled.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,21 @@ Model Context Protocol (MCP) server for analyzing PerfBase PHP profiler data.
|
|
|
8
8
|
claude mcp add perfbase -- npx -y @perfbase/mcp
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
That's it! Restart Claude Code and you can analyze
|
|
11
|
+
That's it! Restart Claude Code and you can profile and analyze PHP scripts directly.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Profile a PHP Script
|
|
16
|
+
|
|
17
|
+
Just ask Claude to profile any PHP script:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Profile /path/to/my-script.php and show me the slowest functions
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Claude will use the `run_profiled_script` tool to execute the script with profiling enabled, then analyze the results.
|
|
24
|
+
|
|
25
|
+
### Analyze an Existing Profile
|
|
12
26
|
|
|
13
27
|
```
|
|
14
28
|
Analyze the profile at /path/to/profile.bin
|
|
@@ -18,6 +32,7 @@ Analyze the profile at /path/to/profile.bin
|
|
|
18
32
|
|
|
19
33
|
| Tool | Description |
|
|
20
34
|
|------|-------------|
|
|
35
|
+
| `run_profiled_script` | Run a PHP script with profiling and save the result |
|
|
21
36
|
| `get_slowest_functions` | Functions sorted by total wall time |
|
|
22
37
|
| `get_most_called_functions` | Functions sorted by call count |
|
|
23
38
|
| `get_cpu_intensive_functions` | Functions sorted by CPU time |
|
|
@@ -28,12 +43,11 @@ Analyze the profile at /path/to/profile.bin
|
|
|
28
43
|
|
|
29
44
|
## Profile Data Format
|
|
30
45
|
|
|
31
|
-
|
|
46
|
+
PerfBase profiles are:
|
|
32
47
|
1. MessagePack encoded
|
|
33
48
|
2. Brotli compressed
|
|
34
|
-
3. Base64 encoded
|
|
35
49
|
|
|
36
|
-
This is the format produced by `perfbase_get_data()`.
|
|
50
|
+
This is the raw binary format produced by `perfbase_get_data()`.
|
|
37
51
|
|
|
38
52
|
## Development
|
|
39
53
|
|
|
@@ -61,7 +75,7 @@ To test locally before publishing:
|
|
|
61
75
|
claude mcp add perfbase -- node /path/to/extension/mcp/dist/index.js
|
|
62
76
|
```
|
|
63
77
|
|
|
64
|
-
###
|
|
78
|
+
### Manual Profile Generation
|
|
65
79
|
|
|
66
80
|
```php
|
|
67
81
|
<?php
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Decompression and decoding utilities for PerfBase profile data.
|
|
3
|
-
* Handles
|
|
3
|
+
* Handles Brotli decompression and MessagePack unpacking.
|
|
4
|
+
*
|
|
5
|
+
* PerfBase profile format: Brotli-compressed MessagePack (raw binary)
|
|
4
6
|
*/
|
|
5
7
|
import { ProfilingData } from './types.js';
|
|
6
8
|
/**
|
|
7
9
|
* Load and decode a PerfBase profile from a file path
|
|
8
|
-
* @param filePath Path to the profile file (
|
|
10
|
+
* @param filePath Path to the profile file (Brotli-compressed MessagePack binary)
|
|
9
11
|
*/
|
|
10
12
|
export declare function loadProfile(filePath: string): Promise<ProfilingData>;
|
|
11
13
|
/**
|
|
12
|
-
* Decode a PerfBase profile from
|
|
14
|
+
* Decode a PerfBase profile from binary buffer
|
|
15
|
+
* @param compressed Brotli-compressed MessagePack data
|
|
16
|
+
*/
|
|
17
|
+
export declare function decodeProfileBinary(compressed: Buffer): Promise<ProfilingData>;
|
|
18
|
+
/**
|
|
19
|
+
* Decode a PerfBase profile from base64 string (for testing or API use)
|
|
13
20
|
* @param base64Data Base64-encoded, Brotli-compressed, MessagePack data
|
|
14
21
|
*/
|
|
15
22
|
export declare function decodeProfile(base64Data: string): Promise<ProfilingData>;
|
|
23
|
+
/**
|
|
24
|
+
* Encode a ProfilingData object to binary (Brotli-compressed MessagePack)
|
|
25
|
+
* @param data ProfilingData to encode
|
|
26
|
+
*/
|
|
27
|
+
export declare function encodeProfileBinary(data: ProfilingData): Promise<Buffer>;
|
|
16
28
|
/**
|
|
17
29
|
* Encode a ProfilingData object to base64 (for testing)
|
|
18
30
|
* @param data ProfilingData to encode
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decompress.d.ts","sourceRoot":"","sources":["../../src/decoder/decompress.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"decompress.d.ts","sourceRoot":"","sources":["../../src/decoder/decompress.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAmB3C;;;GAGG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAK1E;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAQpF;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAG9E;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAM9E;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAGxE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,aAAa,CAa1E"}
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Decompression and decoding utilities for PerfBase profile data.
|
|
3
|
-
* Handles
|
|
3
|
+
* Handles Brotli decompression and MessagePack unpacking.
|
|
4
|
+
*
|
|
5
|
+
* PerfBase profile format: Brotli-compressed MessagePack (raw binary)
|
|
4
6
|
*/
|
|
5
7
|
import { promisify } from 'node:util';
|
|
6
8
|
import { brotliDecompress, brotliCompress } from 'node:zlib';
|
|
7
9
|
import { decode as msgpackDecode, encode as msgpackEncode } from '@msgpack/msgpack';
|
|
8
10
|
const brotliDecompressAsync = promisify(brotliDecompress);
|
|
9
11
|
const brotliCompressAsync = promisify(brotliCompress);
|
|
10
|
-
/**
|
|
11
|
-
* Decode base64 string to Buffer
|
|
12
|
-
*/
|
|
13
|
-
function base64Decode(base64) {
|
|
14
|
-
return Buffer.from(base64, 'base64');
|
|
15
|
-
}
|
|
16
12
|
/**
|
|
17
13
|
* Decompress Brotli-compressed data
|
|
18
14
|
*/
|
|
@@ -27,37 +23,50 @@ function decodeMessagePack(data) {
|
|
|
27
23
|
}
|
|
28
24
|
/**
|
|
29
25
|
* Load and decode a PerfBase profile from a file path
|
|
30
|
-
* @param filePath Path to the profile file (
|
|
26
|
+
* @param filePath Path to the profile file (Brotli-compressed MessagePack binary)
|
|
31
27
|
*/
|
|
32
28
|
export async function loadProfile(filePath) {
|
|
33
29
|
const fs = await import('node:fs/promises');
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
// Read as binary buffer, not text
|
|
31
|
+
const compressed = await fs.readFile(filePath);
|
|
32
|
+
return decodeProfileBinary(compressed);
|
|
36
33
|
}
|
|
37
34
|
/**
|
|
38
|
-
* Decode a PerfBase profile from
|
|
39
|
-
* @param
|
|
35
|
+
* Decode a PerfBase profile from binary buffer
|
|
36
|
+
* @param compressed Brotli-compressed MessagePack data
|
|
40
37
|
*/
|
|
41
|
-
export async function
|
|
42
|
-
// Step 1:
|
|
43
|
-
const compressed = base64Decode(base64Data);
|
|
44
|
-
// Step 2: Brotli decompress
|
|
38
|
+
export async function decodeProfileBinary(compressed) {
|
|
39
|
+
// Step 1: Brotli decompress
|
|
45
40
|
const decompressed = await decompressBrotli(compressed);
|
|
46
|
-
// Step
|
|
41
|
+
// Step 2: MessagePack decode
|
|
47
42
|
const data = decodeMessagePack(decompressed);
|
|
48
43
|
return data;
|
|
49
44
|
}
|
|
50
45
|
/**
|
|
51
|
-
*
|
|
46
|
+
* Decode a PerfBase profile from base64 string (for testing or API use)
|
|
47
|
+
* @param base64Data Base64-encoded, Brotli-compressed, MessagePack data
|
|
48
|
+
*/
|
|
49
|
+
export async function decodeProfile(base64Data) {
|
|
50
|
+
const compressed = Buffer.from(base64Data, 'base64');
|
|
51
|
+
return decodeProfileBinary(compressed);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Encode a ProfilingData object to binary (Brotli-compressed MessagePack)
|
|
52
55
|
* @param data ProfilingData to encode
|
|
53
56
|
*/
|
|
54
|
-
export async function
|
|
57
|
+
export async function encodeProfileBinary(data) {
|
|
55
58
|
// Step 1: MessagePack encode
|
|
56
59
|
const msgpacked = Buffer.from(msgpackEncode(data));
|
|
57
60
|
// Step 2: Brotli compress
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
return brotliCompressAsync(msgpacked);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Encode a ProfilingData object to base64 (for testing)
|
|
65
|
+
* @param data ProfilingData to encode
|
|
66
|
+
*/
|
|
67
|
+
export async function encodeProfile(data) {
|
|
68
|
+
const binary = await encodeProfileBinary(data);
|
|
69
|
+
return binary.toString('base64');
|
|
61
70
|
}
|
|
62
71
|
/**
|
|
63
72
|
* Validate that the data has the expected structure
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decompress.js","sourceRoot":"","sources":["../../src/decoder/decompress.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"decompress.js","sourceRoot":"","sources":["../../src/decoder/decompress.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGpF,MAAM,qBAAqB,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAAC;AAC1D,MAAM,mBAAmB,GAAG,SAAS,CAAC,cAAc,CAAC,CAAC;AAEtD;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAAC,UAAkB;IAChD,OAAO,qBAAqB,CAAC,UAAU,CAAC,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,aAAa,CAAC,IAAI,CAAkB,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB;IAChD,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC5C,kCAAkC;IAClC,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/C,OAAO,mBAAmB,CAAC,UAAU,CAAC,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,UAAkB;IAC1D,4BAA4B;IAC5B,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAExD,6BAA6B;IAC7B,MAAM,IAAI,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAE7C,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAkB;IACpD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACrD,OAAO,mBAAmB,CAAC,UAAU,CAAC,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAmB;IAC3D,6BAA6B;IAC7B,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IAEnD,0BAA0B;IAC1B,OAAO,mBAAmB,CAAC,SAAS,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAmB;IACrD,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAa;IACjD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,GAAG,GAAG,IAA+B,CAAC;IAE5C,kBAAkB;IAClB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC,CAAE,WAAW;IACrD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC,CAAE,QAAQ;IAClD,IAAI,OAAO,GAAG,CAAC,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC,CAAE,OAAO;IAEvE,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Trie traversal utilities for reconstructing function call paths
|
|
3
3
|
* from the compressed trie structure.
|
|
4
|
+
*
|
|
5
|
+
* Trie Structure:
|
|
6
|
+
* - Each node has `keys` (array of glossary indices for this segment)
|
|
7
|
+
* - `children` are child nodes for the next segment
|
|
8
|
+
* - `value` is the FunctionData if this is a termination point
|
|
4
9
|
*/
|
|
5
10
|
import { ProfilingData, FunctionInfo } from './types.js';
|
|
6
11
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trie-walker.d.ts","sourceRoot":"","sources":["../../src/decoder/trie-walker.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"trie-walker.d.ts","sourceRoot":"","sources":["../../src/decoder/trie-walker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,aAAa,EAGb,YAAY,EAEb,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,aAAa,EACnB,QAAQ,CAAC,EAAE,MAAM,GAChB,YAAY,EAAE,CAmBhB;AA4ED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,EAAE,CAEjE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,EAAE,CAE1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAqB1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,YAAY,EAAE,EACzB,OAAO,EAAE,MAAM,GACd,YAAY,EAAE,CAOhB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAoBjF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,YAAY,EACtD,SAAS,EAAE,YAAY,EAAE,EACzB,KAAK,EAAE,CAAC,EACR,KAAK,CAAC,EAAE,MAAM,GACb,YAAY,EAAE,CAWhB"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Trie traversal utilities for reconstructing function call paths
|
|
3
3
|
* from the compressed trie structure.
|
|
4
|
+
*
|
|
5
|
+
* Trie Structure:
|
|
6
|
+
* - Each node has `keys` (array of glossary indices for this segment)
|
|
7
|
+
* - `children` are child nodes for the next segment
|
|
8
|
+
* - `value` is the FunctionData if this is a termination point
|
|
4
9
|
*/
|
|
5
10
|
/**
|
|
6
11
|
* Walk the trie and collect all function info with reconstructed paths
|
|
@@ -25,56 +30,57 @@ export function walkTrie(data, spanName) {
|
|
|
25
30
|
/**
|
|
26
31
|
* Recursively walk a trie node and collect function info
|
|
27
32
|
*/
|
|
28
|
-
function walkNode(node,
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
// If there's a child node at this index, recurse
|
|
37
|
-
if (children && children[i]) {
|
|
38
|
-
walkNode(children[i], currentPath, glossary, files, results);
|
|
39
|
-
}
|
|
33
|
+
function walkNode(node, pathSegments, glossary, files, results) {
|
|
34
|
+
// Convert this node's keys to names
|
|
35
|
+
const segmentNames = node.k.map((idx) => glossary[idx]?.n ?? `<unknown:${idx}>`);
|
|
36
|
+
const currentPath = [...pathSegments, segmentNames];
|
|
37
|
+
// If this node has function data, create a FunctionInfo
|
|
38
|
+
if (node.v) {
|
|
39
|
+
const info = buildFunctionInfo(node.v, currentPath, glossary, files);
|
|
40
|
+
results.push(info);
|
|
40
41
|
}
|
|
41
|
-
//
|
|
42
|
-
if (
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
// Recurse into children
|
|
43
|
+
if (node.h) {
|
|
44
|
+
for (const child of node.h) {
|
|
45
|
+
if (child) {
|
|
46
|
+
walkNode(child, currentPath, glossary, files, results);
|
|
47
|
+
}
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
/**
|
|
51
|
-
* Build a FunctionInfo from FunctionData and path
|
|
52
|
+
* Build a FunctionInfo from FunctionData and path segments
|
|
52
53
|
*/
|
|
53
|
-
function buildFunctionInfo(data,
|
|
54
|
-
//
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
54
|
+
function buildFunctionInfo(data, pathSegments, glossary, files) {
|
|
55
|
+
// Flatten path segments: [[App, Controller], [index]] => "App::Controller > index"
|
|
56
|
+
const callPath = pathSegments
|
|
57
|
+
.map((segment) => segment.join('::'))
|
|
58
|
+
.join(' > ');
|
|
59
|
+
// The function name is the last part of the last segment
|
|
60
|
+
const lastSegment = pathSegments[pathSegments.length - 1];
|
|
61
|
+
const name = lastSegment?.[lastSegment.length - 1] ?? '<unknown>';
|
|
62
|
+
// Try to find file/line from the glossary entry for the function name
|
|
63
|
+
// Look up the name in the glossary to find its entry with file/line
|
|
64
|
+
const entry = glossary.find((e) => e.n === name);
|
|
65
|
+
const file = entry?.f !== undefined ? files[entry.f] : undefined;
|
|
66
|
+
const line = entry?.l;
|
|
61
67
|
return {
|
|
62
68
|
callPath,
|
|
63
|
-
name
|
|
69
|
+
name,
|
|
64
70
|
file,
|
|
65
|
-
line
|
|
71
|
+
line,
|
|
66
72
|
callCount: data.c,
|
|
67
73
|
totalWallTime: data.w,
|
|
68
74
|
avgWallTime: data.c > 0 ? data.w / data.c : 0,
|
|
69
75
|
minWallTime: data.wn,
|
|
70
76
|
maxWallTime: data.wx,
|
|
71
|
-
totalCpuTime: data.u,
|
|
72
|
-
avgCpuTime: data.c > 0 ? data.u / data.c : 0,
|
|
73
|
-
minCpuTime: data.un,
|
|
74
|
-
maxCpuTime: data.ux,
|
|
75
|
-
memoryAllocated: data.mt,
|
|
76
|
-
memoryPeak: data.mp,
|
|
77
|
-
memoryNet: data.m,
|
|
77
|
+
totalCpuTime: data.u ?? 0,
|
|
78
|
+
avgCpuTime: data.c > 0 ? (data.u ?? 0) / data.c : 0,
|
|
79
|
+
minCpuTime: data.un ?? 0,
|
|
80
|
+
maxCpuTime: data.ux ?? 0,
|
|
81
|
+
memoryAllocated: data.mt ?? 0,
|
|
82
|
+
memoryPeak: data.mp ?? 0,
|
|
83
|
+
memoryNet: data.m ?? 0,
|
|
78
84
|
};
|
|
79
85
|
}
|
|
80
86
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trie-walker.js","sourceRoot":"","sources":["../../src/decoder/trie-walker.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"trie-walker.js","sourceRoot":"","sources":["../../src/decoder/trie-walker.ts"],"names":[],"mappings":"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"}
|
package/dist/decoder/types.d.ts
CHANGED
|
@@ -45,9 +45,9 @@ export interface FunctionData {
|
|
|
45
45
|
/** Memory freed */
|
|
46
46
|
mf: number;
|
|
47
47
|
/** Memory net change */
|
|
48
|
-
m
|
|
49
|
-
/**
|
|
50
|
-
g
|
|
48
|
+
m?: number;
|
|
49
|
+
/** Feature flags (not glossary index) */
|
|
50
|
+
g?: number;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
53
|
* Trie node representing a call stack path
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/decoder/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,oBAAoB;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,6CAA6C;IAC7C,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,6BAA6B;IAC7B,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,iBAAiB;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,qCAAqC;IACrC,CAAC,EAAE,MAAM,CAAC;IACV,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,oCAAoC;IACpC,CAAC,EAAE,MAAM,CAAC;IACV,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,6BAA6B;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,wBAAwB;IACxB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/decoder/types.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import { memoryHogsSchema, getMemoryHogs, formatMemoryHogsOutput, } from './tool
|
|
|
16
16
|
import { databaseQueriesSchema, getDatabaseQueries, formatDatabaseQueriesOutput, } from './tools/database-queries.js';
|
|
17
17
|
import { nPlusOneSchema, detectNPlusOne, formatNPlusOneOutput, } from './tools/n-plus-one.js';
|
|
18
18
|
import { summarySchema, getProfileSummary, formatSummaryOutput, } from './tools/summary.js';
|
|
19
|
+
import { runProfiledSchema, runProfiledScript, formatRunProfiledOutput, } from './tools/run-profiled.js';
|
|
19
20
|
// Resources
|
|
20
21
|
import { getProfileMetadata, formatMetadataAsJson, } from './resources/profile-metadata.js';
|
|
21
22
|
// Tool definitions for MCP
|
|
@@ -172,6 +173,43 @@ const TOOLS = [
|
|
|
172
173
|
required: ['filePath'],
|
|
173
174
|
},
|
|
174
175
|
},
|
|
176
|
+
{
|
|
177
|
+
name: 'run_profiled_script',
|
|
178
|
+
description: 'Profile a PHP script to find performance bottlenecks. Runs the script with profiling enabled, captures timing/memory data, and saves the profile for analysis. Use this when the user wants to profile, benchmark, or find slow code in a PHP file.',
|
|
179
|
+
inputSchema: {
|
|
180
|
+
type: 'object',
|
|
181
|
+
properties: {
|
|
182
|
+
scriptPath: {
|
|
183
|
+
type: 'string',
|
|
184
|
+
description: 'Absolute path to the PHP script to profile',
|
|
185
|
+
},
|
|
186
|
+
args: {
|
|
187
|
+
type: 'array',
|
|
188
|
+
items: { type: 'string' },
|
|
189
|
+
description: 'Optional arguments to pass to the script',
|
|
190
|
+
},
|
|
191
|
+
spanName: {
|
|
192
|
+
type: 'string',
|
|
193
|
+
description: 'Span name for the profile (default: "cli")',
|
|
194
|
+
default: 'cli',
|
|
195
|
+
},
|
|
196
|
+
outputDir: {
|
|
197
|
+
type: 'string',
|
|
198
|
+
description: 'Directory to save profile (default: same as script)',
|
|
199
|
+
},
|
|
200
|
+
phpBinary: {
|
|
201
|
+
type: 'string',
|
|
202
|
+
description: 'Path to PHP binary (default: "php")',
|
|
203
|
+
default: 'php',
|
|
204
|
+
},
|
|
205
|
+
extensionPath: {
|
|
206
|
+
type: 'string',
|
|
207
|
+
description: 'Path to perfbase extension .so/.dylib (if not in php.ini)',
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
required: ['scriptPath'],
|
|
211
|
+
},
|
|
212
|
+
},
|
|
175
213
|
];
|
|
176
214
|
// Create server instance
|
|
177
215
|
const server = new Server({
|
|
@@ -182,6 +220,17 @@ const server = new Server({
|
|
|
182
220
|
tools: {},
|
|
183
221
|
resources: {},
|
|
184
222
|
},
|
|
223
|
+
instructions: `Use this server when the user wants to:
|
|
224
|
+
- Profile a PHP script to find performance issues
|
|
225
|
+
- Analyze PHP performance, speed, or timing
|
|
226
|
+
- Find slow functions, bottlenecks, or hot paths in PHP code
|
|
227
|
+
- Detect N+1 queries or database performance issues
|
|
228
|
+
- Check memory usage or CPU time in PHP
|
|
229
|
+
- Debug why PHP code is slow
|
|
230
|
+
|
|
231
|
+
Keywords that should trigger use: profile, performance, slow, bottleneck, optimize, profiler, timing, benchmark, N+1, memory leak, CPU usage
|
|
232
|
+
|
|
233
|
+
When profiling PHP scripts, use run_profiled_script first, then analyze with other tools like get_slowest_functions or get_profile_summary.`,
|
|
185
234
|
});
|
|
186
235
|
// Handle list tools request
|
|
187
236
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
@@ -245,6 +294,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
245
294
|
content: [{ type: 'text', text: formatSummaryOutput(result) }],
|
|
246
295
|
};
|
|
247
296
|
}
|
|
297
|
+
case 'run_profiled_script': {
|
|
298
|
+
const input = runProfiledSchema.parse(args);
|
|
299
|
+
const result = await runProfiledScript(input);
|
|
300
|
+
return {
|
|
301
|
+
content: [{ type: 'text', text: formatRunProfiledOutput(result) }],
|
|
302
|
+
};
|
|
303
|
+
}
|
|
248
304
|
default:
|
|
249
305
|
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
250
306
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,SAAS,EACT,QAAQ,GACT,MAAM,oCAAoC,CAAC;AAE5C,QAAQ;AACR,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,4BAA4B,GAC7B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,cAAc,EACd,cAAc,EACd,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool: run_profiled_script
|
|
3
|
+
* Runs a PHP script with PerfBase profiling and saves the output
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export declare const runProfiledSchema: z.ZodObject<{
|
|
7
|
+
scriptPath: z.ZodString;
|
|
8
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
9
|
+
spanName: z.ZodDefault<z.ZodString>;
|
|
10
|
+
outputDir: z.ZodOptional<z.ZodString>;
|
|
11
|
+
phpBinary: z.ZodDefault<z.ZodString>;
|
|
12
|
+
extensionPath: z.ZodOptional<z.ZodString>;
|
|
13
|
+
flags: z.ZodDefault<z.ZodNumber>;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
scriptPath: string;
|
|
16
|
+
spanName: string;
|
|
17
|
+
phpBinary: string;
|
|
18
|
+
flags: number;
|
|
19
|
+
args?: string[] | undefined;
|
|
20
|
+
outputDir?: string | undefined;
|
|
21
|
+
extensionPath?: string | undefined;
|
|
22
|
+
}, {
|
|
23
|
+
scriptPath: string;
|
|
24
|
+
args?: string[] | undefined;
|
|
25
|
+
spanName?: string | undefined;
|
|
26
|
+
outputDir?: string | undefined;
|
|
27
|
+
phpBinary?: string | undefined;
|
|
28
|
+
extensionPath?: string | undefined;
|
|
29
|
+
flags?: number | undefined;
|
|
30
|
+
}>;
|
|
31
|
+
export type RunProfiledInput = z.infer<typeof runProfiledSchema>;
|
|
32
|
+
export interface RunProfiledResult {
|
|
33
|
+
profilePath: string;
|
|
34
|
+
scriptOutput: string;
|
|
35
|
+
scriptErrors: string;
|
|
36
|
+
exitCode: number;
|
|
37
|
+
executionTime: number;
|
|
38
|
+
}
|
|
39
|
+
export declare function runProfiledScript(input: RunProfiledInput): Promise<RunProfiledResult>;
|
|
40
|
+
export declare function formatRunProfiledOutput(result: RunProfiledResult): string;
|
|
41
|
+
//# sourceMappingURL=run-profiled.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-profiled.d.ts","sourceRoot":"","sources":["../../src/tools/run-profiled.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;EAQ5B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAoDD,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,iBAAiB,CAAC,CA+F5B;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAmCzE"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool: run_profiled_script
|
|
3
|
+
* Runs a PHP script with PerfBase profiling and saves the output
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { spawn } from 'node:child_process';
|
|
7
|
+
import { writeFile, mkdtemp, stat } from 'node:fs/promises';
|
|
8
|
+
import { tmpdir } from 'node:os';
|
|
9
|
+
import { join, basename, dirname } from 'node:path';
|
|
10
|
+
export const runProfiledSchema = z.object({
|
|
11
|
+
scriptPath: z.string().describe('Absolute path to the PHP script to profile'),
|
|
12
|
+
args: z.array(z.string()).optional().describe('Arguments to pass to the script'),
|
|
13
|
+
spanName: z.string().default('cli').describe('Span name for the profile'),
|
|
14
|
+
outputDir: z.string().optional().describe('Directory to save profile (default: same as script)'),
|
|
15
|
+
phpBinary: z.string().default('php').describe('Path to PHP binary'),
|
|
16
|
+
extensionPath: z.string().optional().describe('Path to perfbase extension .so/.dylib'),
|
|
17
|
+
flags: z.number().default(0).describe('PerfBase flags (0 = all features)'),
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Create a wrapper script that profiles the target script
|
|
21
|
+
*/
|
|
22
|
+
function createWrapperScript(targetScript, spanName, flags, outputPath) {
|
|
23
|
+
// Escape strings for PHP
|
|
24
|
+
const escapePhp = (s) => s.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
25
|
+
return `<?php
|
|
26
|
+
// PerfBase profiling wrapper - auto-generated
|
|
27
|
+
\$_perfbase_target = '${escapePhp(targetScript)}';
|
|
28
|
+
\$_perfbase_output = '${escapePhp(outputPath)}';
|
|
29
|
+
\$_perfbase_span = '${escapePhp(spanName)}';
|
|
30
|
+
\$_perfbase_flags = ${flags};
|
|
31
|
+
|
|
32
|
+
if (!extension_loaded('perfbase')) {
|
|
33
|
+
fwrite(STDERR, "Error: perfbase extension not loaded\\n");
|
|
34
|
+
exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Start profiling
|
|
38
|
+
perfbase_enable(\$_perfbase_span, \$_perfbase_flags);
|
|
39
|
+
|
|
40
|
+
// Set working directory to script's directory
|
|
41
|
+
chdir(dirname(\$_perfbase_target));
|
|
42
|
+
|
|
43
|
+
// Include the target script
|
|
44
|
+
try {
|
|
45
|
+
require \$_perfbase_target;
|
|
46
|
+
} catch (Throwable \$e) {
|
|
47
|
+
fwrite(STDERR, "Script error: " . \$e->getMessage() . "\\n");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Stop profiling and save
|
|
51
|
+
perfbase_disable(\$_perfbase_span);
|
|
52
|
+
\$data = perfbase_get_data();
|
|
53
|
+
|
|
54
|
+
if (\$data) {
|
|
55
|
+
file_put_contents(\$_perfbase_output, \$data);
|
|
56
|
+
fwrite(STDERR, "\\n[perfbase] Profile saved to: \$_perfbase_output\\n");
|
|
57
|
+
} else {
|
|
58
|
+
fwrite(STDERR, "\\n[perfbase] Warning: No profile data generated\\n");
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
61
|
+
}
|
|
62
|
+
export async function runProfiledScript(input) {
|
|
63
|
+
const startTime = Date.now();
|
|
64
|
+
// Determine output path
|
|
65
|
+
const scriptDir = dirname(input.scriptPath);
|
|
66
|
+
const scriptName = basename(input.scriptPath, '.php');
|
|
67
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
68
|
+
const outputDir = input.outputDir ?? scriptDir;
|
|
69
|
+
const profilePath = join(outputDir, `${scriptName}-${timestamp}.profile.bin`);
|
|
70
|
+
// Create temp directory for wrapper script
|
|
71
|
+
const tempDir = await mkdtemp(join(tmpdir(), 'perfbase-'));
|
|
72
|
+
const wrapperPath = join(tempDir, 'wrapper.php');
|
|
73
|
+
// Write wrapper script
|
|
74
|
+
const wrapperScript = createWrapperScript(input.scriptPath, input.spanName, input.flags, profilePath);
|
|
75
|
+
await writeFile(wrapperPath, wrapperScript);
|
|
76
|
+
// Build PHP command
|
|
77
|
+
const phpArgs = [];
|
|
78
|
+
// Add extension if specified
|
|
79
|
+
if (input.extensionPath) {
|
|
80
|
+
phpArgs.push('-d', `extension=${input.extensionPath}`);
|
|
81
|
+
}
|
|
82
|
+
// Add wrapper script
|
|
83
|
+
phpArgs.push(wrapperPath);
|
|
84
|
+
// Add script arguments
|
|
85
|
+
if (input.args) {
|
|
86
|
+
phpArgs.push('--', ...input.args);
|
|
87
|
+
}
|
|
88
|
+
// Run PHP
|
|
89
|
+
const result = await new Promise((resolve) => {
|
|
90
|
+
const proc = spawn(input.phpBinary, phpArgs, {
|
|
91
|
+
cwd: dirname(input.scriptPath),
|
|
92
|
+
env: { ...process.env },
|
|
93
|
+
});
|
|
94
|
+
let stdout = '';
|
|
95
|
+
let stderr = '';
|
|
96
|
+
proc.stdout.on('data', (data) => {
|
|
97
|
+
stdout += data.toString();
|
|
98
|
+
});
|
|
99
|
+
proc.stderr.on('data', (data) => {
|
|
100
|
+
stderr += data.toString();
|
|
101
|
+
});
|
|
102
|
+
proc.on('close', (code) => {
|
|
103
|
+
resolve({
|
|
104
|
+
stdout,
|
|
105
|
+
stderr,
|
|
106
|
+
exitCode: code ?? 1,
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
proc.on('error', (err) => {
|
|
110
|
+
resolve({
|
|
111
|
+
stdout,
|
|
112
|
+
stderr: stderr + `\nProcess error: ${err.message}`,
|
|
113
|
+
exitCode: 1,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
const executionTime = Date.now() - startTime;
|
|
118
|
+
// Check if profile was created
|
|
119
|
+
let actualProfilePath = profilePath;
|
|
120
|
+
try {
|
|
121
|
+
await stat(profilePath);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
actualProfilePath = '';
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
profilePath: actualProfilePath,
|
|
128
|
+
scriptOutput: result.stdout,
|
|
129
|
+
scriptErrors: result.stderr,
|
|
130
|
+
exitCode: result.exitCode,
|
|
131
|
+
executionTime,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
export function formatRunProfiledOutput(result) {
|
|
135
|
+
const lines = [
|
|
136
|
+
`# PHP Script Execution Results`,
|
|
137
|
+
``,
|
|
138
|
+
`**Exit Code**: ${result.exitCode}`,
|
|
139
|
+
`**Execution Time**: ${result.executionTime}ms`,
|
|
140
|
+
``,
|
|
141
|
+
];
|
|
142
|
+
if (result.profilePath) {
|
|
143
|
+
lines.push(`**Profile Saved**: ${result.profilePath}`);
|
|
144
|
+
lines.push(``);
|
|
145
|
+
lines.push(`You can now analyze this profile with other perfbase tools.`);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
lines.push(`**Warning**: No profile was generated.`);
|
|
149
|
+
}
|
|
150
|
+
if (result.scriptOutput) {
|
|
151
|
+
lines.push(``, `## Script Output`, ``, '```', result.scriptOutput.trim(), '```');
|
|
152
|
+
}
|
|
153
|
+
if (result.scriptErrors) {
|
|
154
|
+
// Filter out the perfbase status messages for cleaner output
|
|
155
|
+
const errors = result.scriptErrors
|
|
156
|
+
.split('\n')
|
|
157
|
+
.filter(line => !line.includes('[perfbase]'))
|
|
158
|
+
.join('\n')
|
|
159
|
+
.trim();
|
|
160
|
+
if (errors) {
|
|
161
|
+
lines.push(``, `## Script Errors`, ``, '```', errors, '```');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return lines.join('\n');
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=run-profiled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-profiled.js","sourceRoot":"","sources":["../../src/tools/run-profiled.ts"],"names":[],"mappings":"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"}
|