
Python library for local LLM-powered security analysis with Ghidra binary analysis, C/C++ vulnerability scanning, and MCP tool integration for automated reverse engineering and report generation.
TrustedSec LLM Library is a Python library for interacting with local LLMs that support tool usage. It enables running large workflows traditionally only possible with frontier models by leveraging local LLM endpoints and MCP (Model Context Protocol) integration.
# Clone or copy the repository
git clone https://github.com/trustedsec/ts_llmlib.git
cd ts_llmlib
# Install with pip
pip install -e .
Copy the ts_llmlib/ directory to your project:
cp -rf ts_llmlib /path/to/your/project/
from ts_llmlib import ChatSession
# Initialize with defaults (connects to http://localhost:1234/v1/chat/completions)
chat = ChatSession()
# Run a prompt
response = chat.run_prompt("What files are in the current directory?")
print(response['content'])
from ts_llmlib import ChatSession
# Configure with custom settings
chat = ChatSession(
system_prompt="You are a helpful assistant that uses file tools.",
tool_list=[], # Empty = use default file tools
mcp_servers={
"default": "http://localhost:3000/mcp"
},
llm_endpoint_url="http://localhost:1234/v1/chat/completions",
model_name="qwen3-coder-next",
timeout=60,
max_runtime=300
)
response = chat.run_prompt("Write 'hello' to /tmp/greeting.txt")
print(response['content'])
from ts_llmlib import ChatSession
chat = ChatSession()
history = [
{"role": "user", "content": "What is 2+2?"},
{"role": "assistant", "content": "The answer is 4."}
]
response = chat.run_prompt("Can you write that to a file?", history=history)
| Tool | Parameters | Description |
|---|---|---|
read_local_file | path: str | Read contents from a local file |
write_local_file | path: str, content: str | Write content to a local file |
list_directory | path: str | List files and directories in a path |
MCP (Model Context Protocol) enables integration with external tools and services. When MCP servers are configured, ts_llmlib will:
from ts_llmlib import ChatSession
chat = ChatSession(
mcp_servers={
"ghidraSvr": "http://localhost:8081/sse"
},
llm_endpoint_url="http://localhost:1234/v1/chat/completions",
model_name="qwen3-coder-next"
)
# The chat session will automatically fetch and integrate Ghidra tools
# such as list_methods, decompile_function, get_xrefs_to, etc.
ts_llmlib supports both RPC-style and SSE (Server-Sent Events) endpoints:
http://localhost:3000/mcphttp://localhost:3000/sse (auto-converts to /mcp for RPC calls)ChatSession(
system_prompt: str | None = None,
tool_list: list | None = None,
mcp_servers: dict[str, str] | None = None,
llm_endpoint_url: str = "http://localhost:1234/v1/chat/completions",
model_name: str = "default",
timeout: int = 60,
max_runtime: int = 300
)
Parameters:
system_prompt (str | None): Custom system prompt. Defaults to a minimal assistant prompt.tool_list (list | None): List of custom tool definitions. Empty list uses built-in tools.mcp_servers (dict[str, str] | None): Dict mapping server names to URLs.llm_endpoint_url (str): URL of the LLM API endpoint.model_name (str): Model identifier for the LLM endpoint.timeout (int): HTTP request timeout in seconds.max_runtime (int): Maximum execution time for a prompt in seconds.response = chat.run_prompt(
user_prompt: str,
conversation_history: list[dict] | None = None,
disable_tools: list[str] | None = None,
max_runtime: int | None = None
) -> dict
Parameters:
user_prompt (str): The user's message or question.conversation_history (list[dict] | None): Optional conversation history as a list of role/content pairs.disable_tools (list[str] | None): List of tool names to disable for this call.max_runtime (int | None): Override the default max runtime for this specific call.Returns:
{
"content": str, # LLM response text
"tool_calls": list, # List of tool calls made (if any)
"usage": dict | None, # Token usage if available from the LLM
"error": str | None # Error message if failed
}
The ToolRegistry manages all tools available to the chat session:
tool_list parameterTo override the default paths you can set the following variables, these are checked in ChatSession.
TS_LLM_MODEL=qwen3-coder-next TS_LLM_ENDPOINT=http://HOSTNAME:1234/v1/chat/completions
# Example usage
export TS_LLM_MODEL=qwen3-coder-next
export TS_LLM_ENDPOINT=http://HOSTNAME:1234/v1/chat/completions
ts_llmlib-redclippy
# OR
TS_LLM_MODEL=qwen3-coder-next TS_LLM_ENDPOINT=http://HOSTNAME:1234/v1/chat/completions ts_llmlib-redclippy
Analyzes C/C++ source files for security vulnerabilities:
ts_llmlib-cpp-analyze <source_folder> <output_folder>
Reverse engineering binary analysis with Ghidra integration:
# Basic analysis
ts_llmlib-ghidra-analyze <output_folder>
# Rename-only mode (first pass)
ts_llmlib-ghidra-analyze --rename_only <output_folder>
# Process only previously unnamed functions
ts_llmlib-ghidra-analyze --process_unnamed_only <output_folder>
# Grouped analysis for call relationship grouping
ts_llmlib-ghidra-analyze --grouped <output_folder>
Once done running if not doing --rename_only you can cleanup the structure by running:
ts_llmlib-ghidra-cleanup <input_folder> <output_folder>
Generate formatted vulnerability reports from JSON review files:
ts_llmlib-ghidra-report <review_folder>
Run the RedClippy Qt-based chat interface (note this example requires pyside6):
ts_llmlib-redclippy
ts_llmlib connects to any OpenAI-compatible API endpoint. Common local LLM servers:
| Server | Default URL |
|---|---|
| Ollama | http://localhost:11434/v1/chat/completions |
| LM Studio | http://localhost:1234/v1/chat/completions |
| vLLM | http://localhost:8000/v1/chat/completions |
Two timeout settings control execution:
timeout): Maximum time for a single API requestmax_runtime): Total wall-clock time allowed for prompt processing (including tool calls)If either limit is exceeded, the response will contain an error message.
All errors are returned in the response dictionary:
response = chat.run_prompt("Some prompt")
if response.get('error'):
print(f"Error: {response['error']}")
else:
print(response['content'])
max_runtime limitts_llmlib/
├── __init__.py # Package initialization, exports ChatSession
├── client.py # LLMClient for HTTP requests to LLM endpoints
├── chat.py # ChatSession class (main API)
├── mcp.py # MCPClient for Model Context Protocol integration
├── tools.py # ToolRegistry for tool management
├── HOW_TO_TS_LLMLIB.md # Original documentation
└── examples/ # Example scripts
├── c_cpp_analyze.py # C/C++ vulnerability analysis script
├── redclippy.py # Qt-based GUI chat application
├── ghidra_analyze.py # Ghidra binary analysis with MCP integration
├── ghidra_vuln_report.py # Vulnerability report generator
├── ghidra_cleanup.py # Output file reorganization utility
└── example_ts_llmlib.py # Example script demonstrating library usage
pyproject.toml # Modern Python package configuration (scripts defined here)
LICENSE.txt # BSD-3-Clause License
README.md # This file
BSD-3-Clause License - See LICENSE.txt file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)