@decaf-ts/decorator-validation
Version:
simple decorator based validation engine
70 lines • 8.7 kB
JavaScript
import { FastMCP } from "fastmcp";
import { Logging } from "@decaf-ts/logging";
function validateVersion(version) {
const regexp = /(\d+)\.(\d+)\.(\d+)/g;
const match = regexp.exec(version);
if (!match)
throw new Error(`Invalid version string. should obey semantic versioning: ${version}`);
return `${match[1]}.${match[2]}.${match[3]}`;
}
class Builder {
constructor() {
this.tools = {};
this.log = Logging.for("MCP Builder");
}
setName(value) {
this.name = value;
this.log.debug(`name set to ${value}`);
return this;
}
setVersion(value) {
this.version = validateVersion(value);
this.log.debug(`version set to ${value}`);
return this;
}
addTool(config) {
const { name } = config;
if (name in this.tools)
throw new Error(`tool ${name} already registered`);
this.tools[name] = config;
this.log.debug(`tool ${name} added`);
return this;
}
build() {
if (!this.name)
throw new Error("name is required");
if (!this.version)
throw new Error("version is required");
const mcp = new FastMCP({
name: this.name,
version: this.version,
});
Object.values(this.tools).forEach((tool) => {
try {
mcp.addTool(tool);
}
catch (e) {
throw new Error(`Failed to add tool ${tool.name}: ${e}`);
}
});
this.log.info(`${this.name} MCP built`);
this.log.debug(`${this.name} MCP - available tools: ${Object.keys(this.tools).join(", ")}`);
return new ModelContextProtocol(mcp);
}
}
export class ModelContextProtocol {
get log() {
return Logging.for(this);
}
constructor(mcp) {
this.mcp = mcp;
}
static { this.Builder = Builder; }
static get builder() {
return new ModelContextProtocol.Builder();
}
static validateVersion(version) {
return validateVersion(version);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTW9kZWxDb250ZXh0UHJvdG9jb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbWNwL01vZGVsQ29udGV4dFByb3RvY29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQVEsTUFBTSxTQUFTLENBQUM7QUFDeEMsT0FBTyxFQUFVLE9BQU8sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBR3BELFNBQVMsZUFBZSxDQUFDLE9BQWU7SUFDdEMsTUFBTSxNQUFNLEdBQUcsc0JBQXNCLENBQUM7SUFDdEMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuQyxJQUFJLENBQUMsS0FBSztRQUNSLE1BQU0sSUFBSSxLQUFLLENBQ2IsNERBQTRELE9BQU8sRUFBRSxDQUN0RSxDQUFDO0lBQ0osT0FBTyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFxQyxDQUFDO0FBQ2xGLENBQUM7QUFFRCxNQUFNLE9BQU87SUFPWDtRQUpBLFVBQUssR0FBbUMsRUFBRSxDQUFDO1FBRTNDLFFBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBRWxCLENBQUM7SUFFaEIsT0FBTyxDQUFDLEtBQWE7UUFDbkIsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUM7UUFDbEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsZUFBZSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELFVBQVUsQ0FBQyxLQUFhO1FBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGtCQUFrQixLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzFDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE9BQU8sQ0FDTCxNQUF1QjtRQUV2QixNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDO1FBQ3hCLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxRQUFRLElBQUkscUJBQXFCLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUMxQixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDLENBQUM7UUFDckMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsS0FBSztRQUdILElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDMUQsTUFBTSxHQUFHLEdBQUcsSUFBSSxPQUFPLENBQU87WUFDNUIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO1lBQ2YsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1NBQ3RCLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ3pDLElBQUksQ0FBQztnQkFDSCxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3BCLENBQUM7WUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO2dCQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixJQUFJLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDM0QsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxZQUFZLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWixHQUFHLElBQUksQ0FBQyxJQUFJLDJCQUEyQixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDNUUsQ0FBQztRQUNGLE9BQU8sSUFBSSxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN2QyxDQUFDO0NBQ0Y7QUFFRCxNQUFNLE9BQU8sb0JBQW9CO0lBQy9CLElBQWMsR0FBRztRQUNmLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFXLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQsWUFBK0IsR0FBa0I7UUFBbEIsUUFBRyxHQUFILEdBQUcsQ0FBZTtJQUFHLENBQUM7YUFFckMsWUFBTyxHQUFHLE9BQU8sQ0FBQztJQUVsQyxNQUFNLEtBQUssT0FBTztRQUNoQixPQUFPLElBQUksb0JBQW9CLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDNUMsQ0FBQztJQUVPLE1BQU0sQ0FBQyxlQUFlLENBQzVCLE9BQWU7UUFFZixPQUFPLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNsQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRmFzdE1DUCwgVG9vbCB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQgeyBMb2dnZXIsIExvZ2dpbmcgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcbmltcG9ydCB7IEZhc3RNQ1BTZXNzaW9uQXV0aCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmZ1bmN0aW9uIHZhbGlkYXRlVmVyc2lvbih2ZXJzaW9uOiBzdHJpbmcpOiBgJHtudW1iZXJ9LiR7bnVtYmVyfS4ke251bWJlcn1gIHtcbiAgY29uc3QgcmVnZXhwID0gLyhcXGQrKVxcLihcXGQrKVxcLihcXGQrKS9nO1xuICBjb25zdCBtYXRjaCA9IHJlZ2V4cC5leGVjKHZlcnNpb24pO1xuICBpZiAoIW1hdGNoKVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBJbnZhbGlkIHZlcnNpb24gc3RyaW5nLiBzaG91bGQgb2JleSBzZW1hbnRpYyB2ZXJzaW9uaW5nOiAke3ZlcnNpb259YFxuICAgICk7XG4gIHJldHVybiBgJHttYXRjaFsxXX0uJHttYXRjaFsyXX0uJHttYXRjaFszXX1gIGFzIGAke251bWJlcn0uJHtudW1iZXJ9LiR7bnVtYmVyfWA7XG59XG5cbmNsYXNzIEJ1aWxkZXIge1xuICBuYW1lITogc3RyaW5nO1xuICB2ZXJzaW9uITogYCR7bnVtYmVyfS4ke251bWJlcn0uJHtudW1iZXJ9YDtcbiAgdG9vbHM6IFJlY29yZDxzdHJpbmcsIFRvb2w8YW55LCBhbnk+PiA9IHt9O1xuXG4gIGxvZyA9IExvZ2dpbmcuZm9yKFwiTUNQIEJ1aWxkZXJcIik7XG5cbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIHNldE5hbWUodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMubmFtZSA9IHZhbHVlO1xuICAgIHRoaXMubG9nLmRlYnVnKGBuYW1lIHNldCB0byAke3ZhbHVlfWApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc2V0VmVyc2lvbih2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy52ZXJzaW9uID0gdmFsaWRhdGVWZXJzaW9uKHZhbHVlKTtcbiAgICB0aGlzLmxvZy5kZWJ1ZyhgdmVyc2lvbiBzZXQgdG8gJHt2YWx1ZX1gKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGFkZFRvb2w8QXV0aCBleHRlbmRzIEZhc3RNQ1BTZXNzaW9uQXV0aCA9IHVuZGVmaW5lZD4oXG4gICAgY29uZmlnOiBUb29sPEF1dGgsIGFueT5cbiAgKSB7XG4gICAgY29uc3QgeyBuYW1lIH0gPSBjb25maWc7XG4gICAgaWYgKG5hbWUgaW4gdGhpcy50b29scykgdGhyb3cgbmV3IEVycm9yKGB0b29sICR7bmFtZX0gYWxyZWFkeSByZWdpc3RlcmVkYCk7XG4gICAgdGhpcy50b29sc1tuYW1lXSA9IGNvbmZpZztcbiAgICB0aGlzLmxvZy5kZWJ1ZyhgdG9vbCAke25hbWV9IGFkZGVkYCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBidWlsZDxcbiAgICBBdXRoIGV4dGVuZHMgRmFzdE1DUFNlc3Npb25BdXRoID0gdW5kZWZpbmVkLFxuICA+KCk6IE1vZGVsQ29udGV4dFByb3RvY29sPEF1dGg+IHtcbiAgICBpZiAoIXRoaXMubmFtZSkgdGhyb3cgbmV3IEVycm9yKFwibmFtZSBpcyByZXF1aXJlZFwiKTtcbiAgICBpZiAoIXRoaXMudmVyc2lvbikgdGhyb3cgbmV3IEVycm9yKFwidmVyc2lvbiBpcyByZXF1aXJlZFwiKTtcbiAgICBjb25zdCBtY3AgPSBuZXcgRmFzdE1DUDxBdXRoPih7XG4gICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICB2ZXJzaW9uOiB0aGlzLnZlcnNpb24sXG4gICAgfSk7XG4gICAgT2JqZWN0LnZhbHVlcyh0aGlzLnRvb2xzKS5mb3JFYWNoKCh0b29sKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBtY3AuYWRkVG9vbCh0b29sKTtcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gYWRkIHRvb2wgJHt0b29sLm5hbWV9OiAke2V9YCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5sb2cuaW5mbyhgJHt0aGlzLm5hbWV9IE1DUCBidWlsdGApO1xuICAgIHRoaXMubG9nLmRlYnVnKFxuICAgICAgYCR7dGhpcy5uYW1lfSBNQ1AgLSBhdmFpbGFibGUgdG9vbHM6ICR7T2JqZWN0LmtleXModGhpcy50b29scykuam9pbihcIiwgXCIpfWBcbiAgICApO1xuICAgIHJldHVybiBuZXcgTW9kZWxDb250ZXh0UHJvdG9jb2wobWNwKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTW9kZWxDb250ZXh0UHJvdG9jb2w8QXV0aCBleHRlbmRzIEZhc3RNQ1BTZXNzaW9uQXV0aCA9IHVuZGVmaW5lZD4ge1xuICBwcm90ZWN0ZWQgZ2V0IGxvZygpOiBMb2dnZXIge1xuICAgIHJldHVybiBMb2dnaW5nLmZvcih0aGlzIGFzIGFueSk7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgcmVhZG9ubHkgbWNwOiBGYXN0TUNQPEF1dGg+KSB7fVxuXG4gIHN0YXRpYyByZWFkb25seSBCdWlsZGVyID0gQnVpbGRlcjtcblxuICBzdGF0aWMgZ2V0IGJ1aWxkZXIoKSB7XG4gICAgcmV0dXJuIG5ldyBNb2RlbENvbnRleHRQcm90b2NvbC5CdWlsZGVyKCk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyB2YWxpZGF0ZVZlcnNpb24oXG4gICAgdmVyc2lvbjogc3RyaW5nXG4gICk6IGAke251bWJlcn0uJHtudW1iZXJ9LiR7bnVtYmVyfWAge1xuICAgIHJldHVybiB2YWxpZGF0ZVZlcnNpb24odmVyc2lvbik7XG4gIH1cbn1cbiJdfQ==