agent-recorder 2.0.0 → 2.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/dist/bundle.js +8 -0
- package/dist/bundle.js.map +1 -1
- package/package.json +4 -2
- package/vendor/node_modules/@agent-recorder/cli/commands/hooks.d.ts +12 -0
- package/vendor/node_modules/@agent-recorder/cli/commands/hooks.d.ts.map +1 -0
- package/vendor/node_modules/@agent-recorder/cli/commands/hooks.js +182 -0
- package/vendor/node_modules/@agent-recorder/cli/commands/hooks.js.map +1 -0
- package/vendor/node_modules/@agent-recorder/cli/commands/upstream.d.ts.map +1 -1
- package/vendor/node_modules/@agent-recorder/cli/commands/upstream.js +21 -0
- package/vendor/node_modules/@agent-recorder/cli/commands/upstream.js.map +1 -1
- package/vendor/node_modules/@agent-recorder/cli/index.js +23 -0
- package/vendor/node_modules/@agent-recorder/cli/index.js.map +1 -1
- package/vendor/node_modules/@agent-recorder/cli/package.json +1 -1
- package/vendor/node_modules/@agent-recorder/hooks/handler.d.ts +24 -0
- package/vendor/node_modules/@agent-recorder/hooks/handler.d.ts.map +1 -0
- package/vendor/node_modules/@agent-recorder/hooks/handler.js +132 -0
- package/vendor/node_modules/@agent-recorder/hooks/handler.js.map +1 -0
- package/vendor/node_modules/@agent-recorder/hooks/index.d.ts +8 -0
- package/vendor/node_modules/@agent-recorder/hooks/index.d.ts.map +1 -0
- package/vendor/node_modules/@agent-recorder/hooks/index.js +8 -0
- package/vendor/node_modules/@agent-recorder/hooks/index.js.map +1 -0
- package/vendor/node_modules/@agent-recorder/hooks/package.json +12 -0
- package/vendor/node_modules/@agent-recorder/hooks/types.d.ts +94 -0
- package/vendor/node_modules/@agent-recorder/hooks/types.d.ts.map +1 -0
- package/vendor/node_modules/@agent-recorder/hooks/types.js +8 -0
- package/vendor/node_modules/@agent-recorder/hooks/types.js.map +1 -0
- package/vendor/node_modules/@agent-recorder/service/mcp/proxy.d.ts.map +1 -1
- package/vendor/node_modules/@agent-recorder/service/mcp/proxy.js +68 -0
- package/vendor/node_modules/@agent-recorder/service/mcp/proxy.js.map +1 -1
- package/vendor/node_modules/@agent-recorder/service/routes/hooks.d.ts +15 -0
- package/vendor/node_modules/@agent-recorder/service/routes/hooks.d.ts.map +1 -0
- package/vendor/node_modules/@agent-recorder/service/routes/hooks.js +166 -0
- package/vendor/node_modules/@agent-recorder/service/routes/hooks.js.map +1 -0
- package/vendor/node_modules/@agent-recorder/service/routes/stdio.d.ts +14 -0
- package/vendor/node_modules/@agent-recorder/service/routes/stdio.d.ts.map +1 -0
- package/vendor/node_modules/@agent-recorder/service/routes/stdio.js +85 -0
- package/vendor/node_modules/@agent-recorder/service/routes/stdio.js.map +1 -0
- package/vendor/node_modules/@agent-recorder/service/server.d.ts +1 -0
- package/vendor/node_modules/@agent-recorder/service/server.d.ts.map +1 -1
- package/vendor/node_modules/@agent-recorder/service/server.js +5 -1
- package/vendor/node_modules/@agent-recorder/service/server.js.map +1 -1
- package/vendor/node_modules/@agent-recorder/stdio-proxy/cli.d.ts +22 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/cli.d.ts.map +1 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/cli.js +158 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/cli.js.map +1 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/index.d.ts +9 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/index.d.ts.map +1 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/index.js +8 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/index.js.map +1 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/package.json +12 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/proxy.d.ts +45 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/proxy.d.ts.map +1 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/proxy.js +293 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/proxy.js.map +1 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/types.d.ts +68 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/types.d.ts.map +1 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/types.js +5 -0
- package/vendor/node_modules/@agent-recorder/stdio-proxy/types.js.map +1 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* STDIO Proxy CLI
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* agent-recorder-proxy [options] -- <command> [args...]
|
|
7
|
+
*
|
|
8
|
+
* Examples:
|
|
9
|
+
* # Basic usage
|
|
10
|
+
* agent-recorder-proxy -- npx -y @modelcontextprotocol/server-github
|
|
11
|
+
*
|
|
12
|
+
* # With file output
|
|
13
|
+
* agent-recorder-proxy --output ./logs/github.jsonl -- npx -y @modelcontextprotocol/server-github
|
|
14
|
+
*
|
|
15
|
+
* # With remote endpoint
|
|
16
|
+
* agent-recorder-proxy --endpoint http://localhost:8787/api/stdio -- npx -y @modelcontextprotocol/server-github
|
|
17
|
+
*
|
|
18
|
+
* # Debug mode
|
|
19
|
+
* agent-recorder-proxy --debug -- npx -y @modelcontextprotocol/server-github
|
|
20
|
+
*/
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;GAkBG"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* STDIO Proxy CLI
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* agent-recorder-proxy [options] -- <command> [args...]
|
|
7
|
+
*
|
|
8
|
+
* Examples:
|
|
9
|
+
* # Basic usage
|
|
10
|
+
* agent-recorder-proxy -- npx -y @modelcontextprotocol/server-github
|
|
11
|
+
*
|
|
12
|
+
* # With file output
|
|
13
|
+
* agent-recorder-proxy --output ./logs/github.jsonl -- npx -y @modelcontextprotocol/server-github
|
|
14
|
+
*
|
|
15
|
+
* # With remote endpoint
|
|
16
|
+
* agent-recorder-proxy --endpoint http://localhost:8787/api/stdio -- npx -y @modelcontextprotocol/server-github
|
|
17
|
+
*
|
|
18
|
+
* # Debug mode
|
|
19
|
+
* agent-recorder-proxy --debug -- npx -y @modelcontextprotocol/server-github
|
|
20
|
+
*/
|
|
21
|
+
import { randomUUID } from "node:crypto";
|
|
22
|
+
import { StdioProxy } from "./proxy.js";
|
|
23
|
+
/** Parse command line arguments */
|
|
24
|
+
function parseArgs(argv) {
|
|
25
|
+
const options = {};
|
|
26
|
+
const command = [];
|
|
27
|
+
let foundSeparator = false;
|
|
28
|
+
for (let i = 0; i < argv.length; i++) {
|
|
29
|
+
const arg = argv[i];
|
|
30
|
+
if (foundSeparator) {
|
|
31
|
+
command.push(arg);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (arg === "--") {
|
|
35
|
+
foundSeparator = true;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (arg === "--output" || arg === "-o") {
|
|
39
|
+
options.outputFile = argv[++i];
|
|
40
|
+
}
|
|
41
|
+
else if (arg === "--endpoint" || arg === "-e") {
|
|
42
|
+
options.endpoint = argv[++i];
|
|
43
|
+
}
|
|
44
|
+
else if (arg === "--session" || arg === "-s") {
|
|
45
|
+
options.sessionId = argv[++i];
|
|
46
|
+
}
|
|
47
|
+
else if (arg === "--cwd" || arg === "-c") {
|
|
48
|
+
options.cwd = argv[++i];
|
|
49
|
+
}
|
|
50
|
+
else if (arg === "--debug" || arg === "-d") {
|
|
51
|
+
options.debug = true;
|
|
52
|
+
}
|
|
53
|
+
else if (arg === "--help" || arg === "-h") {
|
|
54
|
+
printHelp();
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
else if (arg === "--version" || arg === "-v") {
|
|
58
|
+
console.log("agent-recorder-proxy 2.0.0");
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
else if (arg.startsWith("-")) {
|
|
62
|
+
console.error(`Unknown option: ${arg}`);
|
|
63
|
+
console.error("Use --help for usage information");
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// Assume rest is command
|
|
68
|
+
command.push(arg);
|
|
69
|
+
for (let j = i + 1; j < argv.length; j++) {
|
|
70
|
+
command.push(argv[j]);
|
|
71
|
+
}
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return { options, command };
|
|
76
|
+
}
|
|
77
|
+
function printHelp() {
|
|
78
|
+
console.log(`
|
|
79
|
+
agent-recorder-proxy - STDIO proxy for MCP server observability
|
|
80
|
+
|
|
81
|
+
USAGE:
|
|
82
|
+
agent-recorder-proxy [OPTIONS] -- <command> [args...]
|
|
83
|
+
agent-recorder-proxy [OPTIONS] <command> [args...]
|
|
84
|
+
|
|
85
|
+
OPTIONS:
|
|
86
|
+
-o, --output <file> Write JSONL logs to file
|
|
87
|
+
-e, --endpoint <url> POST telemetry to HTTP endpoint
|
|
88
|
+
-s, --session <id> Session ID for correlation (auto-generated if not set)
|
|
89
|
+
-c, --cwd <dir> Working directory for child process
|
|
90
|
+
-d, --debug Enable debug logging to stderr
|
|
91
|
+
-h, --help Show this help message
|
|
92
|
+
-v, --version Show version
|
|
93
|
+
|
|
94
|
+
EXAMPLES:
|
|
95
|
+
# Basic usage - wrap a GitHub MCP server
|
|
96
|
+
agent-recorder-proxy -- npx -y @modelcontextprotocol/server-github
|
|
97
|
+
|
|
98
|
+
# Log to file
|
|
99
|
+
agent-recorder-proxy -o ./mcp.jsonl -- npx -y @modelcontextprotocol/server-filesystem /tmp
|
|
100
|
+
|
|
101
|
+
# Send telemetry to Agent Recorder service
|
|
102
|
+
agent-recorder-proxy -e http://localhost:8787/api/stdio -- npx -y @modelcontextprotocol/server-github
|
|
103
|
+
|
|
104
|
+
# Debug mode (logs to stderr)
|
|
105
|
+
agent-recorder-proxy --debug -- python -m mcp_server_custom
|
|
106
|
+
|
|
107
|
+
ENVIRONMENT:
|
|
108
|
+
All environment variables from the parent process are passed to the child.
|
|
109
|
+
This includes API keys (GITHUB_TOKEN, etc.) and PATH.
|
|
110
|
+
|
|
111
|
+
MCP CLIENT CONFIGURATION:
|
|
112
|
+
Before (direct):
|
|
113
|
+
{
|
|
114
|
+
"command": "npx",
|
|
115
|
+
"args": ["-y", "@modelcontextprotocol/server-github"]
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
After (with proxy):
|
|
119
|
+
{
|
|
120
|
+
"command": "npx",
|
|
121
|
+
"args": ["-y", "agent-recorder-proxy", "--", "npx", "-y", "@modelcontextprotocol/server-github"]
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
For more information, visit: https://github.com/EdytaKucharska/agent_recorder
|
|
125
|
+
`);
|
|
126
|
+
}
|
|
127
|
+
async function main() {
|
|
128
|
+
const { options, command } = parseArgs(process.argv.slice(2));
|
|
129
|
+
if (command.length === 0) {
|
|
130
|
+
console.error("Error: No command specified");
|
|
131
|
+
console.error("Usage: agent-recorder-proxy [options] -- <command> [args...]");
|
|
132
|
+
console.error("Use --help for more information");
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
// Extract command and args
|
|
136
|
+
const [cmd, ...args] = command;
|
|
137
|
+
// Build proxy options
|
|
138
|
+
const proxyOptions = {
|
|
139
|
+
command: cmd,
|
|
140
|
+
args,
|
|
141
|
+
cwd: options.cwd,
|
|
142
|
+
outputFile: options.outputFile,
|
|
143
|
+
endpoint: options.endpoint,
|
|
144
|
+
sessionId: options.sessionId ?? randomUUID(),
|
|
145
|
+
debug: options.debug ?? false,
|
|
146
|
+
};
|
|
147
|
+
// Create and start proxy
|
|
148
|
+
const proxy = new StdioProxy(proxyOptions);
|
|
149
|
+
try {
|
|
150
|
+
await proxy.start();
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
console.error(`Failed to start proxy: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
main();
|
|
158
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @agent-recorder/stdio-proxy
|
|
3
|
+
*
|
|
4
|
+
* STDIO proxy for MCP server observability.
|
|
5
|
+
* Wraps any MCP server and records all stdin/stdout traffic.
|
|
6
|
+
*/
|
|
7
|
+
export { StdioProxy } from "./proxy.js";
|
|
8
|
+
export type { ProxyOptions, ProxyState, McpMessage, JsonRpcRequest, JsonRpcResponse, } from "./types.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* STDIO Proxy for MCP Server Observability
|
|
3
|
+
*
|
|
4
|
+
* This proxy wraps an MCP server and records all stdin/stdout traffic
|
|
5
|
+
* without modifying the message content.
|
|
6
|
+
*
|
|
7
|
+
* Key constraints (from MCP spec):
|
|
8
|
+
* - Server MUST NOT write anything to stdout that is not a valid MCP message
|
|
9
|
+
* - Messages are newline-delimited JSON
|
|
10
|
+
* - Messages MUST NOT contain embedded newlines
|
|
11
|
+
*
|
|
12
|
+
* Safety measures:
|
|
13
|
+
* - All logging goes to stderr or file (NEVER stdout)
|
|
14
|
+
* - Unbuffered I/O to prevent message loss
|
|
15
|
+
* - Signal handling for clean shutdown
|
|
16
|
+
*/
|
|
17
|
+
import type { ProxyOptions, ProxyState } from "./types.js";
|
|
18
|
+
export declare class StdioProxy {
|
|
19
|
+
private options;
|
|
20
|
+
private state;
|
|
21
|
+
private child;
|
|
22
|
+
private logStream;
|
|
23
|
+
private readMutex;
|
|
24
|
+
private shutdownRequested;
|
|
25
|
+
constructor(options: ProxyOptions);
|
|
26
|
+
/** Log to stderr (NEVER stdout) */
|
|
27
|
+
private log;
|
|
28
|
+
/** Record a message to file and/or endpoint */
|
|
29
|
+
private recordMessage;
|
|
30
|
+
/** Parse JSON-RPC message for telemetry */
|
|
31
|
+
private parseMessage;
|
|
32
|
+
/** Set up signal handlers for clean shutdown */
|
|
33
|
+
private setupSignalHandlers;
|
|
34
|
+
/** Start the proxy */
|
|
35
|
+
start(): Promise<void>;
|
|
36
|
+
/** Set up stdin pipe with recording */
|
|
37
|
+
private setupStdinPipe;
|
|
38
|
+
/** Set up stdout pipe with recording */
|
|
39
|
+
private setupStdoutPipe;
|
|
40
|
+
/** Stop the proxy and clean up */
|
|
41
|
+
stop(exitCode?: number): void;
|
|
42
|
+
/** Get current proxy state */
|
|
43
|
+
getState(): ProxyState;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EAIX,MAAM,YAAY,CAAC;AA4BpB,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,iBAAiB,CAAS;gBAEtB,OAAO,EAAE,YAAY;IASjC,mCAAmC;IACnC,OAAO,CAAC,GAAG;IAMX,+CAA+C;YACjC,aAAa;IAgC3B,2CAA2C;IAC3C,OAAO,CAAC,YAAY;IA2BpB,gDAAgD;IAChD,OAAO,CAAC,mBAAmB;IAiB3B,sBAAsB;IAChB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4E5B,uCAAuC;IACvC,OAAO,CAAC,cAAc;IAmCtB,wCAAwC;IACxC,OAAO,CAAC,eAAe;IA2CvB,kCAAkC;IAClC,IAAI,CAAC,QAAQ,SAAI,GAAG,IAAI;IAuCxB,8BAA8B;IAC9B,QAAQ,IAAI,UAAU;CAGvB"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* STDIO Proxy for MCP Server Observability
|
|
3
|
+
*
|
|
4
|
+
* This proxy wraps an MCP server and records all stdin/stdout traffic
|
|
5
|
+
* without modifying the message content.
|
|
6
|
+
*
|
|
7
|
+
* Key constraints (from MCP spec):
|
|
8
|
+
* - Server MUST NOT write anything to stdout that is not a valid MCP message
|
|
9
|
+
* - Messages are newline-delimited JSON
|
|
10
|
+
* - Messages MUST NOT contain embedded newlines
|
|
11
|
+
*
|
|
12
|
+
* Safety measures:
|
|
13
|
+
* - All logging goes to stderr or file (NEVER stdout)
|
|
14
|
+
* - Unbuffered I/O to prevent message loss
|
|
15
|
+
* - Signal handling for clean shutdown
|
|
16
|
+
*/
|
|
17
|
+
import { spawn } from "node:child_process";
|
|
18
|
+
import { createWriteStream } from "node:fs";
|
|
19
|
+
import { createInterface } from "node:readline";
|
|
20
|
+
/** Mutex for synchronized stdout reading */
|
|
21
|
+
class ReadMutex {
|
|
22
|
+
locked = false;
|
|
23
|
+
queue = [];
|
|
24
|
+
async acquire() {
|
|
25
|
+
if (!this.locked) {
|
|
26
|
+
this.locked = true;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
this.queue.push(resolve);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
release() {
|
|
34
|
+
const next = this.queue.shift();
|
|
35
|
+
if (next) {
|
|
36
|
+
next();
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.locked = false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export class StdioProxy {
|
|
44
|
+
options;
|
|
45
|
+
state;
|
|
46
|
+
child = null;
|
|
47
|
+
logStream = null;
|
|
48
|
+
readMutex = new ReadMutex();
|
|
49
|
+
shutdownRequested = false;
|
|
50
|
+
constructor(options) {
|
|
51
|
+
this.options = options;
|
|
52
|
+
this.state = {
|
|
53
|
+
running: false,
|
|
54
|
+
requestCount: 0,
|
|
55
|
+
responseCount: 0,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** Log to stderr (NEVER stdout) */
|
|
59
|
+
log(message) {
|
|
60
|
+
if (this.options.debug) {
|
|
61
|
+
process.stderr.write(`[agent-recorder] ${message}\n`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Record a message to file and/or endpoint */
|
|
65
|
+
async recordMessage(message) {
|
|
66
|
+
const line = JSON.stringify(message) + "\n";
|
|
67
|
+
// Write to file if configured
|
|
68
|
+
if (this.logStream) {
|
|
69
|
+
this.logStream.write(line);
|
|
70
|
+
}
|
|
71
|
+
// POST to endpoint if configured
|
|
72
|
+
if (this.options.endpoint) {
|
|
73
|
+
try {
|
|
74
|
+
const controller = new AbortController();
|
|
75
|
+
const timeout = setTimeout(() => controller.abort(), 2000);
|
|
76
|
+
await fetch(this.options.endpoint, {
|
|
77
|
+
method: "POST",
|
|
78
|
+
headers: { "Content-Type": "application/json" },
|
|
79
|
+
body: JSON.stringify({
|
|
80
|
+
...message,
|
|
81
|
+
sessionId: this.options.sessionId,
|
|
82
|
+
}),
|
|
83
|
+
signal: controller.signal,
|
|
84
|
+
});
|
|
85
|
+
clearTimeout(timeout);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Fail silently - don't block the proxy
|
|
89
|
+
this.log(`Failed to POST to endpoint: ${this.options.endpoint}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** Parse JSON-RPC message for telemetry */
|
|
94
|
+
parseMessage(raw, direction) {
|
|
95
|
+
const timestamp = new Date().toISOString();
|
|
96
|
+
const message = { timestamp, direction, raw };
|
|
97
|
+
try {
|
|
98
|
+
const parsed = JSON.parse(raw);
|
|
99
|
+
if ("method" in parsed) {
|
|
100
|
+
// Request
|
|
101
|
+
message.method = parsed.method;
|
|
102
|
+
message.id = parsed.id;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// Response
|
|
106
|
+
message.id = parsed.id;
|
|
107
|
+
message.isError = "error" in parsed;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Invalid JSON - just record raw
|
|
112
|
+
this.log(`Invalid JSON: ${raw.slice(0, 100)}`);
|
|
113
|
+
}
|
|
114
|
+
return message;
|
|
115
|
+
}
|
|
116
|
+
/** Set up signal handlers for clean shutdown */
|
|
117
|
+
setupSignalHandlers() {
|
|
118
|
+
const shutdown = (signal) => {
|
|
119
|
+
if (this.shutdownRequested)
|
|
120
|
+
return;
|
|
121
|
+
this.shutdownRequested = true;
|
|
122
|
+
this.log(`Received ${signal}, shutting down...`);
|
|
123
|
+
this.stop();
|
|
124
|
+
};
|
|
125
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
126
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
127
|
+
process.on("SIGHUP", () => shutdown("SIGHUP"));
|
|
128
|
+
// Handle parent process death
|
|
129
|
+
process.on("disconnect", () => shutdown("disconnect"));
|
|
130
|
+
}
|
|
131
|
+
/** Start the proxy */
|
|
132
|
+
async start() {
|
|
133
|
+
if (this.state.running) {
|
|
134
|
+
throw new Error("Proxy is already running");
|
|
135
|
+
}
|
|
136
|
+
this.log(`Starting proxy for: ${this.options.command} ${this.options.args.join(" ")}`);
|
|
137
|
+
// Open log file if configured
|
|
138
|
+
if (this.options.outputFile) {
|
|
139
|
+
this.logStream = createWriteStream(this.options.outputFile, {
|
|
140
|
+
flags: "a",
|
|
141
|
+
});
|
|
142
|
+
this.log(`Logging to: ${this.options.outputFile}`);
|
|
143
|
+
}
|
|
144
|
+
// Set up signal handlers
|
|
145
|
+
this.setupSignalHandlers();
|
|
146
|
+
// Build environment - pass through all env vars
|
|
147
|
+
const env = {
|
|
148
|
+
...process.env,
|
|
149
|
+
...this.options.env,
|
|
150
|
+
};
|
|
151
|
+
// Spawn child process with unbuffered pipes
|
|
152
|
+
this.child = spawn(this.options.command, this.options.args, {
|
|
153
|
+
cwd: this.options.cwd ?? process.cwd(),
|
|
154
|
+
env,
|
|
155
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
156
|
+
// Don't use shell - direct execution is safer
|
|
157
|
+
shell: false,
|
|
158
|
+
});
|
|
159
|
+
this.state.childPid = this.child.pid;
|
|
160
|
+
this.state.startedAt = new Date().toISOString();
|
|
161
|
+
this.state.running = true;
|
|
162
|
+
this.log(`Child process started with PID: ${this.child.pid}`);
|
|
163
|
+
// Handle child process errors
|
|
164
|
+
this.child.on("error", (err) => {
|
|
165
|
+
process.stderr.write(`[agent-recorder] Child process error: ${err.message}\n`);
|
|
166
|
+
this.stop(1);
|
|
167
|
+
});
|
|
168
|
+
// Handle child process exit
|
|
169
|
+
this.child.on("exit", (code, signal) => {
|
|
170
|
+
this.log(`Child process exited with code ${code}, signal ${signal}`);
|
|
171
|
+
this.state.running = false;
|
|
172
|
+
// Close log stream
|
|
173
|
+
if (this.logStream) {
|
|
174
|
+
this.logStream.end();
|
|
175
|
+
this.logStream = null;
|
|
176
|
+
}
|
|
177
|
+
// Exit with same code as child
|
|
178
|
+
process.exit(code ?? 0);
|
|
179
|
+
});
|
|
180
|
+
// Pipe stdin from parent to child (requests)
|
|
181
|
+
this.setupStdinPipe();
|
|
182
|
+
// Pipe stdout from child to parent (responses)
|
|
183
|
+
this.setupStdoutPipe();
|
|
184
|
+
// Forward stderr from child to parent stderr
|
|
185
|
+
if (this.child.stderr) {
|
|
186
|
+
this.child.stderr.pipe(process.stderr);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/** Set up stdin pipe with recording */
|
|
190
|
+
setupStdinPipe() {
|
|
191
|
+
if (!this.child?.stdin)
|
|
192
|
+
return;
|
|
193
|
+
// Use readline for line-by-line processing (JSON-RPC messages are newline-delimited)
|
|
194
|
+
const rl = createInterface({
|
|
195
|
+
input: process.stdin,
|
|
196
|
+
crlfDelay: Infinity,
|
|
197
|
+
});
|
|
198
|
+
rl.on("line", async (line) => {
|
|
199
|
+
if (!this.child?.stdin || this.shutdownRequested)
|
|
200
|
+
return;
|
|
201
|
+
// Record the request
|
|
202
|
+
const message = this.parseMessage(line, "request");
|
|
203
|
+
this.state.requestCount++;
|
|
204
|
+
// Log method for debugging
|
|
205
|
+
if (message.method) {
|
|
206
|
+
this.log(`→ ${message.method} (id: ${message.id})`);
|
|
207
|
+
}
|
|
208
|
+
// Record asynchronously (don't block)
|
|
209
|
+
this.recordMessage(message).catch(() => { });
|
|
210
|
+
// Forward to child stdin immediately (unbuffered)
|
|
211
|
+
this.child.stdin.write(line + "\n");
|
|
212
|
+
});
|
|
213
|
+
rl.on("close", () => {
|
|
214
|
+
this.log("Parent stdin closed");
|
|
215
|
+
// Close child stdin to signal EOF
|
|
216
|
+
this.child?.stdin?.end();
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
/** Set up stdout pipe with recording */
|
|
220
|
+
setupStdoutPipe() {
|
|
221
|
+
if (!this.child?.stdout)
|
|
222
|
+
return;
|
|
223
|
+
// Use readline for line-by-line processing
|
|
224
|
+
const rl = createInterface({
|
|
225
|
+
input: this.child.stdout,
|
|
226
|
+
crlfDelay: Infinity,
|
|
227
|
+
});
|
|
228
|
+
rl.on("line", async (line) => {
|
|
229
|
+
if (this.shutdownRequested)
|
|
230
|
+
return;
|
|
231
|
+
// Use mutex to prevent concurrent stdout corruption
|
|
232
|
+
await this.readMutex.acquire();
|
|
233
|
+
try {
|
|
234
|
+
// Record the response
|
|
235
|
+
const message = this.parseMessage(line, "response");
|
|
236
|
+
this.state.responseCount++;
|
|
237
|
+
// Log for debugging
|
|
238
|
+
if (message.isError) {
|
|
239
|
+
this.log(`← ERROR (id: ${message.id})`);
|
|
240
|
+
}
|
|
241
|
+
else if (message.id !== undefined) {
|
|
242
|
+
this.log(`← response (id: ${message.id})`);
|
|
243
|
+
}
|
|
244
|
+
// Record asynchronously (don't block)
|
|
245
|
+
this.recordMessage(message).catch(() => { });
|
|
246
|
+
// Forward to parent stdout immediately (unbuffered)
|
|
247
|
+
// This is the ONLY place we write to stdout
|
|
248
|
+
process.stdout.write(line + "\n");
|
|
249
|
+
}
|
|
250
|
+
finally {
|
|
251
|
+
this.readMutex.release();
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
rl.on("close", () => {
|
|
255
|
+
this.log("Child stdout closed");
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
/** Stop the proxy and clean up */
|
|
259
|
+
stop(exitCode = 0) {
|
|
260
|
+
this.log("Stopping proxy...");
|
|
261
|
+
this.shutdownRequested = true;
|
|
262
|
+
// Kill child process if running
|
|
263
|
+
if (this.child && !this.child.killed) {
|
|
264
|
+
this.log(`Terminating child process PID ${this.child.pid}`);
|
|
265
|
+
// Try graceful shutdown first
|
|
266
|
+
this.child.kill("SIGTERM");
|
|
267
|
+
// Force kill after timeout
|
|
268
|
+
setTimeout(() => {
|
|
269
|
+
if (this.child && !this.child.killed) {
|
|
270
|
+
this.log("Force killing child process");
|
|
271
|
+
this.child.kill("SIGKILL");
|
|
272
|
+
}
|
|
273
|
+
}, 5000);
|
|
274
|
+
}
|
|
275
|
+
// Close log stream
|
|
276
|
+
if (this.logStream) {
|
|
277
|
+
this.logStream.end();
|
|
278
|
+
this.logStream = null;
|
|
279
|
+
}
|
|
280
|
+
this.state.running = false;
|
|
281
|
+
// Log final stats
|
|
282
|
+
this.log(`Stats: ${this.state.requestCount} requests, ${this.state.responseCount} responses`);
|
|
283
|
+
// Exit if child hasn't exited yet
|
|
284
|
+
if (!this.child?.killed) {
|
|
285
|
+
setTimeout(() => process.exit(exitCode), 100);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/** Get current proxy state */
|
|
289
|
+
getState() {
|
|
290
|
+
return { ...this.state };
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the STDIO proxy
|
|
3
|
+
*/
|
|
4
|
+
/** JSON-RPC 2.0 request structure */
|
|
5
|
+
export interface JsonRpcRequest {
|
|
6
|
+
jsonrpc: "2.0";
|
|
7
|
+
method: string;
|
|
8
|
+
params?: unknown;
|
|
9
|
+
id?: string | number | null;
|
|
10
|
+
}
|
|
11
|
+
/** JSON-RPC 2.0 response structure */
|
|
12
|
+
export interface JsonRpcResponse {
|
|
13
|
+
jsonrpc: "2.0";
|
|
14
|
+
result?: unknown;
|
|
15
|
+
error?: {
|
|
16
|
+
code: number;
|
|
17
|
+
message: string;
|
|
18
|
+
data?: unknown;
|
|
19
|
+
};
|
|
20
|
+
id: string | number | null;
|
|
21
|
+
}
|
|
22
|
+
/** Recorded MCP message for telemetry */
|
|
23
|
+
export interface McpMessage {
|
|
24
|
+
/** Timestamp when message was captured */
|
|
25
|
+
timestamp: string;
|
|
26
|
+
/** Direction: client → server or server → client */
|
|
27
|
+
direction: "request" | "response";
|
|
28
|
+
/** Raw JSON-RPC message */
|
|
29
|
+
raw: string;
|
|
30
|
+
/** Parsed method (if request) */
|
|
31
|
+
method?: string | undefined;
|
|
32
|
+
/** Parsed id (for correlation) */
|
|
33
|
+
id?: string | number | null | undefined;
|
|
34
|
+
/** Whether this is an error response */
|
|
35
|
+
isError?: boolean | undefined;
|
|
36
|
+
}
|
|
37
|
+
/** Proxy configuration options */
|
|
38
|
+
export interface ProxyOptions {
|
|
39
|
+
/** Command to execute (e.g., "npx") */
|
|
40
|
+
command: string;
|
|
41
|
+
/** Arguments for the command */
|
|
42
|
+
args: string[];
|
|
43
|
+
/** Working directory */
|
|
44
|
+
cwd?: string | undefined;
|
|
45
|
+
/** Environment variables to pass */
|
|
46
|
+
env?: Record<string, string> | undefined;
|
|
47
|
+
/** Output file for JSONL logs */
|
|
48
|
+
outputFile?: string | undefined;
|
|
49
|
+
/** Remote endpoint to POST telemetry */
|
|
50
|
+
endpoint?: string | undefined;
|
|
51
|
+
/** Enable debug logging to stderr */
|
|
52
|
+
debug?: boolean | undefined;
|
|
53
|
+
/** Session ID for correlation */
|
|
54
|
+
sessionId?: string | undefined;
|
|
55
|
+
}
|
|
56
|
+
/** Proxy state */
|
|
57
|
+
export interface ProxyState {
|
|
58
|
+
/** Child process PID */
|
|
59
|
+
childPid?: number | undefined;
|
|
60
|
+
/** Whether proxy is running */
|
|
61
|
+
running: boolean;
|
|
62
|
+
/** Start timestamp */
|
|
63
|
+
startedAt?: string | undefined;
|
|
64
|
+
/** Message counts */
|
|
65
|
+
requestCount: number;
|
|
66
|
+
responseCount: number;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,sCAAsC;AACtC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,yCAAyC;AACzC,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,SAAS,EAAE,SAAS,GAAG,UAAU,CAAC;IAClC,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,kCAAkC;IAClC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACxC,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,kCAAkC;AAClC,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,oCAAoC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACzC,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,qCAAqC;IACrC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,kBAAkB;AAClB,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,+BAA+B;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,qBAAqB;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB"}
|