@virsanghavi/axis-server 1.4.0 → 1.5.0

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.
Files changed (2) hide show
  1. package/dist/mcp-server.mjs +111 -0
  2. package/package.json +1 -1
@@ -1545,6 +1545,92 @@ var nerveCenter = new NerveCenter(manager, {
1545
1545
  projectName: process.env.PROJECT_NAME || "default"
1546
1546
  });
1547
1547
  logger.info("=== Axis MCP Server Initialized ===");
1548
+ var RECHECK_INTERVAL_MS = 30 * 60 * 1e3;
1549
+ var GRACE_PERIOD_MS = 5 * 60 * 1e3;
1550
+ var subscription = {
1551
+ checked: false,
1552
+ valid: true,
1553
+ // Assume valid until proven otherwise (for startup)
1554
+ plan: "unknown",
1555
+ reason: "",
1556
+ checkedAt: 0
1557
+ };
1558
+ async function verifySubscription() {
1559
+ if (!apiSecret) {
1560
+ subscription = { checked: true, valid: true, plan: "local", reason: "No API key configured \u2014 local mode", checkedAt: Date.now() };
1561
+ logger.info("[subscription] No API key \u2014 running in local/dev mode, skipping verification");
1562
+ return subscription;
1563
+ }
1564
+ const verifyUrl = apiUrl.endsWith("/v1") ? `${apiUrl}/verify` : `${apiUrl}/v1/verify`;
1565
+ logger.info(`[subscription] Verifying subscription at ${verifyUrl}`);
1566
+ const controller = new AbortController();
1567
+ const timeout = setTimeout(() => controller.abort(), 1e4);
1568
+ try {
1569
+ const response = await fetch(verifyUrl, {
1570
+ method: "GET",
1571
+ headers: {
1572
+ "Authorization": `Bearer ${apiSecret}`
1573
+ },
1574
+ signal: controller.signal
1575
+ });
1576
+ clearTimeout(timeout);
1577
+ const data = await response.json();
1578
+ logger.info(`[subscription] Verify response: ${JSON.stringify(data)}`);
1579
+ if (data.valid === true) {
1580
+ subscription = {
1581
+ checked: true,
1582
+ valid: true,
1583
+ plan: data.plan || "Pro",
1584
+ reason: "",
1585
+ checkedAt: Date.now(),
1586
+ validUntil: data.validUntil
1587
+ };
1588
+ } else {
1589
+ subscription = {
1590
+ checked: true,
1591
+ valid: false,
1592
+ plan: data.plan || "Free",
1593
+ reason: data.reason || "subscription_invalid",
1594
+ checkedAt: Date.now()
1595
+ };
1596
+ logger.warn(`[subscription] Subscription NOT valid: ${data.reason}`);
1597
+ }
1598
+ } catch (e) {
1599
+ clearTimeout(timeout);
1600
+ logger.warn(`[subscription] Verification failed (network): ${e.message}`);
1601
+ if (!subscription.checked) {
1602
+ subscription = {
1603
+ checked: true,
1604
+ valid: true,
1605
+ // Grace period
1606
+ plan: "unverified",
1607
+ reason: "Verification endpoint unreachable \u2014 grace period active",
1608
+ checkedAt: Date.now()
1609
+ };
1610
+ logger.warn("[subscription] First check failed \u2014 allowing grace period");
1611
+ }
1612
+ }
1613
+ return subscription;
1614
+ }
1615
+ function isSubscriptionStale() {
1616
+ return Date.now() - subscription.checkedAt > RECHECK_INTERVAL_MS;
1617
+ }
1618
+ function getSubscriptionBlockMessage() {
1619
+ return [
1620
+ "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
1621
+ " Axis Pro subscription required",
1622
+ "",
1623
+ ` Status: ${subscription.reason || "subscription_expired"}`,
1624
+ ` Current plan: ${subscription.plan}`,
1625
+ "",
1626
+ " Your Axis Pro subscription has expired or is inactive.",
1627
+ " All Axis MCP tools are disabled until the subscription is renewed.",
1628
+ "",
1629
+ " \u2192 Renew at https://useaxis.dev/dashboard",
1630
+ " \u2192 After renewing, restart your IDE to re-verify.",
1631
+ "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"
1632
+ ].join("\n");
1633
+ }
1548
1634
  var ragEngine;
1549
1635
  if (!useRemoteApiOnly && process.env.NEXT_PUBLIC_SUPABASE_URL && process.env.SUPABASE_SERVICE_ROLE_KEY) {
1550
1636
  ragEngine = new RagEngine(
@@ -1894,6 +1980,16 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
1894
1980
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
1895
1981
  const { name, arguments: args } = request.params;
1896
1982
  logger.info("Tool call", { name });
1983
+ if (isSubscriptionStale()) {
1984
+ await verifySubscription();
1985
+ }
1986
+ if (!subscription.valid) {
1987
+ logger.warn(`[subscription] Blocking tool call "${name}" \u2014 subscription invalid`);
1988
+ return {
1989
+ content: [{ type: "text", text: getSubscriptionBlockMessage() }],
1990
+ isError: true
1991
+ };
1992
+ }
1897
1993
  if (name === READ_CONTEXT_TOOL) {
1898
1994
  const filename = String(args?.filename);
1899
1995
  try {
@@ -2069,6 +2165,21 @@ async function main() {
2069
2165
  ragEngine.setProjectId(nerveCenter.projectId);
2070
2166
  logger.info(`Local RAG Engine linked to Project ID: ${nerveCenter.projectId}`);
2071
2167
  }
2168
+ await verifySubscription();
2169
+ if (!subscription.valid) {
2170
+ logger.error("[subscription] Subscription invalid at startup \u2014 all tools will be blocked");
2171
+ logger.error(`[subscription] Reason: ${subscription.reason} | Plan: ${subscription.plan}`);
2172
+ } else {
2173
+ logger.info(`[subscription] Subscription verified: ${subscription.plan} (valid until: ${subscription.validUntil || "N/A"})`);
2174
+ }
2175
+ setInterval(async () => {
2176
+ try {
2177
+ await verifySubscription();
2178
+ logger.info(`[subscription] Periodic re-check: valid=${subscription.valid}, plan=${subscription.plan}`);
2179
+ } catch (e) {
2180
+ logger.warn(`[subscription] Periodic re-check failed: ${e}`);
2181
+ }
2182
+ }, RECHECK_INTERVAL_MS);
2072
2183
  logger.info("MCP server ready - all tools and resources registered");
2073
2184
  const transport = new StdioServerTransport();
2074
2185
  await server.connect(transport);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@virsanghavi/axis-server",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Axis MCP Server CLI",
5
5
  "main": "dist/index.js",
6
6
  "bin": {