Joern MCP Server
The Joern MCP Server acts as a bridge to Joern for comprehensive code review and security analysis through Code Property Graphs (CPGs).
Core Capabilities:
Server Management: Start, manage, and configure the Joern server with customizable settings, check connection status and version information
CPG Operations: Load CPG files from specified paths for detailed code analysis
Method Analysis: Retrieve method details by ID or name, including source code, parameters, and relationships; identify callers and callees; analyze calls within methods
Class Analysis: Get class information by ID or name, list class methods, explore parent and derived class hierarchies
Call Graph Analysis: Navigate method call relationships and retrieve associated source code for comprehensive flow analysis
LLM Integration: Leverage large language models to analyze and query codebases intelligently
Utility Functions: Test server connections, ping status, and access help documentation
Used for environment variable management, storing configuration information for connecting to the Joern server
Supports version control integration, used for cloning source code repositories for analysis
Provides the runtime environment for the MCP server, with utility functions and tools for code analysis
Supports implementation of complex server utility functions through Scala scripts that interact with Joern's core capabilities
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Joern MCP Server analyze this Python code for SQL injection vulnerabilities"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.
Related MCP server: codebadger
Environment Requirements
Python >= 3.10 (default 3.12) & uv
Joern
Installation Steps
Clone the project locally:
git clone https://github.com/sfncat/mcp-joern.git cd mcp-joernInstall 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 fileUsage
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.scWhy 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 withNoClassDefFoundError: 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-Xmx60Gfor 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-8set joern logging level to ERROR
set SL_LOGGING_LEVEL=ERROR //windows export SL_LOGGING_LEVEL=ERROR //linuxif 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=dumbto restore the default behavior
set TERM=xterm-256color export TERM=xterm-256colorCopy env_example.txt to .env Modify the configuration information to match the joern server startup configuration
Run the test connection: Modify the information in
test_mcp_client.pyto confirm the joern server is working properlyuv 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 XXXConfigure MCP server Configure the mcp server in cline, refer to
sample_cline_mcp_settings.json.Use MCP server Ask questions to the large language model, refer to
prompts_en.md
Development Notes
.envfile is used to store environment variables.gitignorefile defines files to be ignored by Git version controlpyproject.tomldefines the Python configuration for the projectMCP tool development
Implement in
server_tools.sc, add definitions inserver_tools.py, and add tests intest_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/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(indexednameExactlookup, 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) andget_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_remotenow uses a kept-aliverequests.Sessionwith 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 ofNone, so callers can tell a failure apart from a legitimately empty result.
Fixes
Credential key compatibility: the shipped
.envusesUSER_NAME/PASSWORDwhile host configs injectJOERN_AUTH_USERNAME/JOERN_AUTH_PASSWORD. Only the latter was read, so any launch without host-injected env (including the bundledtest_mcp_client.py) failed with a silent 401. Both names are now accepted.FastMCP compatibility: the
log_levelconstructor argument was removed in fastmcp 2.x; it is now passed inside atry/exceptwith aFASTMCP_LOG_LEVELfallback.
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.mdandprompts_cn.md..gitignore: ignore local CPG artifacts (*.cpg), backups (*.bak-*) and the local credential-injectingrun_verify.shwrapper.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 ishandleBroadCastReceive()(notonReceive), a 4-hop delegation chain across classes and an interface, a duplicated simple method name, an anonymous inner class, aSharedPreferenceswrite (hd_member) at the chain end, framework calls the chain tool must skip, and a permission-gated receiver.test_mcp_client.pyis 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-hocverify_mcp.pywas merged into it.The fixture APK carries the same version as this package (
pyproject.toml), sotests/fixture/fixture.apkandfixture.cpgare 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 gateAvailable Tools
18 toolscheck_connectionB
Check if the Joern MCP plugin is running
Inputs: no named parameters.
get_call_code_by_idA
Get the source code of a specific call node from the loaded CPG by the call id
@param id: The unique identifier of the call node, the id is a Long int string, like '111669149702L'
@return: The source code of the specified call
Inputs: code_id (required).
get_calls_in_method_by_method_full_nameC
Get the calls info by the method full name which the call is in the method
@param method_full_name: The full name of the method
@return: The calls info of the method
Inputs: method_full_name (required).
get_class_full_name_by_idB
Retrieves the fully name of a class by its ID
@param id: The unique identifier of the class (typeDecl), the id is a Long int string, like '111669149702L'
@return: The fully name of the class (e.g., com.android.nfc.NfcService$6)
Inputs: class_id (required).
get_class_methods_by_class_full_nameB
Get the methods of a class by its fully qualified name
@param class_full_name: The fully qualified name of the class
@return: List of full name, name, signature and id of methods in the class
Inputs: class_full_name (required).
get_derived_classes_by_class_full_nameB
Get the derived classes of a class
@param class_full_name: The fully qualified name of the class
@return: The derived classes info of the class, including the full name, name and id
Inputs: class_full_name (required).
get_helpB
Get help information from joern server
Inputs: no named parameters.
get_method_by_call_idC
Get the method info by the call id which the call is in the method
@param id: The id of the call
@return: The method info of the call
Inputs: call_id (required).
get_method_calleesB
Retrieves a list of methods info that are called by the specified method
@param method_full_name: The fully qualified name of the source method(e.g., com.android.nfc.NfcService$6.onReceive:void(android.content.Context,android.content.Intent)) @return: List of full name, name, signature and id of methods which call the source method
Inputs: method_full_name (required).
get_method_callersA
Retrieves a list of methods that call the specified method
@param method_full_name: The fully qualified name of the source method(e.g., com.android.nfc.NfcService$6.onReceive:void(android.content.Context,android.content.Intent))
@return: List of full name, name, signature and id of methods called by the source method
Inputs: method_full_name (required).
get_method_code_by_class_full_name_and_method_nameA
Get the code of a method by its class full name and method name, this tool is usually used when you don't know the full name of the method, but you know the full name of the class and the name of the method. If there are multiple methods with the same name in the class, the code of all methods will be returned.
@param class_full_name: The fully qualified name of the class, like 'com.android.nfc.NfcService'
@param method_name: The name of the method, like 'onReceive'
@return: List of full name, name, signature and id of methods in the class
Inputs: class_full_name (required), method_name (required).
get_method_code_by_full_nameA
Get the code of a method by its fully name, If you know the full name of the method, you can use this tool to get the method code directly. If you only know the full name of the class and the name of the method, you should use get_method_code_by_class_full_name_and_method_name @param method_full_name: The fully qualified name of the method (e.g., com.android.nfc.NfcService$6.onReceive:void(android.content.Context,android.content.Intent)) @return: The source code of the specified method
Inputs: method_full_name (required).
get_method_code_by_idC
Get the code of a method by its class full name and method name
@param class_full_name: The fully qualified name of the class
@param method_name: The name of the method
@return: List of full name, name, signature and id of methods in the class
Inputs: method_id (required).
get_method_full_name_by_idA
Retrieves the fully qualified name of a method by its ID
@param id: The unique identifier of the method, the id is a Long int string, like '111669149702L'
@return: The fully qualified name of the method (e.g., com.android.nfc.NfcService$6.onReceive:void(android.content.Context,android.content.Intent))
Inputs: method_id (required).
get_parent_classes_by_class_full_nameB
Get the parent classes of a class
@param class_full_name: The fully qualified name of the class
@return: The parent classes info of the class, including the full name, name and id
Inputs: class_full_name (required).
get_referenced_method_full_name_by_call_idC
Get the method info by the call id which the call is referenced the method
@param id: The id of the call
@return: The method info of the call
Inputs: call_id (required).
load_cpgB
Loads a CPG from a file if the cpg is not loaded or the cpg is not the same as the filepath.
Args:
cpg_filepath (str): The path to the CPG file, the filepath is absolute path.
Returns:
str: True if the CPG is loaded successfully, False otherwise.
Inputs: cpg_filepath (required).
pingA
Checks if the Joern server is running and responsive by querying its version
@return: The Joern server version if successful, 'Query Failed' if the server is not responding
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 18 tools
The tools have clear purposes but significant overlap exists. For example, get_method_code_by_full_name, get_method_code_by_class_full_name_and_method_name, and get_method_code_by_id all retrieve method code with different input parameters, which could confuse agents about which to use. However, descriptions help clarify the distinctions, preventing complete ambiguity.
Most tools follow a consistent verb_noun pattern (e.g., get_call_code_by_id, get_method_by_call_id), with minor deviations like check_connection and ping (which are simpler verbs). The naming is generally predictable and readable, though not perfectly uniform across all tools.
With 18 tools, the count is slightly high but reasonable for a code analysis server like Joern, which needs to handle various CPG queries. It covers multiple aspects (methods, classes, calls, loading), though it might feel a bit heavy compared to more focused servers.
The tool set provides comprehensive coverage for querying a CPG, including loading, checking connections, and retrieving details on calls, methods, and classes with full lifecycle support (e.g., get, list, derive, parent). No obvious gaps are present for its intended domain of static code analysis.
Maintenance
Related MCP Connectors
Security scanner for MCP servers. Detect vulnerabilities, prompt injection, and tool poisoning.
MCP server for static security analysis of Android source code
Repository knowledge graph MCP server for codebase understanding and debugging.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceEnables AI agents and LLMs to build Joern Code Property Graphs from repositories, paths, or snippets and query them over MCP for CPGQL queries, data-flow and taint tracing, program slicing, and vulnerability hunting across many languages. It scales to large analysis batches with per-CPG worker pools, memory-aware scheduling, and a Postgres/Redis backend.-
- FlicenseNot gradedqualityAmaintenanceA containerized MCP server that enables AI agents and LLMs to build and query Joern Code Property Graphs from Git repositories, local paths, or pasted snippets, exposing CPGQL queries, data-flow and taint tracing, program slicing, and vulnerability hunting across many languages. It scales to large analysis batches with worker pools, memory-aware scheduling, and a Postgres/Redis backend.-
- FlicenseNot gradedqualityAmaintenanceThis MCP server builds Joern Code Property Graphs from a Git repository, local path, or pasted snippet and exposes them over MCP, letting AI agents run CPGQL queries, trace data flow and taint, slice programs, and hunt for vulnerabilities across many languages.-
- FlicenseNot gradedqualityAmaintenanceEnables AI agents and LLMs to build Joern Code Property Graphs from repositories, local paths, or snippets and query them over MCP for program analysis, data-flow and taint tracing, program slicing, and vulnerability hunting across many languages.-