github Python re-analysis due

saagpatel/mcpforge

github

Generate production-ready FastMCP 3.x MCP servers from plain-English descriptions

maintainer
saagpatel
licence
MIT
first seen
2026-06-07
last seen
2026-09-10
releases · 30d
0
short id

Drift inferred · capture-to-capture

  1. HIGH code analysis flagged dynamic code execution in saagpatel/mcpforge
  2. HIGH code analysis flagged dynamic code execution in saagpatel/mcpforge
capabilities 10 tools
transport stdio · streamable-http · http verified reported listed in the official MCP registry counts 10 tools · 0 res · 0 prompts permission surface via code analysis

tools

  • doctor
  • echo
  • generate
  • get_current_weather
  • get_forecast
  • inspect
  • list_generated_servers
  • plan
  • update
  • validate
skills & danger signals github-tarball
code evidence vv0.3.2 · github-tarball
evidence-backed findings quoted directly from the published source artifact — not inferred

code files: 92

filesystem 36

  • fs (weak) saagpatel-mcpforge-e098392/examples/file-reader-server/server.py :5 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/examples/v03-database-server/test_server.py :73 os.unlink(db_path)
  • fs (weak) saagpatel-mcpforge-e098392/examples/v03-filesystem-server/server.py :8 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/examples/v03-filesystem-server/test_server.py :6 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/scripts/verify_safeforge_handoff.py :13 from pathlib import Path
  • fs saagpatel-mcpforge-e098392/src/mcpforge/cli.py :6 from pathlib import Path
  • fs saagpatel-mcpforge-e098392/src/mcpforge/discovery.py :6 from pathlib import Path
  • fs saagpatel-mcpforge-e098392/src/mcpforge/doctor.py :5 import shutil
  • fs saagpatel-mcpforge-e098392/src/mcpforge/forge_receipt.py :11 from pathlib import Path
  • fs saagpatel-mcpforge-e098392/src/mcpforge/inspection.py :5 from pathlib import Path
  • fs saagpatel-mcpforge-e098392/src/mcpforge/mcp_server.py :4 from pathlib import Path
  • fs saagpatel-mcpforge-e098392/src/mcpforge/openapi.py :5 from pathlib import Path
show 24 more
  • fs (weak) saagpatel-mcpforge-e098392/src/mcpforge/safeforge_fixture.py :7 from pathlib import Path
  • fs saagpatel-mcpforge-e098392/src/mcpforge/sandbox.py :10 from pathlib import Path
  • fs saagpatel-mcpforge-e098392/src/mcpforge/security.py :96 "shutil.rmtree",
  • fs saagpatel-mcpforge-e098392/src/mcpforge/template_hints.py :25 "Use pathlib.Path throughout. Return file contents as strings."
  • fs saagpatel-mcpforge-e098392/src/mcpforge/updater.py :4 from pathlib import Path
  • fs saagpatel-mcpforge-e098392/src/mcpforge/validator.py :15 from pathlib import Path
  • fs saagpatel-mcpforge-e098392/src/mcpforge/validator_ts.py :6 from pathlib import Path
  • fs saagpatel-mcpforge-e098392/src/mcpforge/writer.py :6 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_cli.py :3 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_cli_phase3.py :3 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_cli_phase4.py :4 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_demo.py :4 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_discovery.py :4 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_generated_fixtures.py :3 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_hosted_generation_smoke.py :23 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_inspection_doctor_providers.py :6 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_mcp_server.py :4 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_openapi.py :4 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_project_metadata.py :7 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_safeforge_fixture.py :7 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_sandbox.py :3 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_security.py :54 code = 'import shutil\nshutil.rmtree("/")\n'
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_template_hints.py :3 from pathlib import Path
  • fs (weak) saagpatel-mcpforge-e098392/tests/test_updater.py :4 from pathlib import Path

shell / exec 7

  • shell (weak) saagpatel-mcpforge-e098392/scripts/verify_safeforge_handoff.py :10 import subprocess
  • shell saagpatel-mcpforge-e098392/src/mcpforge/doctor.py :6 import subprocess
  • shell saagpatel-mcpforge-e098392/src/mcpforge/validator.py :14 import subprocess
  • shell (weak) saagpatel-mcpforge-e098392/tests/test_generated_fixtures.py :36 import subprocess
  • shell (weak) saagpatel-mcpforge-e098392/tests/test_inspection_doctor_providers.py :4 import subprocess
  • shell (weak) saagpatel-mcpforge-e098392/tests/test_security.py :42 code = 'import subprocess\nsubprocess.run(["ls"])\n'
  • shell (weak) saagpatel-mcpforge-e098392/tests/test_validator.py :3 import subprocess

