Skip to content

security + refactor: harden scaffold, clean code, re-export FastMCP#2

Closed
jieyao-MilestoneHub wants to merge 4 commits into
mainfrom
refactor/security-solid-cleanup
Closed

security + refactor: harden scaffold, clean code, re-export FastMCP#2
jieyao-MilestoneHub wants to merge 4 commits into
mainfrom
refactor/security-solid-cleanup

Conversation

@jieyao-MilestoneHub
Copy link
Copy Markdown
Contributor

Summary

  • docs: Fix broken GitHub URL in core README (404 → CoreNovus/mcp-forge), fix mcp.run()run_server(mcp), remove stale PLAN.md
  • security: Jinja2 SandboxedEnvironment, path traversal guard, input validation for author/email/description, bounded InMemory providers (max_size/max_metrics), default bind 127.0.0.1, narrow exception catching in AWS providers (ClientError, BotoCoreError instead of bare Exception)
  • refactor: Remove dead code in bedrock_llm.py, DRY retry loop extraction, fix CLI version command, fix Windows encoding in tests
  • feat: Re-export FastMCP from mcp_forge_core, update generated test template to use create_mcp_app(), remove redundant mcp dependency from generated pyproject.toml

Security Findings Addressed

Severity Finding Fix
MEDIUM Jinja2 Environment allows template introspection SandboxedEnvironment
MEDIUM Template injection via unvalidated description/author/email validate_text_field()
MEDIUM Unbounded InMemory provider growth max_size / max_metrics params
MEDIUM Default bind to 0.0.0.0 exposes dev server to network Default to 127.0.0.1
LOW Bare except Exception in AWS providers except (ClientError, BotoCoreError)
LOW Path traversal possible if scaffold called directly .resolve() + parent check

Test plan

  • pytest packages/mcp-forge-core/tests/ — 150 passed
  • pytest packages/mcp-forge-aws/tests/ — 67 passed
  • pytest packages/mcp-forge-cli/tests/ — 37 passed (includes 2 previously failing Windows tests now fixed)
  • ruff check packages/ — all checks passed

🤖 Generated with Claude Code

jieyao-MilestoneHub and others added 4 commits April 11, 2026 01:02
- Fix mcp-forge-core README: github.com/mcp-forge/mcp-forge (404) →
  github.com/CoreNovus/mcp-forge
- Fix Quick Start example: mcp.run() → run_server(mcp) to use the
  mode-switching server factory
- Remove PLAN.md: documented Protocol-based architecture but code uses
  ABCs, template filenames and workflow structure were outdated

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Scaffold (mcp-forge-cli):
- Use SandboxedEnvironment instead of Environment to prevent Jinja2
  template introspection attacks via custom --templates directories
- Add path traversal guard in MCPServerScaffold.generate() — verify
  output stays within the intended parent directory
- Add validate_text_field() to reject unsafe characters (", \n, \r, \)
  in author/email/description fields before template interpolation
- Call validation in orchestrator before scaffolding

Providers (mcp-forge-core):
- InMemoryCache: add max_size parameter with oldest-first eviction to
  prevent unbounded memory growth in long-running dev servers
- InMemoryTelemetry: add max_metrics parameter with rolling window
- Default server_host from 0.0.0.0 to 127.0.0.1 in config.py and
  server_factory.py to prevent unintended network exposure in dev

AWS providers (mcp-forge-aws):
- Narrow exception handling: catch (ClientError, BotoCoreError) instead
  of bare Exception in DynamoDB and CloudWatch providers — let
  programming errors propagate instead of being silently swallowed
- CloudWatch: use asyncio.to_thread() for consistency with DynamoDB
  providers instead of loop.run_in_executor(lambda)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- bedrock_llm.py: remove no-op message conversion loop — the ternary
  and subsequent for-loop were both identity operations
- retry.py: extract _execute_with_retry() to eliminate duplicated retry
  loop between @Retry decorator and with_retry() function; log
  type(exc).__name__ instead of full exception message to avoid leaking
  sensitive data in retry warnings
- cli.py: fix version command — use proper __version__ import instead
  of hacky ScaffoldConfig.__module__.split('.')[0]
- test_scaffold.py: add encoding="utf-8" to all read_text() calls —
  fixes 2 pre-existing test failures on Windows cp950 locale caused by
  em-dash characters in generated server.py docstring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Make the mcp SDK an invisible implementation detail of mcp-forge-core
so that generated servers never import from mcp.server.fastmcp directly.

- Re-export FastMCP from mcp_forge_core.__init__ — users can now write
  from mcp_forge_core import FastMCP for type annotations
- Update test_sample.py.j2 to use create_mcp_app() instead of directly
  importing FastMCP from the mcp SDK
- Remove redundant mcp>=1.0 dependency from pyproject.toml.j2 — it is
  already a transitive dependency via mcp-forge-core

When mcp SDK 2.0 ships, only server_factory.py needs updating — no
generated user code will break.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jieyao-MilestoneHub
Copy link
Copy Markdown
Contributor Author

Superseded: all commits from refactor/security-solid-cleanup were squash-merged into main via PR #3 (commit ccd44d4). Closing as already landed.

@jieyao-MilestoneHub jieyao-MilestoneHub deleted the refactor/security-solid-cleanup branch April 15, 2026 00:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant