@dollhousemcp/mcp-server
Version:
DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.
53 lines • 7.61 kB
JavaScript
/**
* Lightweight in-memory accumulator for MCP-AQL operation metrics.
*
* Records operation counts, durations, and error rates. The companion
* OperationMetricsCollector reads from this tracker each collection cycle.
*/
const DURATION_RING_SIZE = 1000;
export class OperationMetricsTracker {
totalOps = 0;
failedOps = 0;
durations = [];
byEndpoint = new Map();
byOperation = new Map();
record(operation, endpoint, durationMs, success) {
this.totalOps++;
if (!success)
this.failedOps++;
// Bounded duration history (evicts oldest when full)
this.durations.push(durationMs);
if (this.durations.length > DURATION_RING_SIZE) {
this.durations.shift();
}
this.byEndpoint.set(endpoint, (this.byEndpoint.get(endpoint) ?? 0) + 1);
this.byOperation.set(operation, (this.byOperation.get(operation) ?? 0) + 1);
}
getMetrics() {
return {
totalOps: this.totalOps,
failedOps: this.failedOps,
durations: [...this.durations],
byEndpoint: new Map(this.byEndpoint),
byOperation: new Map(this.byOperation),
};
}
/** Compute duration percentiles from the ring buffer. */
static percentiles(durations) {
if (durations.length === 0) {
return { count: 0, sum: 0, avg: 0, p50: 0, p95: 0, p99: 0 };
}
const sorted = [...durations].sort((a, b) => a - b);
const sum = sorted.reduce((s, v) => s + v, 0);
const pct = (p) => sorted[Math.min(Math.ceil(sorted.length * p) - 1, sorted.length - 1)];
return {
count: sorted.length,
sum,
avg: sum / sorted.length,
p50: pct(0.5),
p95: pct(0.95),
p99: pct(0.99),
};
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT3BlcmF0aW9uTWV0cmljc1RyYWNrZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWV0cmljcy9PcGVyYXRpb25NZXRyaWNzVHJhY2tlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDO0FBVWhDLE1BQU0sT0FBTyx1QkFBdUI7SUFDMUIsUUFBUSxHQUFHLENBQUMsQ0FBQztJQUNiLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFDTCxTQUFTLEdBQWEsRUFBRSxDQUFDO0lBQ3pCLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUN2QyxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7SUFFekQsTUFBTSxDQUFDLFNBQWlCLEVBQUUsUUFBZ0IsRUFBRSxVQUFrQixFQUFFLE9BQWdCO1FBQzlFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsT0FBTztZQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUUvQixxREFBcUQ7UUFDckQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxrQkFBa0IsRUFBRSxDQUFDO1lBQy9DLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDekIsQ0FBQztRQUVELElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFFRCxVQUFVO1FBQ1IsT0FBTztZQUNMLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtZQUN2QixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7WUFDekIsU0FBUyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQzlCLFVBQVUsRUFBRSxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQ3BDLFdBQVcsRUFBRSxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO1NBQ3ZDLENBQUM7SUFDSixDQUFDO0lBRUQseURBQXlEO0lBQ3pELE1BQU0sQ0FBQyxXQUFXLENBQUMsU0FBbUI7UUFRcEMsSUFBSSxTQUFTLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzNCLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQzlELENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqRyxPQUFPO1lBQ0wsS0FBSyxFQUFFLE1BQU0sQ0FBQyxNQUFNO1lBQ3BCLEdBQUc7WUFDSCxHQUFHLEVBQUUsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNO1lBQ3hCLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDO1lBQ2IsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDZCxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQztTQUNmLENBQUM7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIExpZ2h0d2VpZ2h0IGluLW1lbW9yeSBhY2N1bXVsYXRvciBmb3IgTUNQLUFRTCBvcGVyYXRpb24gbWV0cmljcy5cbiAqXG4gKiBSZWNvcmRzIG9wZXJhdGlvbiBjb3VudHMsIGR1cmF0aW9ucywgYW5kIGVycm9yIHJhdGVzLiBUaGUgY29tcGFuaW9uXG4gKiBPcGVyYXRpb25NZXRyaWNzQ29sbGVjdG9yIHJlYWRzIGZyb20gdGhpcyB0cmFja2VyIGVhY2ggY29sbGVjdGlvbiBjeWNsZS5cbiAqL1xuXG5jb25zdCBEVVJBVElPTl9SSU5HX1NJWkUgPSAxMDAwO1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wZXJhdGlvbk1ldHJpY3Mge1xuICB0b3RhbE9wczogbnVtYmVyO1xuICBmYWlsZWRPcHM6IG51bWJlcjtcbiAgZHVyYXRpb25zOiBudW1iZXJbXTtcbiAgYnlFbmRwb2ludDogTWFwPHN0cmluZywgbnVtYmVyPjtcbiAgYnlPcGVyYXRpb246IE1hcDxzdHJpbmcsIG51bWJlcj47XG59XG5cbmV4cG9ydCBjbGFzcyBPcGVyYXRpb25NZXRyaWNzVHJhY2tlciB7XG4gIHByaXZhdGUgdG90YWxPcHMgPSAwO1xuICBwcml2YXRlIGZhaWxlZE9wcyA9IDA7XG4gIHByaXZhdGUgcmVhZG9ubHkgZHVyYXRpb25zOiBudW1iZXJbXSA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IGJ5RW5kcG9pbnQgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGJ5T3BlcmF0aW9uID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcblxuICByZWNvcmQob3BlcmF0aW9uOiBzdHJpbmcsIGVuZHBvaW50OiBzdHJpbmcsIGR1cmF0aW9uTXM6IG51bWJlciwgc3VjY2VzczogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMudG90YWxPcHMrKztcbiAgICBpZiAoIXN1Y2Nlc3MpIHRoaXMuZmFpbGVkT3BzKys7XG5cbiAgICAvLyBCb3VuZGVkIGR1cmF0aW9uIGhpc3RvcnkgKGV2aWN0cyBvbGRlc3Qgd2hlbiBmdWxsKVxuICAgIHRoaXMuZHVyYXRpb25zLnB1c2goZHVyYXRpb25Ncyk7XG4gICAgaWYgKHRoaXMuZHVyYXRpb25zLmxlbmd0aCA+IERVUkFUSU9OX1JJTkdfU0laRSkge1xuICAgICAgdGhpcy5kdXJhdGlvbnMuc2hpZnQoKTtcbiAgICB9XG5cbiAgICB0aGlzLmJ5RW5kcG9pbnQuc2V0KGVuZHBvaW50LCAodGhpcy5ieUVuZHBvaW50LmdldChlbmRwb2ludCkgPz8gMCkgKyAxKTtcbiAgICB0aGlzLmJ5T3BlcmF0aW9uLnNldChvcGVyYXRpb24sICh0aGlzLmJ5T3BlcmF0aW9uLmdldChvcGVyYXRpb24pID8/IDApICsgMSk7XG4gIH1cblxuICBnZXRNZXRyaWNzKCk6IE9wZXJhdGlvbk1ldHJpY3Mge1xuICAgIHJldHVybiB7XG4gICAgICB0b3RhbE9wczogdGhpcy50b3RhbE9wcyxcbiAgICAgIGZhaWxlZE9wczogdGhpcy5mYWlsZWRPcHMsXG4gICAgICBkdXJhdGlvbnM6IFsuLi50aGlzLmR1cmF0aW9uc10sXG4gICAgICBieUVuZHBvaW50OiBuZXcgTWFwKHRoaXMuYnlFbmRwb2ludCksXG4gICAgICBieU9wZXJhdGlvbjogbmV3IE1hcCh0aGlzLmJ5T3BlcmF0aW9uKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIENvbXB1dGUgZHVyYXRpb24gcGVyY2VudGlsZXMgZnJvbSB0aGUgcmluZyBidWZmZXIuICovXG4gIHN0YXRpYyBwZXJjZW50aWxlcyhkdXJhdGlvbnM6IG51bWJlcltdKToge1xuICAgIGNvdW50OiBudW1iZXI7XG4gICAgc3VtOiBudW1iZXI7XG4gICAgYXZnOiBudW1iZXI7XG4gICAgcDUwOiBudW1iZXI7XG4gICAgcDk1OiBudW1iZXI7XG4gICAgcDk5OiBudW1iZXI7XG4gIH0ge1xuICAgIGlmIChkdXJhdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4geyBjb3VudDogMCwgc3VtOiAwLCBhdmc6IDAsIHA1MDogMCwgcDk1OiAwLCBwOTk6IDAgfTtcbiAgICB9XG4gICAgY29uc3Qgc29ydGVkID0gWy4uLmR1cmF0aW9uc10uc29ydCgoYSwgYikgPT4gYSAtIGIpO1xuICAgIGNvbnN0IHN1bSA9IHNvcnRlZC5yZWR1Y2UoKHMsIHYpID0+IHMgKyB2LCAwKTtcbiAgICBjb25zdCBwY3QgPSAocDogbnVtYmVyKSA9PiBzb3J0ZWRbTWF0aC5taW4oTWF0aC5jZWlsKHNvcnRlZC5sZW5ndGggKiBwKSAtIDEsIHNvcnRlZC5sZW5ndGggLSAxKV07XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvdW50OiBzb3J0ZWQubGVuZ3RoLFxuICAgICAgc3VtLFxuICAgICAgYXZnOiBzdW0gLyBzb3J0ZWQubGVuZ3RoLFxuICAgICAgcDUwOiBwY3QoMC41KSxcbiAgICAgIHA5NTogcGN0KDAuOTUpLFxuICAgICAgcDk5OiBwY3QoMC45OSksXG4gICAgfTtcbiAgfVxufVxuIl19