@metabob/mcp 0.2.2 → 0.2.3
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/cli.js +1 -128
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -35025,110 +35025,6 @@ class AuthService {
|
|
|
35025
35025
|
}
|
|
35026
35026
|
var DEFAULT_IDENTITY_ENDPOINT = "https://identity.metabob.com", RESOLVE_TIMEOUT_MS = 5000, BEARER_REFRESH_MARGIN_MS = 60000;
|
|
35027
35027
|
|
|
35028
|
-
// src/vessel-heartbeat.ts
|
|
35029
|
-
class VesselHeartbeat {
|
|
35030
|
-
config;
|
|
35031
|
-
intervalHandle;
|
|
35032
|
-
running = false;
|
|
35033
|
-
failures = 0;
|
|
35034
|
-
lastRegistered;
|
|
35035
|
-
constructor(config2) {
|
|
35036
|
-
const ttl = config2.ttl ?? DEFAULT_TTL_S;
|
|
35037
|
-
this.config = {
|
|
35038
|
-
...config2,
|
|
35039
|
-
ttl,
|
|
35040
|
-
metadata: config2.metadata ?? {},
|
|
35041
|
-
heartbeatIntervalMs: config2.heartbeatIntervalMs ?? ttl * 1000 / 2
|
|
35042
|
-
};
|
|
35043
|
-
}
|
|
35044
|
-
async start() {
|
|
35045
|
-
if (this.running)
|
|
35046
|
-
return;
|
|
35047
|
-
await this.register();
|
|
35048
|
-
this.intervalHandle = setInterval(() => {
|
|
35049
|
-
this.register().catch((err) => {
|
|
35050
|
-
console.error(`[vessel-heartbeat] interval error: ${err instanceof Error ? err.message : err}`);
|
|
35051
|
-
});
|
|
35052
|
-
}, this.config.heartbeatIntervalMs);
|
|
35053
|
-
this.running = true;
|
|
35054
|
-
console.error(`[vessel-heartbeat] started for ${this.config.vesselId} ` + `(ttl=${this.config.ttl}s interval=${this.config.heartbeatIntervalMs}ms)`);
|
|
35055
|
-
}
|
|
35056
|
-
stop() {
|
|
35057
|
-
if (!this.running)
|
|
35058
|
-
return;
|
|
35059
|
-
clearInterval(this.intervalHandle);
|
|
35060
|
-
this.intervalHandle = undefined;
|
|
35061
|
-
this.running = false;
|
|
35062
|
-
console.error(`[vessel-heartbeat] stopped for ${this.config.vesselId}`);
|
|
35063
|
-
}
|
|
35064
|
-
async register() {
|
|
35065
|
-
const { activityEndpoint, vesselId, vesselName, endpoint, shapes, metadata, ttl, authService } = this.config;
|
|
35066
|
-
const headers = { "Content-Type": "application/json" };
|
|
35067
|
-
if (authService.bearerTokenIsStale()) {
|
|
35068
|
-
authService.refreshTenant().catch(() => {});
|
|
35069
|
-
}
|
|
35070
|
-
const bearer = authService.getBearerToken();
|
|
35071
|
-
const identityApiKey = authService.getIdentityApiKey();
|
|
35072
|
-
if (bearer) {
|
|
35073
|
-
headers["Authorization"] = `Bearer ${bearer}`;
|
|
35074
|
-
} else if (identityApiKey) {
|
|
35075
|
-
headers["Authorization"] = `ApiKey ${identityApiKey}`;
|
|
35076
|
-
}
|
|
35077
|
-
const body = {
|
|
35078
|
-
vesselId,
|
|
35079
|
-
vesselName,
|
|
35080
|
-
endpoint,
|
|
35081
|
-
shapes,
|
|
35082
|
-
metadata,
|
|
35083
|
-
ttl,
|
|
35084
|
-
resolve_endpoint: "/v2/impulses/resolve",
|
|
35085
|
-
resolve_request_format: "pointer",
|
|
35086
|
-
auth_scheme: "ApiKey",
|
|
35087
|
-
resolve_timeout_ms: 30000,
|
|
35088
|
-
auth_token_source: "header",
|
|
35089
|
-
auth_delegation_mode: "direct"
|
|
35090
|
-
};
|
|
35091
|
-
try {
|
|
35092
|
-
const res = await fetch(`${activityEndpoint}/v2/vessels/register`, {
|
|
35093
|
-
method: "POST",
|
|
35094
|
-
headers,
|
|
35095
|
-
body: JSON.stringify(body),
|
|
35096
|
-
signal: AbortSignal.timeout(1e4)
|
|
35097
|
-
});
|
|
35098
|
-
if (!res.ok) {
|
|
35099
|
-
const text = await res.text().catch(() => "");
|
|
35100
|
-
console.error(`[vessel-heartbeat] registration HTTP ${res.status}: ${text.slice(0, 120)}`);
|
|
35101
|
-
this.onFailure();
|
|
35102
|
-
return false;
|
|
35103
|
-
}
|
|
35104
|
-
this.lastRegistered = new Date;
|
|
35105
|
-
this.failures = 0;
|
|
35106
|
-
console.error(`[vessel-heartbeat] registered ${vesselId} shapes=[${shapes.join(", ")}]`);
|
|
35107
|
-
return true;
|
|
35108
|
-
} catch (err) {
|
|
35109
|
-
console.error(`[vessel-heartbeat] registration error: ${err instanceof Error ? err.message : err}`);
|
|
35110
|
-
this.onFailure();
|
|
35111
|
-
return false;
|
|
35112
|
-
}
|
|
35113
|
-
}
|
|
35114
|
-
onFailure() {
|
|
35115
|
-
this.failures++;
|
|
35116
|
-
if (this.failures >= MAX_FAILURES) {
|
|
35117
|
-
console.error(`[vessel-heartbeat] ${MAX_FAILURES} consecutive failures — stopping`);
|
|
35118
|
-
this.stop();
|
|
35119
|
-
}
|
|
35120
|
-
}
|
|
35121
|
-
status() {
|
|
35122
|
-
return {
|
|
35123
|
-
running: this.running,
|
|
35124
|
-
lastRegistered: this.lastRegistered,
|
|
35125
|
-
consecutiveFailures: this.failures,
|
|
35126
|
-
vesselId: this.config.vesselId
|
|
35127
|
-
};
|
|
35128
|
-
}
|
|
35129
|
-
}
|
|
35130
|
-
var MAX_FAILURES = 3, DEFAULT_TTL_S = 300;
|
|
35131
|
-
|
|
35132
35028
|
// src/index.ts
|
|
35133
35029
|
var exports_src = {};
|
|
35134
35030
|
function log(level, message, data) {
|
|
@@ -35210,15 +35106,11 @@ Authentication failed: ${err.message}`);
|
|
|
35210
35106
|
log("warn", "Continuing without connection slot. Some features may be limited.");
|
|
35211
35107
|
}
|
|
35212
35108
|
}
|
|
35213
|
-
vesselHeartbeat.start().catch((err) => {
|
|
35214
|
-
log("warn", "Discovery registration failed (continuing without discovery)", { error: err.message });
|
|
35215
|
-
});
|
|
35216
35109
|
const transport = new StdioServerTransport;
|
|
35217
35110
|
await server.connect(transport);
|
|
35218
35111
|
log("info", "MCP server ready");
|
|
35219
35112
|
process.on("SIGINT", async () => {
|
|
35220
35113
|
log("info", "Shutting down...");
|
|
35221
|
-
vesselHeartbeat.stop();
|
|
35222
35114
|
authService.stopKeyHeartbeat();
|
|
35223
35115
|
await apiClient.shutdown();
|
|
35224
35116
|
await vesselServer.stop();
|
|
@@ -35228,7 +35120,6 @@ Authentication failed: ${err.message}`);
|
|
|
35228
35120
|
});
|
|
35229
35121
|
process.on("SIGTERM", async () => {
|
|
35230
35122
|
log("info", "Shutting down...");
|
|
35231
|
-
vesselHeartbeat.stop();
|
|
35232
35123
|
authService.stopKeyHeartbeat();
|
|
35233
35124
|
await apiClient.shutdown();
|
|
35234
35125
|
await vesselServer.stop();
|
|
@@ -35237,7 +35128,7 @@ Authentication failed: ${err.message}`);
|
|
|
35237
35128
|
process.exit(0);
|
|
35238
35129
|
});
|
|
35239
35130
|
}
|
|
35240
|
-
var ANALYSIS_API_URL, ACTIVITY_API_URL, SESSION_ID, LOG_LEVEL, MAX_REQUESTS_PER_MINUTE, HEALTH_PORT, METABOB_API_KEY, SESSION_TOKEN, USE_CONNECTION_SLOTS, IDENTITY_ENDPOINT,
|
|
35131
|
+
var ANALYSIS_API_URL, ACTIVITY_API_URL, SESSION_ID, LOG_LEVEL, MAX_REQUESTS_PER_MINUTE, HEALTH_PORT, METABOB_API_KEY, SESSION_TOKEN, USE_CONNECTION_SLOTS, IDENTITY_ENDPOINT, apiClient, sessionManager, rateLimiter, circuitBreaker, authService, identityApiKey, vesselServer, server;
|
|
35241
35132
|
var init_src = __esm(() => {
|
|
35242
35133
|
init_server2();
|
|
35243
35134
|
init_stdio2();
|
|
@@ -35257,9 +35148,6 @@ var init_src = __esm(() => {
|
|
|
35257
35148
|
SESSION_TOKEN = process.env.SESSION_TOKEN;
|
|
35258
35149
|
USE_CONNECTION_SLOTS = process.env.USE_CONNECTION_SLOTS === "true";
|
|
35259
35150
|
IDENTITY_ENDPOINT = process.env.IDENTITY_ENDPOINT || "https://identity.metabob.com";
|
|
35260
|
-
ACTIVITY_ENDPOINT = process.env.ACTIVITY_ENDPOINT || "https://activity.metabob.com";
|
|
35261
|
-
VESSEL_ID = process.env.VESSEL_ID || "metabob_mcp";
|
|
35262
|
-
VESSEL_ENDPOINT = process.env.VESSEL_ENDPOINT || `http://localhost:${HEALTH_PORT}`;
|
|
35263
35151
|
apiClient = new AnalysisAPIClient({
|
|
35264
35152
|
baseURL: ANALYSIS_API_URL,
|
|
35265
35153
|
activityApiUrl: ACTIVITY_API_URL,
|
|
@@ -35298,21 +35186,6 @@ var init_src = __esm(() => {
|
|
|
35298
35186
|
apiKey: METABOB_API_KEY,
|
|
35299
35187
|
authService
|
|
35300
35188
|
});
|
|
35301
|
-
vesselHeartbeat = new VesselHeartbeat({
|
|
35302
|
-
activityEndpoint: ACTIVITY_ENDPOINT,
|
|
35303
|
-
vesselId: VESSEL_ID,
|
|
35304
|
-
vesselName: "Metabob MCP",
|
|
35305
|
-
endpoint: VESSEL_ENDPOINT,
|
|
35306
|
-
shapes: [
|
|
35307
|
-
"mcp:tool_call",
|
|
35308
|
-
"code:cochange_prediction",
|
|
35309
|
-
"code:impact_analysis",
|
|
35310
|
-
"code:git_change_assignment",
|
|
35311
|
-
"code:analysis_context"
|
|
35312
|
-
],
|
|
35313
|
-
metadata: { version: "0.2.0" },
|
|
35314
|
-
authService
|
|
35315
|
-
});
|
|
35316
35189
|
server = new Server({
|
|
35317
35190
|
name: "metabob-mcp",
|
|
35318
35191
|
version: "0.2.0"
|