Local Code Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Local Code Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
local-code-mcp is a reusable, profile-driven MCP server for safely inspecting and changing local Git repositories through a Streamable HTTP endpoint. RentingHub is the first profile/plugin; no RentingHub business logic is embedded in the core server.
The security model is deny-by-default:
127.0.0.1 by default;shell: false;main, master, or the profile default branch are blocked;logs/audit.log with sensitive arguments redacted.rg is optional; search_code falls back to a Node implementationgh is optional and required only for automatic PR creationThe included RentingHub profile currently points to:
/Volumes/Home_EX/Projects/RentingHubUpdate profiles/rentinghub.json or set MCP_PROFILE_PATH if the repository is elsewhere.
export MCP_HOST=127.0.0.1
export MCP_PORT=3333
export MCP_ACTIVE_PROFILE=rentinghub
export MCP_PROFILE_PATH="$PWD/profiles/rentinghub.json"
export MCP_AUTH_MODE=bearer
export MCP_BEARER_TOKEN="$(openssl rand -hex 32)"
export MCP_PUBLIC_MODE=true
export MCP_ENABLE_FILE_WRITE=false
export MCP_ENABLE_GIT_WRITE=false
export MCP_ENABLE_PUSH=false
export MCP_ENABLE_DESTRUCTIVE=false
export MCP_TOOL_CATALOG_MODE=chatgpt_default
npm install
npm run build
npm run startHealth check:
curl http://127.0.0.1:3333/healthThe MCP endpoint is:
http://127.0.0.1:3333/mcpSupported environment variables:
MCP_HOST=127.0.0.1
MCP_PORT=3333
MCP_ACTIVE_PROFILE=rentinghub
MCP_PROFILE_PATH=/absolute/path/to/profiles/rentinghub.json
MCP_AUTH_MODE=none|bearer|oauth
MCP_BEARER_TOKEN=<required when exposed remotely>
MCP_PUBLIC_BASE_URL=https://host.example
MCP_OAUTH_ISSUER=https://host.example
MCP_OAUTH_ADMIN_SECRET=<local approval secret>
MCP_OAUTH_ACCESS_TOKEN_TTL_SECONDS=3600
MCP_OAUTH_REFRESH_TOKEN_TTL_SECONDS=2592000
MCP_OAUTH_STORAGE_PATH=./data/oauth-store.json
MCP_OAUTH_DEBUG=false
MCP_ALLOWED_ORIGINS=<comma-separated exact origins>
MCP_PUBLIC_MODE=false
MCP_ENABLE_FILE_WRITE=false
MCP_ENABLE_GIT_WRITE=false
MCP_ENABLE_PUSH=false
MCP_ENABLE_DESTRUCTIVE=false
MCP_ENABLE_FORCE_PUSH=false
MCP_ENABLE_GH_WRITE=false
MCP_ENABLE_GH_MERGE=false
MCP_ENABLE_GIT_REWRITE=false
MCP_GIT_REMOTE=origin
MCP_MAX_READ_BYTES=262144
MCP_MAX_OUTPUT_BYTES=200000
MCP_TOOL_CATALOG_MODE=chatgpt_default|chatgpt_code|chatgpt_full|power_user|debug (default: chatgpt_default)
LOCAL_CODE_MCP_TOOL_CATALOG=chatgpt_full (alternative env to explicitly override tool catalog mode)MCP_TOOL_CATALOG_MODE restricts which tools are exposed to the AI client to prevent ChatGPT/Cursor from picking low-level or deprecated tools (like apply_patch or write_file) in favor of preferred high-level ones (like apply_patch_batch and run_targeted_validation).
chatgpt_default: Hides legacy and low-level tools, registering only preferred high-level tools focused on read, audit, and validation.chatgpt_code: Exposes read, audit, and validation tools + safe implementation tools (like apply_patch_batch, git_add, git_commit, git_push_branch, gh_pr_create).chatgpt_full (or alias mcpfull / full): Exposes the full trusted workflow including write, git, PR, and job tools depending on safety gate allowances. Can be requested via LOCAL_CODE_MCP_TOOL_CATALOG=chatgpt_full, MCP_TOOL_CATALOG_MODE=chatgpt_full, or profile field toolCatalogMode: "chatgpt_full".power_user: Exposes all tools in the project profile except explicitly deprecated ones.debug: Exposes all tools configured in the project profile.MCP_AUTH_MODE defaults to bearer, preserving the existing Codex CLI flow. In bearer mode, every /mcp request must include the configured token. In OAuth mode, every /mcp request must include a server-issued OAuth access token. none is intended only for local development; public no-auth mode prints a prominent warning. If an Origin header is present in bearer/none mode, it must exactly match MCP_ALLOWED_ORIGINS.
Start the local server first, then expose its port:
tailscale funnel 3333For background mode:
tailscale funnel --bg 3333The public endpoint will be:
https://<machine>.<tailnet>.ts.net/mcpVerify and disable Funnel:
tailscale funnel status
tailscale funnel reset
tailscale funnel statusDo not keep Funnel enabled when it is not in use. Never expose this server publicly without bearer or OAuth authentication. Tailscale Funnel publishes to the internet; it is not limited to devices in your tailnet.
Export the same bearer token in the environment that starts Codex:
export LOCAL_CODE_MCP_TOKEN="<same token used by MCP_BEARER_TOKEN>"Add this to ~/.codex/config.toml or a trusted project's .codex/config.toml:
[mcp_servers.local_code_mcp]
url = "https://<machine>.<tailnet>.ts.net/mcp"
bearer_token_env_var = "LOCAL_CODE_MCP_TOKEN"
enabled = true
startup_timeout_sec = 20
tool_timeout_sec = 120
default_tools_approval_mode = "prompt"
enabled_tools = [
"repo_info",
"list_files",
"search_code",
"read_file",
"git_status",
"git_diff",
"inspect_package_scripts",
"read_test_failures",
"apply_patch",
"run_check",
"run_validation_sequence",
"git_create_branch",
"git_add",
"git_commit",
"git_push_branch",
"github_create_pr",
"rentinghub_scan_architecture",
"rentinghub_run_core_validation"
]
[mcp_servers.local_code_mcp.tools.apply_patch]
approval_mode = "approve"
[mcp_servers.local_code_mcp.tools.run_check]
approval_mode = "approve"
[mcp_servers.local_code_mcp.tools.run_validation_sequence]
approval_mode = "approve"
[mcp_servers.local_code_mcp.tools.git_add]
approval_mode = "approve"
[mcp_servers.local_code_mcp.tools.git_commit]
approval_mode = "approve"
[mcp_servers.local_code_mcp.tools.git_push_branch]
approval_mode = "approve"
[mcp_servers.local_code_mcp.tools.github_create_pr]
approval_mode = "approve"Codex supports Streamable HTTP URLs, bearer tokens sourced from environment variables, tool allowlists, and per-tool approval modes. Restart Codex after changing its configuration.
Start the server in OAuth mode with every write gate disabled:
cd /Volumes/Home_EX/Projects/local-code-mcp
export MCP_HOST=127.0.0.1
export MCP_PORT=3333
export MCP_ACTIVE_PROFILE=rentinghub
export MCP_PROFILE_PATH="$PWD/profiles/rentinghub.json"
export MCP_AUTH_MODE=oauth
export MCP_PUBLIC_MODE=true
export MCP_PUBLIC_BASE_URL="https://ats-mac-mini.tail60fb71.ts.net"
export MCP_OAUTH_ISSUER="https://ats-mac-mini.tail60fb71.ts.net"
export MCP_OAUTH_ADMIN_SECRET="$(openssl rand -hex 16)"
export MCP_ENABLE_FILE_WRITE=false
export MCP_ENABLE_GIT_WRITE=false
export MCP_ENABLE_PUSH=false
export MCP_ENABLE_DESTRUCTIVE=false
echo "ADMIN SECRET FOR OAUTH APPROVAL:"
echo "$MCP_OAUTH_ADMIN_SECRET"
npm run build
npm startIn another terminal, expose the local port:
tailscale funnel --bg 3333
tailscale funnel statusChatGPT configuration / Cấu hình ChatGPT:
https://ats-mac-mini.tail60fb71.ts.net/mcp.MCP_OAUTH_ADMIN_SECRET; approval is never automatic.The OAuth server publishes protected-resource metadata, authorization-server/OpenID metadata, dynamic client registration, authorization with PKCE S256, token and refresh-token endpoints, and an empty JWKS because access tokens are opaque and strictly stored/verified server-side.
Set MCP_OAUTH_DEBUG=true temporarily to log OAuth request method, path, status, MCP authentication failures, and safely redacted rejected redirect locations. Debug logging never includes tokens, authorization codes, PKCE verifiers, or the admin secret.
Run the local OAuth smoke test after building:
npm run smoke:oauthOAuth scopes authorize a tool, but they do not enable it. The environment gates remain authoritative. To enable full write access manually for a limited session:
export MCP_ENABLE_FILE_WRITE=true
export MCP_ENABLE_GIT_WRITE=true
export MCP_ENABLE_PUSH=true
export MCP_ENABLE_DESTRUCTIVE=trueRestart the server after changing gates. Never use MCP_AUTH_MODE=none with write enabled. Do not keep Funnel enabled when MCP is not in use. Do not expose logs/ or data/oauth-store.json. Do not auto-merge pull requests.
The server implements a Codex-style project trust system to manage multiple projects safely, switch projects at runtime, and enforce permissions.
Trust store path: ~/.local/share/local-code-mcp/config.toml (or configured via MCP_TRUST_STORE_PATH).
mcptrust trust rentinghub \
--repo /Volumes/Home_EX/Projects/RentingHub \
--profile-path /Volumes/Home_EX/Projects/local-code-mcp/profiles/rentinghub.json \
--github Phamtuandat/RentingHub \
--mode full \
--default \
--yes
mcpfull rentinghub
mcpread /Volumes/Home_EX/Projects/UnknownRepo
mcptrust list
mcptrust current
mcptrust doctor
mcpswitch mentorly
mcpstopWhen running mcpfull or mcpread on an untrusted directory, the CLI will ask for explicit approval:
mcpfull /Volumes/Home_EX/Projects/Mentorly
Project is not trusted:
/Volumes/Home_EX/Projects/Mentorly
Trust this folder with full workspace permissions? [y/N]y/yes is selected, the project is verified (must contain .git), registered in the trust store, and started.n/no is selected for mcpfull, the startup is refused.n/no is selected for mcpread, it starts in an untrusted read-only mode (skipping local config files).fs.realpath resolution. Symlinks and real paths match interchangeably..mcp/project.toml configurations..mcp/project.toml are strictly validated:npm, npx, node, pnpm, yarn, bun, dotnet, cargo, go, python, python3, pytest, vitest, jest, tsc, eslint, prettier.rm, sudo, su, chmod, chown, curl, wget, ssh, scp, rsync, dd, mkfs, diskutil, osascript, open, launchctl, kill, pkill, docker, docker-compose, bash, sh, zsh, fish, powershell, pwsh.;, &&, ||, |, >, >>, <, ` `, $(, ${, \n, \r`.cwd of any command must reside within the repository sandbox.enableForcePush), GitHub merge (enableGhMerge), or destructive actions. Any attempt will log warnings.mcpswitch <project> or the switch_project MCP tool without restarting the HTTP/OAuth server process. Note:enabledTools, the MCP client might need to reconnect/reinitialize the session to reflect changes in the visible tool catalog.local-code-mcp code.repo_infogit_statusgit_create_and_checkout_branchapply_patchrun_validation_sequencegit_diffgit_addgit_commitgit_push_branchgh_pr_creategh_pr_checksgh_pr_merge (only if explicitly enabled)Configure the following environment variables to control permissions:
MCP_ENABLE_FILE_WRITE=true
MCP_ENABLE_GIT_WRITE=true
MCP_ENABLE_PUSH=true
MCP_ENABLE_DESTRUCTIVE=true
MCP_ENABLE_GH_WRITE=true
MCP_ENABLE_GH_MERGE=false
MCP_ENABLE_GIT_REWRITE=false
MCP_ENABLE_FORCE_PUSH=falseProfiles are JSON files that define:
The core loads a plugin by projectPlugin. Plugins receive the same constrained tool context and cannot replace the path sandbox or command allowlist. The RentingHub plugin adds architecture discovery and the core validation sequence.
To support another project, create a new profile and optionally register a narrowly scoped plugin in src/projectProfiles/plugins.ts.
Recommended progression:
MCP_ENABLE_FILE_WRITE=true for apply_patch, new files, and moves.MCP_ENABLE_GIT_WRITE=true for branch, stage, and commit operations.MCP_ENABLE_PUSH=true only for pushing a non-default branch and creating a PR.write_file refuses to replace an existing file unless destructive mode is also enabled. delete_file requires destructive mode. Force push is disabled unless MCP_ENABLE_FORCE_PUSH=true, and then uses --force-with-lease; protected/default branch pushes remain forbidden.
run_check never executes arbitrary shell text. It resolves an exact command key or a safe alias to an existing allowedCommands entry in the active profile, then executes that entry's immutable argv array with shell: false.
Examples:
run_check({ "commandKey": "backend_build" })
run_check({ "commandKey": "backend_jest_run_in_band" })
run_validation_sequence({ "stopOnFailure": true })Aliases such as npm run build, build, and npm test are accepted only when they uniquely map to a configured profile command. Unknown commands are rejected and the response lists available command keys and aliases.
npm test
npm run build
npm run smoke
npm run smoke:oauthThe smoke test starts the built server on a test port, checks /health, verifies unauthenticated MCP rejection, and performs an authenticated MCP initialize request.
This server supports performance-optimized workflows that reduce tool round-trip latency by providing batch operations, targeted validation, background jobs, project indexing, and task context.
1. workflow_summary
2. task_context(query)
3. read_files_batch(paths)
4. apply_patch_batch(patches)
5. run_targeted_validation(level="quick")
6. read_test_failures_smart (if quick validation failed)
7. run_targeted_validation(level="full")
8. git_diff
9. git_commitstart_code_job
get_code_job_status
get_code_job_resultgh uses the locally authenticated GitHub account. Scope that account/token to only the repositories required.0600, ignored by Git, and should be retained and deleted according to local policy.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.