Math MCP
by AhmedAhmedEG
README.md
# Math MCP
[](https://www.python.org/)
[](https://github.com/modelcontextprotocol/python-sdk)
[](https://fastapi.tiangolo.com/)
[](LICENSE)
A comprehensive math utility server implementing the **Model Context Protocol (MCP)** over streamable HTTP. Designed primarily for **reverse engineering** workflows in tools like IDA Pro, Ghidra, x64dbg, and others — but equally useful as a general-purpose math sidekick for any LLM-powered coding assistant.
---
## Features
- **Base conversion** — decimal, hex, binary, octal, all at once
- **Bitwise operations** — AND, OR, XOR, NOT, NAND, NOR
- **Bit shifts & rotates** — logical, arithmetic, rotate left/right
- **Endianness** — swap between little and big endian for 16/32/64-bit values
- **IEEE-754 floats** — inspect float32/float64 sign, exponent, mantissa, bit layout
- **Struct packing** — `struct.pack` / `struct.unpack` with arbitrary format strings
- **Bit fields** — create masks, extract, set, clear, test arbitrary bit ranges
- **ASCII / Unicode** — character to code point lookup, hex bytes to string
- **XOR cipher** — XOR data with a repeating key (hex or string input)
- **GUID / UUID** — parse mixed-endian GUID and RFC 4122 UUID from raw bytes
- **Timestamp conversion** — FILETIME (NTFS), Unix, DOS timestamps
- **Hashing** — MD5, SHA1, SHA256, SHA512
- **Hex dump** — traditional format with ASCII sidebar
- **And more** — CRC32, base64, sign extension, alignment, popcount, bit reverse, next power of 2
---
## Tools Reference
### Arithmetic
| Tool | Description | Parameters | Returns | Example |
|------|-------------|------------|---------|---------|
| `calc` | Basic arithmetic operations | `op` (enum: `add`, `sub`, `mul`, `div`, `mod`, `pow`, `sqrt`, `log`, `abs`, `neg`, `gcd`, `lcm`), `a` (string, first operand), `b` (string, second operand — omit for unary ops), `base` (number, log base, default: `2`) | Formatted result in all bases (if integer) or decimal string | `calc(op="add", a="0xFF", b="1")` → `dec: 256\nhex: 0x100\nbin: 0b100000000\noct: 0o400` |
### Number Conversion
| Tool | Description | Parameters | Returns | Example |
|------|-------------|------------|---------|---------|
| `convert` | Convert a number between bases | `value` (string, any base), `to` (enum: `dec`, `hex`, `bin`, `oct`, `all`, default: `all`) | Requested representation(s) | `convert(value="0xFF", to="dec")` → `255` |
| `compare` | Compare two numbers with diff/ratio | `a` (string), `b` (string) | Difference, signed values, ratio, relationship | `compare(a="0x100", b="0x80")` → shows a > b by 128 |
### Bitwise & Shift
| Tool | Description | Parameters | Returns | Example |
|------|-------------|------------|---------|---------|
| `bitwise` | Bitwise AND / OR / XOR / NOT / NAND / NOR | `op` (enum: `and`, `or`, `xor`, `not`, `nand`, `nor`), `a` (string), `b` (string, omit for `not`), `width` (int, default: `32`) | Formatted result in all bases | `bitwise(op="xor", a="0xAB", b="0xCD")` → `dec: 102\nhex: 0x66\nbin: 0b1100110\noct: 0o146` |
| `shift` | Bit shift / rotate | `op` (enum: `shl`, `shr`, `sar`, `rol`, `ror`), `value` (string), `amount` (int), `width` (int, default: `32`) | Formatted result in all bases | `shift(op="rol", value="0x80000000", amount=1)` → `dec: 1\nhex: 0x1\n...` |
| `bitmask` | Create / extract / set / clear / test bit fields | `op` (enum: `mask`, `extract`, `set`, `clear`, `test`), `high_bit` (int), `low_bit` (int, default: `0`), `value` (string), `set_value` (string) | Mask value, extracted field, or modified value | `bitmask(op="mask", high_bit=7)` → `mask[7:0]:\ndec: 255\nhex: 0xFF\n...` |
| `popcount` | Count set bits | `value` (string), `width` (int, default: `32`) | Set/clear counts, density percentage | `popcount(value="0xFF")` → `set bits: 8\nclear bits: 24\ndensity: 25.0%` |
| `bit_reverse` | Reverse bit order | `value` (string), `width` (int, default: `32`) | Original and reversed binary | `bit_reverse(value="0x00000001")` → `reversed: 0x80000000` |
### Data Layout
| Tool | Description | Parameters | Returns | Example |
|------|-------------|------------|---------|---------|
| `endian` | Swap byte order (little ↔ big endian) | `value` (string), `width` (int, enum: `16`, `32`, `64`, default: `32`) | Byte-swapped value in all bases | `endian(value="0x12345678", width=32)` → `0x78563412` |
| `sign_extend` | Sign-extend from N to M bits | `value` (string), `from_bits` (int), `to_bits` (int, default: `64`) | Extended value with signed interpretation | `sign_extend(value="0x80", from_bits=8)` → `sign bit set — negative\nunsigned extended: 0xFFFFFFFFFFFFFF80\nsigned decimal: -128` |
| `pack` | Pack integer to bytes or unpack hex bytes | `op` (enum: `pack`, `unpack`), `fmt` (string, struct format), `value` (string) | Packed hex bytes or unpacked values | `pack(op="pack", fmt="<I", value="0xDEADBEEF")` → `bytes: EF BE AD DE` |
| `align` | Align value up/down to a power-of-2 boundary | `value` (string), `boundary` (string, must be power of 2), `direction` (enum: `up`, `down`, default: `up`) | Aligned value and difference | `align(value="0x1235", boundary=16)` → `aligned: 0x1240, difference: +11` |
### Float Analysis
| Tool | Description | Parameters | Returns | Example |
|------|-------------|------------|---------|---------|
| `float_bits` | Inspect IEEE-754 float32 or float64 bit layout | `value` (string — decimal float, hex, or binary), `width` (int, enum: `32`, `64`, default: `32`) | Sign, exponent, mantissa, hex, binary | `float_bits(value="3.14159", width=32)` → `sign=0 exp=128 mantissa=0x490FD0` |
### String & Encoding
| Tool | Description | Parameters | Returns | Example |
|------|-------------|------------|---------|---------|
| `ascii` | Character ↔ code point lookup | `value` (string — single char, decimal, hex, binary) | Character info or code point info | `ascii(value="A")` → `'A' → dec=65, hex=0x41, bin=0b01000001` |
| `string` | Convert hex bytes or comma-separated decimals to ASCII | `value` (string — hex or `12,34,56` format) | ASCII string and byte count | `string(value="48 65 6C 6C 6F")` → `ascii: Hello` |
| `base64` | Encode to or decode from base64 | `op` (enum: `encode`, `decode`, default: `encode`), `value` (string) | Encoded or decoded result | `base64(op="encode", value="Hello")` → `SGVsbG8=` |
| `crc32` | Calculate CRC32 checksum | `value` (string — text or hex bytes) | CRC32 in hex and signed decimal | `crc32(value="Hello")` → `0xF7D18982` |
| `hash` | Calculate hash digest | `algo` (enum: `md5`, `sha1`, `sha256`, `sha512`, default: `md5`), `value` (string — text or hex bytes) | Hash hex digest | `hash(algo="sha256", value="Hello")` → `SHA256: 185F8DB3...` |
### Reverse Engineering Utilities
| Tool | Description | Parameters | Returns | Example |
|------|-------------|------------|---------|---------|
| `xor` | XOR cipher with repeating key | `value` (string — hex or text), `key` (string — hex or text) | XOR result in hex and ASCII | `xor(value="48656C6C6F", key="FF")` → `B79A939390` |
| `guid` | Parse/format GUID/UUID from raw bytes | `value` (string — hex bytes or GUID string like `xxxxxxxx-...`) | Mixed-endian GUID, RFC 4122 UUID, raw bytes | `guid(value="3B3E9B7A5C3D...")` → GUID/UUID/bytes |
| `timestamp` | Convert FILETIME / Unix / DOS timestamps | `value` (string), `type` (enum: `filetime`, `unix`, `dos`, default: `unix`) | Human-readable UTC and local time | `timestamp(value="0x1D2E3F4A", type="dos")` → DOS parsed date/time |
| `hexdump` | Format hex bytes as traditional hex dump | `value` (string — hex or text), `base` (string, base address, default: `0`) | Hex dump with ASCII sidebar | `hexdump(value="48656C6C6F")` → `00000000 48 65 6C 6C 6F ... |Hello|` |
| `next_pow2` | Find the next power of 2 | `value` (string, must be positive) | Next and previous power of 2 | `next_pow2(value="0x500")` → `next: 0x800 (2048)` |
---
## Getting Started
### Prerequisites
- **Docker** (recommended) — any modern Docker installation
- **or** Python >= 3.14 with `uv` installed
### Docker (recommended)
```bash
# Build the image
docker build -t math-mcp .
# Run in background, mapping host port 13338 to container port 3000
docker run -d -p 13338:3000 --name MathMCP --restart unless-stopped math-mcp
```
### Native (Python 3.14+)
```bash
# Install uv (if not already installed)
pip install uv
# Sync dependencies
uv sync
# Run the server
uv run python server.py
```
## Configuration
### MCP Client Integration
Add to your MCP client configuration (e.g., `~/.config/opencode/opencode.json`, `claude_desktop_config.json`, or Continue config):
```json
{
"mcpServers": {
"math-mcp": {
"type": "url",
"url": "http://localhost:13338/mcp"
}
}
}
```
### Environment / Arguments
The server listens on `0.0.0.0:3000` by default. To change the port, modify the `uvicorn.run()` call in `server.py` or the Docker port mapping.
---
## API
The MCP endpoint uses the **streamable HTTP transport** (SSE + JSON-RPC).
| Path | Method | Description |
|------|--------|-------------|
| `/mcp` | POST | MCP JSON-RPC endpoint over SSE |
Health check (FastAPI default):
```bash
curl http://localhost:13338/docs
```
---
## Building from Source
```bash
git clone https://github.com/yourusername/math-mcp.git
cd math-mcp
# Development with hot reload
uv run uvicorn server:app --host 0.0.0.0 --port 3000 --reload
# Production via Docker
docker build -t math-mcp .
docker run -d -p 13338:3000 --name MathMCP math-mcp
```
---
## Example: Tools in Action
### Convert hex to all bases
```
Input: convert(value="0xDEAD")
Output: dec: 57005
hex: 0xDEAD
bin: 0b1101111010101101
oct: 0o157255
```
### Inspect a float32
```
Input: float_bits(value="3.14159", width=32)
Output: float32: 3.14159
hex: 0x40490FD0
bin: 0b01000000010010010000111111010000
sign=0 exp=128 (unbiased 1) mantissa=0x490FD0
```
### XOR cipher
```
Input: xor(value="48656C6C6F", key="FF")
Output: xor result (hex): B79A939390
xor result (ascii): \xb7\x9a\x93\x93\x90
```
---
## License
MIT — feel free to use, modify, and distribute.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues