foundry-mcp 0.7.0__py3-none-any.whl → 0.8.10__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.
Files changed (54) hide show
  1. foundry_mcp/cli/__init__.py +0 -13
  2. foundry_mcp/cli/commands/session.py +1 -8
  3. foundry_mcp/cli/context.py +39 -0
  4. foundry_mcp/config.py +381 -7
  5. foundry_mcp/core/batch_operations.py +1196 -0
  6. foundry_mcp/core/discovery.py +1 -1
  7. foundry_mcp/core/llm_config.py +8 -0
  8. foundry_mcp/core/naming.py +25 -2
  9. foundry_mcp/core/prometheus.py +0 -13
  10. foundry_mcp/core/providers/__init__.py +12 -0
  11. foundry_mcp/core/providers/base.py +39 -0
  12. foundry_mcp/core/providers/claude.py +45 -1
  13. foundry_mcp/core/providers/codex.py +64 -3
  14. foundry_mcp/core/providers/cursor_agent.py +22 -3
  15. foundry_mcp/core/providers/detectors.py +34 -7
  16. foundry_mcp/core/providers/gemini.py +63 -1
  17. foundry_mcp/core/providers/opencode.py +95 -71
  18. foundry_mcp/core/providers/package-lock.json +4 -4
  19. foundry_mcp/core/providers/package.json +1 -1
  20. foundry_mcp/core/providers/validation.py +128 -0
  21. foundry_mcp/core/research/memory.py +103 -0
  22. foundry_mcp/core/research/models.py +783 -0
  23. foundry_mcp/core/research/providers/__init__.py +40 -0
  24. foundry_mcp/core/research/providers/base.py +242 -0
  25. foundry_mcp/core/research/providers/google.py +507 -0
  26. foundry_mcp/core/research/providers/perplexity.py +442 -0
  27. foundry_mcp/core/research/providers/semantic_scholar.py +544 -0
  28. foundry_mcp/core/research/providers/tavily.py +383 -0
  29. foundry_mcp/core/research/workflows/__init__.py +5 -2
  30. foundry_mcp/core/research/workflows/base.py +106 -12
  31. foundry_mcp/core/research/workflows/consensus.py +160 -17
  32. foundry_mcp/core/research/workflows/deep_research.py +4020 -0
  33. foundry_mcp/core/responses.py +240 -0
  34. foundry_mcp/core/spec.py +1 -0
  35. foundry_mcp/core/task.py +141 -12
  36. foundry_mcp/core/validation.py +6 -1
  37. foundry_mcp/server.py +0 -52
  38. foundry_mcp/tools/unified/__init__.py +37 -18
  39. foundry_mcp/tools/unified/authoring.py +0 -33
  40. foundry_mcp/tools/unified/environment.py +202 -29
  41. foundry_mcp/tools/unified/plan.py +20 -1
  42. foundry_mcp/tools/unified/provider.py +0 -40
  43. foundry_mcp/tools/unified/research.py +644 -19
  44. foundry_mcp/tools/unified/review.py +5 -2
  45. foundry_mcp/tools/unified/review_helpers.py +16 -1
  46. foundry_mcp/tools/unified/server.py +9 -24
  47. foundry_mcp/tools/unified/task.py +528 -9
  48. {foundry_mcp-0.7.0.dist-info → foundry_mcp-0.8.10.dist-info}/METADATA +2 -1
  49. {foundry_mcp-0.7.0.dist-info → foundry_mcp-0.8.10.dist-info}/RECORD +52 -46
  50. foundry_mcp/cli/flags.py +0 -266
  51. foundry_mcp/core/feature_flags.py +0 -592
  52. {foundry_mcp-0.7.0.dist-info → foundry_mcp-0.8.10.dist-info}/WHEEL +0 -0
  53. {foundry_mcp-0.7.0.dist-info → foundry_mcp-0.8.10.dist-info}/entry_points.txt +0 -0
  54. {foundry_mcp-0.7.0.dist-info → foundry_mcp-0.8.10.dist-info}/licenses/LICENSE +0 -0
