Generate production-ready FastMCP 3.x MCP servers from plain-English descriptions
Drift inferred · capture-to-capture
- HIGH code analysis flagged dynamic code execution in saagpatel/mcpforge
- HIGH code analysis flagged dynamic code execution in saagpatel/mcpforge
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
prompt-surface
shipped agent-instruction files + hidden-content / dangerous-code findings —
quoted from the analyzed source
analyzed commit e098392 · analyzer v33 · 2w ago
skills & prompt files 10
- skill saagpatel-mcpforge-e098392/.agents/skills/repo-onboarding/SKILL.md
- agent-rules saagpatel-mcpforge-e098392/AGENTS.md
- prompt-file saagpatel-mcpforge-e098392/src/mcpforge/prompts/generator.md
- prompt-file saagpatel-mcpforge-e098392/src/mcpforge/prompts/generator_multi.md
- prompt-file saagpatel-mcpforge-e098392/src/mcpforge/prompts/generator_ts.md
- prompt-file saagpatel-mcpforge-e098392/src/mcpforge/prompts/planner.md
- prompt-file saagpatel-mcpforge-e098392/src/mcpforge/prompts/self_heal.md
- prompt-file saagpatel-mcpforge-e098392/src/mcpforge/prompts/test_gen.md
- prompt-file saagpatel-mcpforge-e098392/src/mcpforge/prompts/test_gen_ts.md
- prompt-file saagpatel-mcpforge-e098392/src/mcpforge/prompts/updater.md
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