foundry-mcp 0.8.22__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.

Potentially problematic release.


This version of foundry-mcp might be problematic. Click here for more details.

Files changed (153) hide show
  1. foundry_mcp/__init__.py +13 -0
  2. foundry_mcp/cli/__init__.py +67 -0
  3. foundry_mcp/cli/__main__.py +9 -0
  4. foundry_mcp/cli/agent.py +96 -0
  5. foundry_mcp/cli/commands/__init__.py +37 -0
  6. foundry_mcp/cli/commands/cache.py +137 -0
  7. foundry_mcp/cli/commands/dashboard.py +148 -0
  8. foundry_mcp/cli/commands/dev.py +446 -0
  9. foundry_mcp/cli/commands/journal.py +377 -0
  10. foundry_mcp/cli/commands/lifecycle.py +274 -0
  11. foundry_mcp/cli/commands/modify.py +824 -0
  12. foundry_mcp/cli/commands/plan.py +640 -0
  13. foundry_mcp/cli/commands/pr.py +393 -0
  14. foundry_mcp/cli/commands/review.py +667 -0
  15. foundry_mcp/cli/commands/session.py +472 -0
  16. foundry_mcp/cli/commands/specs.py +686 -0
  17. foundry_mcp/cli/commands/tasks.py +807 -0
  18. foundry_mcp/cli/commands/testing.py +676 -0
  19. foundry_mcp/cli/commands/validate.py +982 -0
  20. foundry_mcp/cli/config.py +98 -0
  21. foundry_mcp/cli/context.py +298 -0
  22. foundry_mcp/cli/logging.py +212 -0
  23. foundry_mcp/cli/main.py +44 -0
  24. foundry_mcp/cli/output.py +122 -0
  25. foundry_mcp/cli/registry.py +110 -0
  26. foundry_mcp/cli/resilience.py +178 -0
  27. foundry_mcp/cli/transcript.py +217 -0
  28. foundry_mcp/config.py +1454 -0
  29. foundry_mcp/core/__init__.py +144 -0
  30. foundry_mcp/core/ai_consultation.py +1773 -0
  31. foundry_mcp/core/batch_operations.py +1202 -0
  32. foundry_mcp/core/cache.py +195 -0
  33. foundry_mcp/core/capabilities.py +446 -0
  34. foundry_mcp/core/concurrency.py +898 -0
  35. foundry_mcp/core/context.py +540 -0
  36. foundry_mcp/core/discovery.py +1603 -0
  37. foundry_mcp/core/error_collection.py +728 -0
  38. foundry_mcp/core/error_store.py +592 -0
  39. foundry_mcp/core/health.py +749 -0
  40. foundry_mcp/core/intake.py +933 -0
  41. foundry_mcp/core/journal.py +700 -0
  42. foundry_mcp/core/lifecycle.py +412 -0
  43. foundry_mcp/core/llm_config.py +1376 -0
  44. foundry_mcp/core/llm_patterns.py +510 -0
  45. foundry_mcp/core/llm_provider.py +1569 -0
  46. foundry_mcp/core/logging_config.py +374 -0
  47. foundry_mcp/core/metrics_persistence.py +584 -0
  48. foundry_mcp/core/metrics_registry.py +327 -0
  49. foundry_mcp/core/metrics_store.py +641 -0
  50. foundry_mcp/core/modifications.py +224 -0
  51. foundry_mcp/core/naming.py +146 -0
  52. foundry_mcp/core/observability.py +1216 -0
  53. foundry_mcp/core/otel.py +452 -0
  54. foundry_mcp/core/otel_stubs.py +264 -0
  55. foundry_mcp/core/pagination.py +255 -0
  56. foundry_mcp/core/progress.py +387 -0
  57. foundry_mcp/core/prometheus.py +564 -0
  58. foundry_mcp/core/prompts/__init__.py +464 -0
  59. foundry_mcp/core/prompts/fidelity_review.py +691 -0
  60. foundry_mcp/core/prompts/markdown_plan_review.py +515 -0
  61. foundry_mcp/core/prompts/plan_review.py +627 -0
  62. foundry_mcp/core/providers/__init__.py +237 -0
  63. foundry_mcp/core/providers/base.py +515 -0
  64. foundry_mcp/core/providers/claude.py +472 -0
  65. foundry_mcp/core/providers/codex.py +637 -0
  66. foundry_mcp/core/providers/cursor_agent.py +630 -0
  67. foundry_mcp/core/providers/detectors.py +515 -0
  68. foundry_mcp/core/providers/gemini.py +426 -0
  69. foundry_mcp/core/providers/opencode.py +718 -0
  70. foundry_mcp/core/providers/opencode_wrapper.js +308 -0
  71. foundry_mcp/core/providers/package-lock.json +24 -0
  72. foundry_mcp/core/providers/package.json +25 -0
  73. foundry_mcp/core/providers/registry.py +607 -0
  74. foundry_mcp/core/providers/test_provider.py +171 -0
  75. foundry_mcp/core/providers/validation.py +857 -0
  76. foundry_mcp/core/rate_limit.py +427 -0
  77. foundry_mcp/core/research/__init__.py +68 -0
  78. foundry_mcp/core/research/memory.py +528 -0
  79. foundry_mcp/core/research/models.py +1234 -0
  80. foundry_mcp/core/research/providers/__init__.py +40 -0
  81. foundry_mcp/core/research/providers/base.py +242 -0
  82. foundry_mcp/core/research/providers/google.py +507 -0
  83. foundry_mcp/core/research/providers/perplexity.py +442 -0
  84. foundry_mcp/core/research/providers/semantic_scholar.py +544 -0
  85. foundry_mcp/core/research/providers/tavily.py +383 -0
  86. foundry_mcp/core/research/workflows/__init__.py +25 -0
  87. foundry_mcp/core/research/workflows/base.py +298 -0
  88. foundry_mcp/core/research/workflows/chat.py +271 -0
  89. foundry_mcp/core/research/workflows/consensus.py +539 -0
  90. foundry_mcp/core/research/workflows/deep_research.py +4142 -0
  91. foundry_mcp/core/research/workflows/ideate.py +682 -0
  92. foundry_mcp/core/research/workflows/thinkdeep.py +405 -0
  93. foundry_mcp/core/resilience.py +600 -0
  94. foundry_mcp/core/responses.py +1624 -0
  95. foundry_mcp/core/review.py +366 -0
  96. foundry_mcp/core/security.py +438 -0
  97. foundry_mcp/core/spec.py +4119 -0
  98. foundry_mcp/core/task.py +2463 -0
  99. foundry_mcp/core/testing.py +839 -0
  100. foundry_mcp/core/validation.py +2357 -0
  101. foundry_mcp/dashboard/__init__.py +32 -0
  102. foundry_mcp/dashboard/app.py +119 -0
  103. foundry_mcp/dashboard/components/__init__.py +17 -0
  104. foundry_mcp/dashboard/components/cards.py +88 -0
  105. foundry_mcp/dashboard/components/charts.py +177 -0
  106. foundry_mcp/dashboard/components/filters.py +136 -0
  107. foundry_mcp/dashboard/components/tables.py +195 -0
  108. foundry_mcp/dashboard/data/__init__.py +11 -0
  109. foundry_mcp/dashboard/data/stores.py +433 -0
  110. foundry_mcp/dashboard/launcher.py +300 -0
  111. foundry_mcp/dashboard/views/__init__.py +12 -0
  112. foundry_mcp/dashboard/views/errors.py +217 -0
  113. foundry_mcp/dashboard/views/metrics.py +164 -0
  114. foundry_mcp/dashboard/views/overview.py +96 -0
  115. foundry_mcp/dashboard/views/providers.py +83 -0
  116. foundry_mcp/dashboard/views/sdd_workflow.py +255 -0
  117. foundry_mcp/dashboard/views/tool_usage.py +139 -0
  118. foundry_mcp/prompts/__init__.py +9 -0
  119. foundry_mcp/prompts/workflows.py +525 -0
  120. foundry_mcp/resources/__init__.py +9 -0
  121. foundry_mcp/resources/specs.py +591 -0
  122. foundry_mcp/schemas/__init__.py +38 -0
  123. foundry_mcp/schemas/intake-schema.json +89 -0
  124. foundry_mcp/schemas/sdd-spec-schema.json +414 -0
  125. foundry_mcp/server.py +150 -0
  126. foundry_mcp/tools/__init__.py +10 -0
  127. foundry_mcp/tools/unified/__init__.py +92 -0
  128. foundry_mcp/tools/unified/authoring.py +3620 -0
  129. foundry_mcp/tools/unified/context_helpers.py +98 -0
  130. foundry_mcp/tools/unified/documentation_helpers.py +268 -0
  131. foundry_mcp/tools/unified/environment.py +1341 -0
  132. foundry_mcp/tools/unified/error.py +479 -0
  133. foundry_mcp/tools/unified/health.py +225 -0
  134. foundry_mcp/tools/unified/journal.py +841 -0
  135. foundry_mcp/tools/unified/lifecycle.py +640 -0
  136. foundry_mcp/tools/unified/metrics.py +777 -0
  137. foundry_mcp/tools/unified/plan.py +876 -0
  138. foundry_mcp/tools/unified/pr.py +294 -0
  139. foundry_mcp/tools/unified/provider.py +589 -0
  140. foundry_mcp/tools/unified/research.py +1283 -0
  141. foundry_mcp/tools/unified/review.py +1042 -0
  142. foundry_mcp/tools/unified/review_helpers.py +314 -0
  143. foundry_mcp/tools/unified/router.py +102 -0
  144. foundry_mcp/tools/unified/server.py +565 -0
  145. foundry_mcp/tools/unified/spec.py +1283 -0
  146. foundry_mcp/tools/unified/task.py +3846 -0
  147. foundry_mcp/tools/unified/test.py +431 -0
  148. foundry_mcp/tools/unified/verification.py +520 -0
  149. foundry_mcp-0.8.22.dist-info/METADATA +344 -0
  150. foundry_mcp-0.8.22.dist-info/RECORD +153 -0
  151. foundry_mcp-0.8.22.dist-info/WHEEL +4 -0
  152. foundry_mcp-0.8.22.dist-info/entry_points.txt +3 -0
  153. foundry_mcp-0.8.22.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,327 @@