@@ -27,7 +27,7 @@ from foundry_mcp.core.ai_consultation import (
27
27
  from foundry_mcp.core.prompts.fidelity_review import (
28
28
  FIDELITY_SYNTHESIZED_RESPONSE_SCHEMA,
29
29
  )
30
- from foundry_mcp.core.llm_config import get_consultation_config
30
+ from foundry_mcp.core.llm_config import get_consultation_config, load_consultation_config
31
31
  from foundry_mcp.core.naming import canonical_tool
32
32
  from foundry_mcp.core.observability import get_metrics, mcp_tool
33
33
  from foundry_mcp.core.providers import get_provider_statuses
@@ -703,7 +703,10 @@ def _handle_fidelity(*, config: ServerConfig, payload: Dict[str, Any]) -> dict:
703
703
  preferred_providers = ai_tools if isinstance(ai_tools, list) else []
704
704
  first_provider = preferred_providers[0] if preferred_providers else None
705
705
 
706
- orchestrator = ConsultationOrchestrator()
706
+ # Load consultation config from workspace path to get provider priority list
707
+ config_file = ws_path / "foundry-mcp.toml"
708
+ consultation_config = load_consultation_config(config_file=config_file)
709
+ orchestrator = ConsultationOrchestrator(config=consultation_config)
707
710
  if not orchestrator.is_available(provider_id=first_provider):
708
711
  return asdict(
709
712
  error_response(
@@ -193,6 +193,7 @@ def _run_ai_review(
193
193
  ConsultationRequest,
194
194
  ConsultationWorkflow,
195
195
  )
196
+ from foundry_mcp.core.llm_config import load_consultation_config
196
197
  except ImportError:
197
198
  return asdict(
198
199
  error_response(
@@ -203,7 +204,21 @@ def _run_ai_review(
203
204
  )
204
205
  )
205
206
 
206
- orchestrator = ConsultationOrchestrator(default_timeout=ai_timeout)
207
+ # Load consultation config from workspace (fixes config discovery issue)
208
+ # Derive workspace from specs_dir - check parent directories for config
209
+ config_file = None
210
+ if specs_dir:
211
+ ws_path = specs_dir.parent if specs_dir.name == "specs" else specs_dir
212
+ for _ in range(5): # Search up to 5 levels for foundry-mcp.toml
213
+ candidate = ws_path / "foundry-mcp.toml"
214
+ if candidate.exists():
215
+ config_file = candidate
216
+ break
217
+ if ws_path.parent == ws_path: # Reached root
218
+ break
219
+ ws_path = ws_path.parent
220
+ consultation_config = load_consultation_config(config_file=config_file)
221
+ orchestrator = ConsultationOrchestrator(config=consultation_config, default_timeout=ai_timeout)
207
222
 
208
223
  if not orchestrator.is_available(provider_id=ai_provider):
209
224
  return asdict(
@@ -18,7 +18,6 @@ from mcp.server.fastmcp import FastMCP
18
18
  from foundry_mcp.config import ServerConfig
19
19
  from foundry_mcp.core.context import generate_correlation_id, get_correlation_id
20
20
  from foundry_mcp.core.discovery import get_capabilities, get_tool_registry
21
- from foundry_mcp.core.feature_flags import get_flag_service
22
21
  from foundry_mcp.core.naming import canonical_tool
23
22
  from foundry_mcp.core.observability import (
24
23
  get_metrics,
@@ -256,26 +255,15 @@ def _handle_tools(*, config: ServerConfig, payload: Dict[str, Any]) -> dict:
256
255
 
257
256
  start_time = time.perf_counter()
258
257
 
259
- categories_list: list[str]
260
- flag_service = get_flag_service()
261
- if flag_service.is_enabled("unified_manifest"):
262
- all_tools = _build_unified_manifest_tools()
263
- if category:
264
- all_tools = [tool for tool in all_tools if tool.get("category") == category]
265
- if tag:
266
- all_tools = [tool for tool in all_tools if tag in (tool.get("tags") or [])]
267
- categories_list = sorted(
268
- {tool.get("category", "general") for tool in all_tools}
269
- )
270
- else:
271
- registry = get_tool_registry()
272
- all_tools = registry.list_tools(
273
- category=category,
274
- tag=tag,
275
- include_deprecated=include_deprecated,
276
- )
277
- categories = registry.list_categories()
278
- categories_list = [c["name"] for c in categories]
258
+ # Always use unified manifest (feature flags removed)
259
+ all_tools = _build_unified_manifest_tools()
260
+ if category:
261
+ all_tools = [tool for tool in all_tools if tool.get("category") == category]
262
+ if tag:
263
+ all_tools = [tool for tool in all_tools if tag in (tool.get("tags") or [])]
264
+ categories_list = sorted(
265
+ {tool.get("category", "general") for tool in all_tools}
266
+ )
279
267
 
280
268
  start_idx = 0
281
269
  if cursor:
@@ -360,9 +348,6 @@ def _handle_tools(*, config: ServerConfig, payload: Dict[str, Any]) -> dict:
360
348
  tokens=manifest_tokens,
361
349
  tool_count=len(all_tools),
362
350
  )
363
- exporter.record_feature_flag_state(
364
- "unified_manifest", flag_service.is_enabled("unified_manifest")
365
- )
366
351
 
367
352
  response["meta"]["request_id"] = request_id
368
353
  return response