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.
- Local LLM Support: Connect to any OpenAI-compatible API endpoint or use local LLM servers
- MCP Integration: Full Model Context Protocol support for both RPC and SSE protocols
- Tool Registry: Built-in file operation tools with extensibility for custom tools
- Conversation History: Maintain chat context across multiple turns
- Time Limits: Configurable execution timeouts to prevent runaway operations
- Pure Python: No external dependencies beyond the standard library
# 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:
- Initialize connections to each server
- Fetch available tools from the server
- Merge them with built-in tools (MCP tools take precedence for matching names)
- Execute tool calls using the appropriate server
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:
- RPC:
http://localhost:3000/mcp - SSE:
http://localhost:3000/sse(auto-converts to/mcpfor 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
) -> dictParameters:
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:
- Built-in Tools: File operations (read/write/list)
- MCP Tools: Tools fetched from MCP servers
- Custom Tools: User-defined tools via
tool_listparameter
To 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-redclippyAnalyzes 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-redclippyts_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:
- HTTP Timeout (
timeout): Maximum time for a single API request - Max Runtime (
max_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'])- HTTP Errors: Connection refused, timeout, invalid API key
- JSON Parse Errors: Invalid tool arguments or malformed responses
- Tool Execution Errors: Missing files, permission issues, invalid parameters
- Timeout Errors: Operation exceeded
max_runtimelimit
ts_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.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request