1
+ """Metrics registry for foundry-mcp observability stack.
2
+
3
+ This module provides a centralized catalog of all metrics emitted by foundry-mcp,
4
+ including their definitions, types, labels, and documentation. Use this for:
5
+ - Consistent metric naming across the codebase
6
+ - Automatic documentation generation
7
+ - Metric discovery and introspection
8
+
9
+ Usage:
10
+ from foundry_mcp.core.metrics_registry import (
11
+ get_metrics_catalog,
12
+ get_metrics_by_category,
13
+ MetricCategory,
14
+ )
15
+
16
+ # Get all metrics
17
+ catalog = get_metrics_catalog()
18
+
19
+ # Get tool-related metrics
20
+ tool_metrics = get_metrics_by_category(MetricCategory.TOOL)
21
+
22
+ # Generate markdown documentation
23
+ docs = export_catalog_as_markdown()
24
+ """
25
+
26
+ from dataclasses import dataclass, field
27
+ from enum import Enum
28
+ from typing import Dict, List, Optional
29
+
30
+
31
+ class MetricCategory(Enum):
32
+ """Categories for grouping related metrics."""
33
+
34
+ TOOL = "tool"
35
+ RESOURCE = "resource"
36
+ AUDIT = "audit"
37
+ ERROR = "error"
38
+ SYSTEM = "system"
39
+ PERFORMANCE = "performance"
40
+ CLI = "cli"
41
+
42
+
43
+ class MetricType(Enum):
44
+ """Types of metrics supported."""
45
+
46
+ COUNTER = "counter"
47
+ GAUGE = "gauge"
48
+ HISTOGRAM = "histogram"
49
+ SUMMARY = "summary"
50
+
51
+
52
+ @dataclass
53
+ class MetricDefinition:
54
+ """Definition of a metric including its metadata.
55
+
56
+ Attributes:
57
+ name: Full metric name (e.g., "foundry_mcp_tool_invocations_total")
58
+ description: Human-readable description
59
+ metric_type: Type of metric (counter, gauge, histogram, summary)
60
+ category: Category for grouping
61
+ labels: List of label names
62
+ unit: Unit of measurement (optional)
63
+ examples: Example label values for documentation
64
+ """
65
+
66
+ name: str
67
+ description: str
68
+ metric_type: MetricType
69
+ category: MetricCategory
70
+ labels: List[str] = field(default_factory=list)
71
+ unit: Optional[str] = None
72
+ examples: Dict[str, str] = field(default_factory=dict)
73
+
74
+ def full_name(self, namespace: str = "foundry_mcp") -> str:
75
+ """Get full metric name with namespace prefix."""
76
+ return f"{namespace}_{self.name}"
77
+
78
+
79
+ # =============================================================================
80
+ # Metrics Catalog
81
+ # =============================================================================
82
+
83
+ METRICS_CATALOG: Dict[str, MetricDefinition] = {
84
+ # Tool metrics
85
+ "tool_invocations_total": MetricDefinition(
86
+ name="tool_invocations_total",
87
+ description="Total number of tool invocations",
88
+ metric_type=MetricType.COUNTER,
89
+ category=MetricCategory.TOOL,
90
+ labels=["tool", "status"],
91
+ examples={"tool": "list_specs", "status": "success"},
92
+ ),
93
+ "tool_duration_seconds": MetricDefinition(
94
+ name="tool_duration_seconds",
95
+ description="Tool execution duration in seconds",
96
+ metric_type=MetricType.HISTOGRAM,
97
+ category=MetricCategory.TOOL,
98
+ labels=["tool"],
99
+ unit="seconds",
100
+ examples={"tool": "task_complete"},
101
+ ),
102
+ "tool_errors_total": MetricDefinition(
103
+ name="tool_errors_total",
104
+ description="Total number of tool errors",
105
+ metric_type=MetricType.COUNTER,
106
+ category=MetricCategory.TOOL,
107
+ labels=["tool", "error_type"],
108
+ examples={"tool": "spec", "error_type": "NotFoundError"},
109
+ ),
110
+ "active_operations": MetricDefinition(
111
+ name="active_operations",
112
+ description="Number of currently active operations",
113
+ metric_type=MetricType.GAUGE,
114
+ category=MetricCategory.TOOL,
115
+ labels=["operation_type"],
116
+ examples={"operation_type": "tool:list"},
117
+ ),
118
+ # Resource metrics
119
+ "resource_access_total": MetricDefinition(
120
+ name="resource_access_total",
121
+ description="Total number of resource accesses",
122
+ metric_type=MetricType.COUNTER,
123
+ category=MetricCategory.RESOURCE,
124
+ labels=["resource_type", "action"],
125
+ examples={"resource_type": "spec", "action": "read"},
126
+ ),
127
+ "resource_latency_seconds": MetricDefinition(
128
+ name="resource_latency_seconds",
129
+ description="Resource access latency in seconds",
130
+ metric_type=MetricType.HISTOGRAM,
131
+ category=MetricCategory.RESOURCE,
132
+ labels=["resource_type"],
133
+ unit="seconds",
134
+ examples={"resource_type": "journal"},
135
+ ),
136
+ # Error metrics
137
+ "errors_total": MetricDefinition(
138
+ name="errors_total",
139
+ description="Total number of errors by type",
140
+ metric_type=MetricType.COUNTER,
141
+ category=MetricCategory.ERROR,
142
+ labels=["error_type", "component"],
143
+ examples={"error_type": "ValidationError", "component": "spec"},
144
+ ),
145
+ # System metrics
146
+ "info": MetricDefinition(
147
+ name="info",
148
+ description="Server information gauge (always 1)",
149
+ metric_type=MetricType.GAUGE,
150
+ category=MetricCategory.SYSTEM,
151
+ labels=["version", "python_version"],
152
+ examples={"version": "0.2.0", "python_version": "3.11"},
153
+ ),
154
+ "startup_time_seconds": MetricDefinition(
155
+ name="startup_time_seconds",
156
+ description="Server startup time in seconds",
157
+ metric_type=MetricType.GAUGE,
158
+ category=MetricCategory.SYSTEM,
159
+ unit="seconds",
160
+ ),
161
+ # CLI metrics
162
+ "cli_command_invocations_total": MetricDefinition(
163
+ name="cli_command_invocations_total",
164
+ description="Total CLI command invocations",
165
+ metric_type=MetricType.COUNTER,
166
+ category=MetricCategory.CLI,
167
+ labels=["command", "status"],
168
+ examples={"command": "validate", "status": "success"},
169
+ ),
170
+ "cli_command_duration_seconds": MetricDefinition(
171
+ name="cli_command_duration_seconds",
172
+ description="CLI command execution duration in seconds",
173
+ metric_type=MetricType.HISTOGRAM,
174
+ category=MetricCategory.CLI,
175
+ labels=["command"],
176
+ unit="seconds",
177
+ examples={"command": "test"},
178
+ ),
179
+ # Performance metrics
180
+ "spec_validation_duration_seconds": MetricDefinition(
181
+ name="spec_validation_duration_seconds",
182
+ description="Spec validation duration in seconds",
183
+ metric_type=MetricType.HISTOGRAM,
184
+ category=MetricCategory.PERFORMANCE,
185
+ labels=["spec_id"],
186
+ unit="seconds",
187
+ ),
188
+ "ai_consultation_duration_seconds": MetricDefinition(
189
+ name="ai_consultation_duration_seconds",
190
+ description="AI consultation request duration in seconds",
191
+ metric_type=MetricType.HISTOGRAM,
192
+ category=MetricCategory.PERFORMANCE,
193
+ labels=["provider", "workflow"],
194
+ unit="seconds",
195
+ examples={"provider": "gemini", "workflow": "fidelity_review"},
196
+ ),
197
+ "ai_consultation_tokens_total": MetricDefinition(
198
+ name="ai_consultation_tokens_total",
199
+ description="Total tokens used in AI consultations",
200
+ metric_type=MetricType.COUNTER,
201
+ category=MetricCategory.PERFORMANCE,
202
+ labels=["provider", "token_type"],
203
+ examples={"provider": "openai", "token_type": "completion"},
204
+ ),
205
+ # Audit metrics
206
+ "audit_events_total": MetricDefinition(
207
+ name="audit_events_total",
208
+ description="Total audit events by type",
209
+ metric_type=MetricType.COUNTER,
210
+ category=MetricCategory.AUDIT,
211
+ labels=["event_type"],
212
+ examples={"event_type": "tool_invocation"},
213
+ ),
214
+ }
215
+
216
+
217
+ # =============================================================================
218
+ # Public API
219
+ # =============================================================================
220
+
221
+
222
+ def get_metrics_catalog() -> Dict[str, MetricDefinition]:
223
+ """Get the full metrics catalog.
224
+
225
+ Returns:
226
+ Dict mapping metric names to their definitions
227
+ """
228
+ return METRICS_CATALOG.copy()
229
+
230
+
231
+ def get_metrics_by_category(category: MetricCategory) -> Dict[str, MetricDefinition]:
232
+ """Get metrics filtered by category.
233
+
234
+ Args:
235
+ category: Category to filter by
236
+
237
+ Returns:
238
+ Dict of metrics in the specified category
239
+ """
240
+ return {
241
+ name: defn
242
+ for name, defn in METRICS_CATALOG.items()
243
+ if defn.category == category
244
+ }
245
+
246
+
247
+ def get_metric(name: str) -> Optional[MetricDefinition]:
248
+ """Get a specific metric definition by name.
249
+
250
+ Args:
251
+ name: Metric name (without namespace prefix)
252
+
253
+ Returns:
254
+ MetricDefinition if found, None otherwise
255
+ """
256
+ return METRICS_CATALOG.get(name)
257
+
258
+
259
+ def export_catalog_as_markdown(namespace: str = "foundry_mcp") -> str:
260
+ """Export the metrics catalog as Markdown documentation.
261
+
262
+ Args:
263
+ namespace: Namespace prefix for full metric names
264
+
265
+ Returns:
266
+ Markdown-formatted documentation string
267
+ """
268
+ lines = [
269
+ "# Foundry MCP Metrics Catalog",
270
+ "",
271
+ "This document lists all metrics emitted by foundry-mcp.",
272
+ "",
273
+ ]
274
+
275
+ # Group by category
276
+ for category in MetricCategory:
277
+ category_metrics = get_metrics_by_category(category)
278
+ if not category_metrics:
279
+ continue
280
+
281
+ lines.append(f"## {category.value.title()} Metrics")
282
+ lines.append("")
283
+
284
+ for name, defn in sorted(category_metrics.items()):
285
+ full_name = defn.full_name(namespace)
286
+ lines.append(f"### `{full_name}`")
287
+ lines.append("")
288
+ lines.append(f"**Type:** {defn.metric_type.value}")
289
+ lines.append("")
290
+ lines.append(defn.description)
291
+ lines.append("")
292
+
293
+ if defn.unit:
294
+ lines.append(f"**Unit:** {defn.unit}")
295
+ lines.append("")
296
+
297
+ if defn.labels:
298
+ lines.append("**Labels:**")
299
+ for label in defn.labels:
300
+ example = defn.examples.get(label, "")
301
+ if example:
302
+ lines.append(f"- `{label}` (e.g., `{example}`)")
303
+ else:
304
+ lines.append(f"- `{label}`")
305
+ lines.append("")
306
+
307
+ return "\n".join(lines)
308
+
309
+
310
+ # =============================================================================
311
+ # Exports
312
+ # =============================================================================
313
+
314
+ __all__ = [
315
+ # Enums
316
+ "MetricCategory",
317
+ "MetricType",
318
+ # Types
319
+ "MetricDefinition",
320
+ # Data
321
+ "METRICS_CATALOG",
322
+ # Functions
323
+ "get_metrics_catalog",
324
+ "get_metrics_by_category",
325
+ "get_metric",
326
+ "export_catalog_as_markdown",
327
+ ]