Joern代码安全MCP服务

Joern MCP Server 是一个模型上下文协议(MCP)服务,通过将大语言模型与 Joern 的代码属性图连接,帮助开发者和安全分析师在大型代码库上进行代码审查、漏洞检测和调用链分析。

  • by sfncat
  • Scala
  • 本地部署
  • 52 星标
  • 更新于
在 GitHub 查看 sfncat/mcp-joern

使用说明

Joern MCP Server

A simple MCP Server for Joern.

Project Introduction

This project is an MCP Server based on Joern, providing a series of features to help developers with code review and security analysis.

Environment Requirements

  • Python >= 3.10 (default 3.12) & uv
  • Joern

Installation Steps

  1. Clone the project locally:

    git clone https://github.com/sfncat/mcp-joern.git
    cd mcp-joern
    
  2. Install Python dependencies:

    uv venv .venv
    source .venv/bin/activate
    uv sync
    

Project Structure

├── server.py                       # MCP Server main program
├── test_mcp_client.py              # Test program for joern server and mcp tool
├── test_sc_tools.py                # Direct test program for sc tools
├── common_tools.py                 # Common utility functions
├── server_tools.py                 # Server utility functions
├── server_tools.sc                 # Scala implementation of server utility functions
├── server_tools_source.sc          # Scala implementation of server utility functions,use sourceCode to get the source code of method
├── requirements.txt                # Python dependency file
├── sample_cline_mcp_settings.json  # Sample cline mcp configuration file
└── env_example.txt                 # Environment variables example file

Usage

  1. Start the Joern server:

    joern -J-Xmx40G -J-XX:CompressedClassSpaceSize=1g -J-XX:MaxMetaspaceSize=2g \
          --server --server-host 127.0.0.1 --server-port 16162 \
          --server-auth-username user --server-auth-password password --import server_tools.sc
    Or
    joern -J-Xmx40G -J-XX:CompressedClassSpaceSize=1g -J-XX:MaxMetaspaceSize=2g \
          --server --server-host 127.0.0.1 --server-port 16162 \
          --server-auth-username user --server-auth-password password --import server_tools_source.sc
    

    Why the extra JVM flags. Both defaults are too small and only fail after prolonged use, so the breakage looks like a dead server rather than a JVM sizing problem:

    • -XX:CompressedClassSpaceSize=1g — the Joern REPL compiles one class per query (rs$line$N). The default class space (128m) is exhausted after a few thousand queries, after which every query fails with NoClassDefFoundError: Could not initialize class rs$line$NNNN.
    • -XX:MaxMetaspaceSize=2g — keeps metaspace headroom in step with the class space.
    • -J-Xmx… — size the heap for your CPG. An undersized heap shows up as queries timing out (not as an OOM). We run -Xmx60G for a ~400 MB CPG. If you are using it under Windows, you may need to set the JVM system variables through the command line or in the system environment variables.
    set _JAVA_OPTIONS=-Dfile.encoding=UTF-8
    

    set joern logging level to ERROR

    set SL_LOGGING_LEVEL=ERROR //windows
    export SL_LOGGING_LEVEL=ERROR //linux
    

    if you have the following warning

    Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)
    

    you can disable it by setting the environment variable

    set TERM=dumb
    export TERM=dumb
    

    to restore the default behavior

    set TERM=xterm-256color
    export TERM=xterm-256color
    
  2. Copy env_example.txt to .env Modify the configuration information to match the joern server startup configuration

  3. Run the test connection: Modify the information in test_mcp_client.py to confirm the joern server is working properly

    uv run test_mcp_client.py
    Starting MCP server test...
    ==================================================
    Testing server connection...
    [04/16/25 20:38:54] INFO     Processing request of type CallToolRequest                                                                                                                     server.py:534
    Connection test result: Successfully connected to Joern MCP, joern server version is XXX
    
  4. Configure MCP server Configure the mcp server in cline, refer to sample_cline_mcp_settings.json.

  5. Use MCP server Ask questions to the large language model, refer to prompts_en.md

Development Notes

  • .env file is used to store environment variables
  • .gitignore file defines files to be ignored by Git version control
  • pyproject.toml defines the Python configuration for the project
  • MCP tool development
    • Implement in server_tools.sc, add definitions in server_tools.py, and add tests in test_mcp_client.py

Contribution Guidelines

Welcome to submit Issues and Pull Requests to help improve the project.

Welcome to add more tools.

References

https://github.com/flankerhqd/jebmcp

https://docs.joern.io/server/

https://docs.joern.io/interpreter/

Change Log

v1.2.0 (2026-09-10)

Server-side call-graph tools (performance)

  • New Scala helpers in server_tools.sc: get_methods_by_name (indexed nameExact lookup, replacing full-CPG .filter(_.fullName.contains(...)) scans which time out on large CPGs), get_callee_chain (server-side BFS returning the whole call chain - method full name plus code, JDK/framework callees skipped - in one HTTP round-trip) and get_callee_chain_names (names only, no code).
  • New MCP tools exposing them: get_callee_chain_server, get_methods_by_name.
  • Effect: resolving one call chain drops from ~30 HTTP round-trips to 1.

HTTP client hardening (server.py)

  • joern_remote now uses a kept-alive requests.Session with a connection pool.
  • Retries transient failures 3 times, but fails fast on 401/403 (auth errors are not transient).
  • Returns an explicit ERROR: ... string on failure instead of None, so callers can tell a failure apart from a legitimately empty result.

Fixes

  • Credential key compatibility: the shipped .env uses USER_NAME/PASSWORD while host configs inject JOERN_AUTH_USERNAME/JOERN_AUTH_PASSWORD. Only the latter was read, so any launch without host-injected env (including the bundled test_mcp_client.py) failed with a silent 401. Both names are now accepted.
  • FastMCP compatibility: the log_level constructor argument was removed in fastmcp 2.x; it is now passed inside a try/except with a FASTMCP_LOG_LEVEL fallback.

Docs & housekeeping

  • Start command now includes -XX:CompressedClassSpaceSize=1g -XX:MaxMetaspaceSize=2g (see the note under "Start the Joern server" for why the defaults fail only after prolonged use).
  • Code comments are English only; Chinese is confined to README_cn.md and prompts_cn.md.
  • .gitignore: ignore local CPG artifacts (*.cpg), backups (*.bak-*) and the local credential-injecting run_verify.sh wrapper.
  • Version bumped to 1.2.0.

v1.3.0 (2026-09-10)

  • tests/fixture/: a self-contained Android fixture (crafted sources + build_fixture.sh) that builds a ~12 KB APK against API 36 / SDK extension level 17 and the matching CPG. Every construct that has broken the tooling before is present exactly once: a custom base receiver whose business entry is handleBroadCastReceive() (not onReceive), a 4-hop delegation chain across classes and an interface, a duplicated simple method name, an anonymous inner class, a SharedPreferences write (hd_member) at the chain end, framework calls the chain tool must skip, and a permission-gated receiver.
  • test_mcp_client.py is now an assertion-based regression gate over that fixture: it checks the chain/lookup tools, the legacy queries and the error path, and exits non-zero on failure. The ad-hoc verify_mcp.py was merged into it.
  • The fixture APK carries the same version as this package (pyproject.toml), so tests/fixture/fixture.apk and fixture.cpg are versioned together with the server.
  • Documentation and tool help no longer use the old NFC sample; they use the fixture.
  • Version 1.2.0 -> 1.3.0.

Tests

cd tests/fixture && ./build_fixture.sh --cpg   # fixture.apk + fixture.cpg
cd ../.. && uv run test_mcp_client.py          # protocol-level regression gate