server.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. package mcp
  2. import (
  3. "time"
  4. models "github.com/opencost/opencost/pkg/cloud/models"
  5. "github.com/opencost/opencost/pkg/cloudcost"
  6. "github.com/opencost/opencost/pkg/costmodel"
  7. )
  8. // QueryType defines the type of query to be executed.
  9. type QueryType string
  10. const (
  11. AllocationQueryType QueryType = "allocation"
  12. AssetQueryType QueryType = "asset"
  13. CloudCostQueryType QueryType = "cloudcost"
  14. )
  15. // MCPRequest represents a single turn in a conversation with the OpenCost MCP server.
  16. type MCPRequest struct {
  17. SessionID string `json:"sessionId"`
  18. Query *OpenCostQueryRequest `json:"query"`
  19. }
  20. // MCPResponse is the response from the OpenCost MCP server for a single turn.
  21. type MCPResponse struct {
  22. Data interface{} `json:"data"`
  23. QueryInfo QueryMetadata `json:"queryInfo"`
  24. Summary *DataSummary `json:"summary,omitempty"`
  25. }
  26. // QueryMetadata contains metadata about the query execution.
  27. type QueryMetadata struct {
  28. QueryID string `json:"queryId"`
  29. Timestamp time.Time `json:"timestamp"`
  30. ProcessingTime time.Duration `json:"processingTime"`
  31. }
  32. // DataSummary provides a summary of the data.
  33. type DataSummary struct {
  34. Title string `json:"title"`
  35. Content string `json:"content"`
  36. }
  37. // OpenCostQueryRequest provides a unified interface for all OpenCost query types.
  38. type OpenCostQueryRequest struct {
  39. QueryType QueryType `json:"queryType" validate:"required,oneof=allocation asset cloudcost"`
  40. Window string `json:"window" validate:"required"`
  41. AllocationParams *AllocationQuery `json:"allocationParams,omitempty"`
  42. AssetParams *AssetQuery `json:"assetParams,omitempty"`
  43. CloudCostParams *CloudCostQuery `json:"cloudCostParams,omitempty"`
  44. }
  45. // AllocationQuery contains the parameters for an allocation query.
  46. type AllocationQuery struct {
  47. Step time.Duration `json:"step,omitempty"`
  48. Accumulate bool `json:"accumulate,omitempty"`
  49. ShareIdle bool `json:"shareIdle,omitempty"`
  50. Aggregate string `json:"aggregate,omitempty"`
  51. IncludeIdle bool `json:"includeIdle,omitempty"`
  52. IdleByNode bool `json:"idleByNode,omitempty"`
  53. IncludeProportionalAssetResourceCosts bool `json:"includeProportionalAssetResourceCosts,omitempty"`
  54. IncludeAggregatedMetadata bool `json:"includeAggregatedMetadata,omitempty"`
  55. ShareLB bool `json:"sharelb,omitempty"`
  56. }
  57. // AssetQuery contains the parameters for an asset query.
  58. type AssetQuery struct {
  59. // Currently no specific parameters needed for asset queries as it only takes window as parameter
  60. }
  61. // CloudCostQuery contains the parameters for a cloud cost query.
  62. type CloudCostQuery struct {
  63. Aggregate string `json:"aggregate,omitempty"` // Comma-separated list of aggregation properties
  64. Accumulate string `json:"accumulate,omitempty"` // e.g., "week", "day", "month"
  65. Filter string `json:"filter,omitempty"` // Filter expression for cloud costs
  66. Provider string `json:"provider,omitempty"` // Cloud provider filter (aws, gcp, azure, etc.)
  67. Service string `json:"service,omitempty"` // Service filter (ec2, s3, compute, etc.)
  68. Category string `json:"category,omitempty"` // Category filter (compute, storage, network, etc.)
  69. Region string `json:"region,omitempty"` // Region filter
  70. Account string `json:"account,omitempty"` // Account filter
  71. }
  72. // AllocationResponse represents the allocation data returned to the AI agent.
  73. type AllocationResponse struct {
  74. // The allocation data, as a map of allocation sets.
  75. Allocations map[string]*AllocationSet `json:"allocations"`
  76. }
  77. // AllocationSet represents a set of allocation data.
  78. type AllocationSet struct {
  79. // The name of the allocation set.
  80. Name string `json:"name"`
  81. Properties map[string]string `json:"properties"`
  82. Allocations []*Allocation `json:"allocations"`
  83. }
  84. // TotalCost calculates the total cost of all allocations in the set.
  85. func (as *AllocationSet) TotalCost() float64 {
  86. var total float64
  87. for _, alloc := range as.Allocations {
  88. total += alloc.TotalCost
  89. }
  90. return total
  91. }
  92. // Allocation represents a single allocation data point.
  93. type Allocation struct {
  94. Name string `json:"name"` // Allocation key (namespace, cluster, etc.)
  95. CPUCost float64 `json:"cpuCost"` // Cost of CPU usage
  96. GPUCost float64 `json:"gpuCost"` // Cost of GPU usage
  97. RAMCost float64 `json:"ramCost"` // Cost of memory usage
  98. PVCost float64 `json:"pvCost"` // Cost of persistent volumes
  99. NetworkCost float64 `json:"networkCost"` // Cost of network usage
  100. SharedCost float64 `json:"sharedCost"` // Shared/unallocated costs assigned here
  101. ExternalCost float64 `json:"externalCost"` // External costs (cloud services, etc.)
  102. TotalCost float64 `json:"totalCost"` // Sum of all costs above
  103. CPUCoreHours float64 `json:"cpuCoreHours"` // Usage metrics: CPU core-hours
  104. RAMByteHours float64 `json:"ramByteHours"` // Usage metrics: RAM byte-hours
  105. GPUHours float64 `json:"gpuHours"` // Usage metrics: GPU-hours
  106. PVByteHours float64 `json:"pvByteHours"` // Usage metrics: PV byte-hours
  107. Start time.Time `json:"start"` // Start timestamp for this allocation
  108. End time.Time `json:"end"` // End timestamp for this allocation
  109. }
  110. // AssetResponse represents the asset data returned to the AI agent.
  111. type AssetResponse struct {
  112. // The asset data, as a map of asset sets.
  113. Assets map[string]*AssetSet `json:"assets"`
  114. }
  115. // AssetSet represents a set of asset data.
  116. type AssetSet struct {
  117. // The name of the asset set.
  118. Name string `json:"name"`
  119. // The asset data for the set.
  120. Assets []*Asset `json:"assets"`
  121. }
  122. // Asset represents a single asset data point.
  123. type Asset struct {
  124. Type string `json:"type"`
  125. Properties AssetProperties `json:"properties"`
  126. Labels map[string]string `json:"labels,omitempty"`
  127. Start time.Time `json:"start"`
  128. End time.Time `json:"end"`
  129. Minutes float64 `json:"minutes"`
  130. Adjustment float64 `json:"adjustment"`
  131. TotalCost float64 `json:"totalCost"`
  132. // Disk-specific fields
  133. ByteHours float64 `json:"byteHours,omitempty"`
  134. ByteHoursUsed *float64 `json:"byteHoursUsed,omitempty"`
  135. ByteUsageMax *float64 `json:"byteUsageMax,omitempty"`
  136. StorageClass string `json:"storageClass,omitempty"`
  137. VolumeName string `json:"volumeName,omitempty"`
  138. ClaimName string `json:"claimName,omitempty"`
  139. ClaimNamespace string `json:"claimNamespace,omitempty"`
  140. Local float64 `json:"local,omitempty"`
  141. // Node-specific fields
  142. NodeType string `json:"nodeType,omitempty"`
  143. CPUCoreHours float64 `json:"cpuCoreHours,omitempty"`
  144. RAMByteHours float64 `json:"ramByteHours,omitempty"`
  145. GPUHours float64 `json:"gpuHours,omitempty"`
  146. GPUCount float64 `json:"gpuCount,omitempty"`
  147. CPUCost float64 `json:"cpuCost,omitempty"`
  148. GPUCost float64 `json:"gpuCost,omitempty"`
  149. RAMCost float64 `json:"ramCost,omitempty"`
  150. Discount float64 `json:"discount,omitempty"`
  151. Preemptible float64 `json:"preemptible,omitempty"`
  152. // Breakdown fields (can be used for different types)
  153. Breakdown *AssetBreakdown `json:"breakdown,omitempty"`
  154. CPUBreakdown *AssetBreakdown `json:"cpuBreakdown,omitempty"`
  155. RAMBreakdown *AssetBreakdown `json:"ramBreakdown,omitempty"`
  156. // Overhead (Node-specific)
  157. Overhead *NodeOverhead `json:"overhead,omitempty"`
  158. }
  159. // NodeOverhead represents node overhead information
  160. type NodeOverhead struct {
  161. RamOverheadFraction float64 `json:"ramOverheadFraction"`
  162. CpuOverheadFraction float64 `json:"cpuOverheadFraction"`
  163. OverheadCostFraction float64 `json:"overheadCostFraction"`
  164. }
  165. type AssetProperties struct {
  166. Category string `json:"category,omitempty"`
  167. Provider string `json:"provider,omitempty"`
  168. Account string `json:"account,omitempty"`
  169. Project string `json:"project,omitempty"`
  170. Service string `json:"service,omitempty"`
  171. Cluster string `json:"cluster,omitempty"`
  172. Name string `json:"name,omitempty"`
  173. ProviderID string `json:"providerID,omitempty"`
  174. }
  175. type AssetBreakdown struct {
  176. Idle float64 `json:"idle"`
  177. Other float64 `json:"other"`
  178. System float64 `json:"system"`
  179. User float64 `json:"user"`
  180. }
  181. // CloudCostResponse represents the cloud cost data returned to the AI agent.
  182. type CloudCostResponse struct {
  183. // The cloud cost data, as a map of cloud cost sets.
  184. CloudCosts map[string]*CloudCostSet `json:"cloudCosts"`
  185. // Summary information
  186. Summary *CloudCostSummary `json:"summary,omitempty"`
  187. }
  188. // CloudCostSummary provides summary information about cloud costs
  189. type CloudCostSummary struct {
  190. TotalNetCost float64 `json:"totalNetCost"`
  191. TotalAmortizedCost float64 `json:"totalAmortizedCost"`
  192. TotalInvoicedCost float64 `json:"totalInvoicedCost"`
  193. KubernetesPercent float64 `json:"kubernetesPercent"`
  194. ProviderBreakdown map[string]float64 `json:"providerBreakdown,omitempty"`
  195. ServiceBreakdown map[string]float64 `json:"serviceBreakdown,omitempty"`
  196. RegionBreakdown map[string]float64 `json:"regionBreakdown,omitempty"`
  197. }
  198. // CloudCostSet represents a set of cloud cost data.
  199. type CloudCostSet struct {
  200. // The name of the cloud cost set.
  201. Name string `json:"name"`
  202. // The cloud cost data for the set.
  203. CloudCosts []*CloudCost `json:"cloudCosts"`
  204. // Aggregation information
  205. AggregationProperties []string `json:"aggregationProperties,omitempty"`
  206. // Time window
  207. Window *TimeWindow `json:"window,omitempty"`
  208. }
  209. // TimeWindow represents a time range
  210. type TimeWindow struct {
  211. Start time.Time `json:"start"`
  212. End time.Time `json:"end"`
  213. }
  214. // CloudCostProperties defines the properties of a cloud cost item.
  215. type CloudCostProperties struct {
  216. ProviderID string `json:"providerID,omitempty"`
  217. Provider string `json:"provider,omitempty"`
  218. AccountID string `json:"accountID,omitempty"`
  219. AccountName string `json:"accountName,omitempty"`
  220. InvoiceEntityID string `json:"invoiceEntityID,omitempty"`
  221. InvoiceEntityName string `json:"invoiceEntityName,omitempty"`
  222. RegionID string `json:"regionID,omitempty"`
  223. AvailabilityZone string `json:"availabilityZone,omitempty"`
  224. Service string `json:"service,omitempty"`
  225. Category string `json:"category,omitempty"`
  226. Labels map[string]string `json:"labels,omitempty"`
  227. }
  228. // CloudCost represents a single cloud cost data point.
  229. type CloudCost struct {
  230. Properties CloudCostProperties `json:"properties"`
  231. Window TimeWindow `json:"window"`
  232. ListCost CostMetric `json:"listCost"`
  233. NetCost CostMetric `json:"netCost"`
  234. AmortizedNetCost CostMetric `json:"amortizedNetCost"`
  235. InvoicedCost CostMetric `json:"invoicedCost"`
  236. AmortizedCost CostMetric `json:"amortizedCost"`
  237. }
  238. // CostMetric represents a cost value with Kubernetes percentage
  239. type CostMetric struct {
  240. Cost float64 `json:"cost"`
  241. KubernetesPercent float64 `json:"kubernetesPercent"`
  242. }
  243. // MCPServer holds the dependencies for the MCP API server.
  244. type MCPServer struct {
  245. costModel *costmodel.CostModel
  246. provider models.Provider
  247. integration cloudcost.CloudCostIntegration
  248. }