network 16

  • net (weak) saagpatel-mcpforge-e098392/examples/slack-notifier-server/server.py :5 import httpx
  • net (weak) saagpatel-mcpforge-e098392/examples/slack-notifier-server/test_server.py :31 with patch("httpx.AsyncClient", return_value=_make_mock_client(slack_response)):
  • net (weak) saagpatel-mcpforge-e098392/examples/v03-authenticated-openapi-server/server.py :6 import httpx
  • net (weak) saagpatel-mcpforge-e098392/examples/v03-authenticated-openapi-server/test_server.py :5 import httpx
  • net (weak) saagpatel-mcpforge-e098392/examples/v03-rest-api-server/server.py :5 import httpx
  • net (weak) saagpatel-mcpforge-e098392/examples/v03-rest-api-server/test_server.py :5 import httpx
  • net (weak) saagpatel-mcpforge-e098392/examples/weather-server/server.py :5 import httpx
  • net (weak) saagpatel-mcpforge-e098392/examples/weather-server/test_server.py :32 with patch("httpx.AsyncClient", return_value=_make_mock_client(weather_data)):
  • net saagpatel-mcpforge-e098392/src/mcpforge/demo_assets/server.py :5 import httpx
  • net saagpatel-mcpforge-e098392/src/mcpforge/demo_assets/test_server.py :32 with patch("httpx.AsyncClient", return_value=_make_mock_client(weather_data)):
  • net saagpatel-mcpforge-e098392/src/mcpforge/forge_receipt.py :432 from urllib.parse import urlsplit
  • net saagpatel-mcpforge-e098392/src/mcpforge/template_hints.py :5 "This server wraps a REST API. Use async httpx.AsyncClient for all HTTP calls. "
show 4 more
  • net saagpatel-mcpforge-e098392/src/mcpforge/test_generator.py :111 """Small httpx.Response stand-in for generated OpenAPI tool tests."""
  • net (weak) saagpatel-mcpforge-e098392/tests/test_api_client_streaming.py :8 import httpx
  • net (weak) saagpatel-mcpforge-e098392/tests/test_safeforge_fixture.py :217 import httpx
  • net (weak) saagpatel-mcpforge-e098392/tests/test_security.py :80 import httpx

secrets 12

  • secrets (weak) saagpatel-mcpforge-e098392/examples/slack-notifier-server/server.py :14 token = os.environ.get("SLACK_BOT_TOKEN", "")
  • secrets (weak) saagpatel-mcpforge-e098392/examples/v03-authenticated-openapi-server/server.py :19 key = os.environ.get("HOSTED_AUTH_API_KEY")
  • secrets (weak) saagpatel-mcpforge-e098392/examples/v03-rest-api-server/server.py :16 API_TOKEN = os.environ.get("SUPPORT_API_TOKEN")
  • secrets (weak) saagpatel-mcpforge-e098392/examples/weather-server/server.py :16 api_key = os.environ.get("OPENWEATHER_API_KEY", "")
  • secrets saagpatel-mcpforge-e098392/src/mcpforge/api_client.py :74 resolved_key = api_key or os.environ.get("ANTHROPIC_API_KEY")
  • secrets saagpatel-mcpforge-e098392/src/mcpforge/demo_assets/server.py :16 api_key = os.environ.get("OPENWEATHER_API_KEY", "")
  • secrets saagpatel-mcpforge-e098392/src/mcpforge/doctor.py :84 "ok": bool(os.environ.get("ANTHROPIC_API_KEY")),
  • secrets saagpatel-mcpforge-e098392/src/mcpforge/mcp_server.py :60 if provider == "anthropic" and not os.environ.get("ANTHROPIC_API_KEY"):
  • secrets saagpatel-mcpforge-e098392/src/mcpforge/openai_client.py :20 resolved_key = api_key or os.environ.get("OPENAI_API_KEY")
  • secrets saagpatel-mcpforge-e098392/src/mcpforge/openrouter_client.py :49 resolved_key = api_key or os.environ.get("OPENROUTER_API_KEY")
  • secrets (weak) saagpatel-mcpforge-e098392/tests/test_hosted_generation_smoke.py :67 not os.environ.get("ANTHROPIC_API_KEY"),
  • secrets (weak) saagpatel-mcpforge-e098392/tests/test_mcp_server.py :50 os.environ["ANTHROPIC_API_KEY"] = "test-key"

database 2

  • db (weak) saagpatel-mcpforge-e098392/examples/v03-database-server/test_server.py :4 import sqlite3
  • db saagpatel-mcpforge-e098392/src/mcpforge/template_hints.py :50 "`import redis.asyncio as redis`. Read REDIS_URL and QUEUE_NAME from env vars. "

tool registrations 10

  • get_current_weather saagpatel-mcpforge-e098392/src/mcpforge/demo_assets/server.py :13
  • get_forecast saagpatel-mcpforge-e098392/src/mcpforge/demo_assets/server.py :35
  • generate saagpatel-mcpforge-e098392/src/mcpforge/mcp_server.py :75
  • update saagpatel-mcpforge-e098392/src/mcpforge/mcp_server.py :156
  • validate saagpatel-mcpforge-e098392/src/mcpforge/mcp_server.py :183
  • plan saagpatel-mcpforge-e098392/src/mcpforge/mcp_server.py :203
  • inspect saagpatel-mcpforge-e098392/src/mcpforge/mcp_server.py :219
  • doctor saagpatel-mcpforge-e098392/src/mcpforge/mcp_server.py :226
  • list_generated_servers saagpatel-mcpforge-e098392/src/mcpforge/mcp_server.py :236
  • echo saagpatel-mcpforge-e098392/src/mcpforge/safeforge_assets/server.py :8

declared dependencies 8

  • fastmcp@>=3.4.2
  • anthropic@>=0.87.0
  • click@>=8.1.0
  • jinja2@>=3.1.6
  • openai@>=2.36.0
  • pydantic@>=2.0.0
  • rich@>=15.0.0
  • pyyaml@>=6.0.3