cortexdb-mcp 0.2.0__py3-none-any.whl

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.
@@ -0,0 +1,3 @@
1
+ """CortexDB MCP Server -- expose CortexDB memory operations to AI agents via MCP."""
2
+
3
+ __version__ = "0.2.0"
cortexdb_mcp/api.py ADDED
@@ -0,0 +1,132 @@
1
+ """REST API for the CortexDB insights engine.
2
+
3
+ Exposes a lightweight FastAPI application that the GTM web dashboard calls to
4
+ display proactive insights. Results are cached with a configurable TTL (default
5
+ 5 minutes) so the engine is not re-run on every request.
6
+
7
+ Configuration is read from environment variables:
8
+
9
+ - ``CORTEXDB_URL`` -- CortexDB base URL (default ``http://localhost:3141``)
10
+ - ``CORTEXDB_API_KEY`` -- Optional bearer token
11
+ - ``CORTEXDB_TENANT_ID``-- Optional tenant scope
12
+ - ``INSIGHTS_CACHE_TTL``-- Cache lifetime in seconds (default ``300``)
13
+
14
+ Run directly::
15
+
16
+ uvicorn cortexdb_mcp.api:app --host 0.0.0.0 --port 8080
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import logging
22
+ import os
23
+ import time
24
+ from typing import Any
25
+
26
+ from fastapi import FastAPI
27
+ from fastapi.middleware.cors import CORSMiddleware
28
+
29
+ from cortexdb_mcp.insights import InsightsEngine
30
+
31
+ logger = logging.getLogger("cortexdb_mcp.api")
32
+
33
+ # ---------------------------------------------------------------------------
34
+ # Configuration
35
+ # ---------------------------------------------------------------------------
36
+
37
+ CORTEXDB_URL = os.environ.get("CORTEXDB_URL", "http://localhost:3141")
38
+ CORTEXDB_API_KEY = os.environ.get("CORTEXDB_API_KEY")
39
+ CORTEXDB_TENANT_ID = os.environ.get("CORTEXDB_TENANT_ID")
40
+ INSIGHTS_CACHE_TTL = int(os.environ.get("INSIGHTS_CACHE_TTL", "300"))
41
+
42
+ # ---------------------------------------------------------------------------
43
+ # Cache
44
+ # ---------------------------------------------------------------------------
45
+
46
+
47
+ class InsightsCache:
48
+ """Simple in-memory cache with TTL for generated insights."""
49
+
50
+ def __init__(self, ttl_seconds: int = 300) -> None:
51
+ self.ttl_seconds = ttl_seconds
52
+ self._data: list[dict[str, Any]] | None = None
53
+ self._timestamp: float = 0.0
54
+
55
+ def get(self) -> list[dict[str, Any]] | None:
56
+ """Return cached insights if still valid, otherwise None."""
57
+ if self._data is not None and (time.monotonic() - self._timestamp) < self.ttl_seconds:
58
+ return self._data
59
+ return None
60
+
61
+ def set(self, data: list[dict[str, Any]]) -> None:
62
+ """Store insights in the cache."""
63
+ self._data = data
64
+ self._timestamp = time.monotonic()
65
+
66
+ def invalidate(self) -> None:
67
+ """Force-expire the cache."""
68
+ self._data = None
69
+ self._timestamp = 0.0
70
+
71
+
72
+ _cache = InsightsCache(ttl_seconds=INSIGHTS_CACHE_TTL)
73
+
74
+ # ---------------------------------------------------------------------------
75
+ # FastAPI app
76
+ # ---------------------------------------------------------------------------
77
+
78
+ app = FastAPI(
79
+ title="CortexDB Insights API",
80
+ description="Proactive insights for the CortexDB GTM web dashboard.",
81
+ version="0.1.0",
82
+ )
83
+
84
+ app.add_middleware(
85
+ CORSMiddleware,
86
+ allow_origins=["*"],
87
+ allow_methods=["GET", "POST", "OPTIONS"],
88
+ allow_headers=["*"],
89
+ )
90
+
91
+
92
+ def _engine() -> InsightsEngine:
93
+ """Build a fresh InsightsEngine from environment configuration."""
94
+ return InsightsEngine(
95
+ cortex_url=CORTEXDB_URL,
96
+ api_key=CORTEXDB_API_KEY,
97
+ tenant_id=CORTEXDB_TENANT_ID,
98
+ )
99
+
100
+
101
+ @app.get("/api/insights")
102
+ async def get_insights() -> dict[str, Any]:
103
+ """Return proactive insights as JSON.
104
+
105
+ Results are cached for ``INSIGHTS_CACHE_TTL`` seconds (default 300).
106
+ """
107
+ cached = _cache.get()
108
+ if cached is not None:
109
+ return {"insights": cached, "cached": True}
110
+
111
+ engine = _engine()
112
+ insights = await engine.generate_all()
113
+ serialized = [i.to_dict() for i in insights]
114
+ _cache.set(serialized)
115
+ return {"insights": serialized, "cached": False}
116
+
117
+
118
+ @app.post("/api/insights/refresh")
119
+ async def refresh_insights() -> dict[str, Any]:
120
+ """Force-refresh the insights cache and return fresh results."""
121
+ _cache.invalidate()
122
+ engine = _engine()
123
+ insights = await engine.generate_all()
124
+ serialized = [i.to_dict() for i in insights]
125
+ _cache.set(serialized)
126
+ return {"insights": serialized, "cached": False}
127
+
128
+
129
+ @app.get("/api/health")
130
+ async def health() -> dict[str, str]:
131
+ """Health check for the insights API."""
132
+ return {"status": "ok"}
cortexdb_mcp/config.py ADDED
@@ -0,0 +1,40 @@
1
+ """Configuration management for the CortexDB MCP server.
2
+
3
+ Reads settings from environment variables with sensible defaults.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import os
9
+ from dataclasses import dataclass
10
+
11
+
12
+ @dataclass(frozen=True)
13
+ class CortexMCPConfig:
14
+ """Configuration for connecting to a CortexDB instance.
15
+
16
+ Attributes:
17
+ url: Base URL of the CortexDB HTTP API.
18
+ api_key: Optional API key for authenticated access.
19
+ timeout: HTTP request timeout in seconds.
20
+ """
21
+
22
+ url: str = "http://localhost:3141"
23
+ api_key: str | None = None
24
+ timeout: float = 30.0
25
+
26
+ @classmethod
27
+ def from_env(cls) -> CortexMCPConfig:
28
+ """Build configuration from environment variables.
29
+
30
+ Environment variables
31
+ ---------------------
32
+ CORTEXDB_URL -- CortexDB base URL (default ``http://localhost:3141``)
33
+ CORTEXDB_API_KEY -- API key (default ``None``)
34
+ CORTEXDB_TIMEOUT -- Request timeout in seconds (default ``30.0``)
35
+ """
36
+ return cls(
37
+ url=os.environ.get("CORTEXDB_URL", cls.url),
38
+ api_key=os.environ.get("CORTEXDB_API_KEY", cls.api_key),
39
+ timeout=float(os.environ.get("CORTEXDB_TIMEOUT", str(cls.timeout))),
40
+ )