The default maltego-transforms package is the current SDK for building Maltego transform servers with the JSON protocol. New projects should use the generated starter project, typed entities, async transform functions, and the JSON API routes exposed by the SDK.
If you maintain TRX-style transform code, the recommended path is to move the transform logic into typed SDK functions. Keep the old request/response class shape only as a reference while rewriting each transform.
Comparison with TRX
| Feature | maltego-transforms | maltego-trx |
|---|---|---|
| Transform Execution | Yes | Yes |
| Entity Properties | Yes | Yes |
| Transform Settings | Yes | Yes |
| OAuth | Yes | Yes |
| Icon Discovery | Yes | No |
| Transform Sets | Yes | No |
| Transform & Entity Discovery | Yes | No |
| Python Bindings for Entities | Yes | No |
| Graph-In and -Out | Yes | No |
| Long Running Transforms | Yes | No |
Default SDK behavior
The SDK serves JSON protocol routes by default. When a server starts, use the seed endpoint printed in the logs when adding a current SDK server to Maltego Graph Browser or Maltego Graph Desktop.
Converting TRX transforms
Most new SDK code should use async functions and type annotations instead of TRX classes. A TRX transform often looks like this:
from maltego_trx.entities import Phrase
from maltego_trx.transform import DiscoverableTransform
class GreetPerson(DiscoverableTransform):
@classmethod
def create_entities(cls, request, response):
person_name = request.Value
response.addEntity(Phrase, f"Hi {person_name}, nice to meet you!")The equivalent current SDK transform is a typed async function:
from maltego.entities import Phrase
from maltego.server import register_transform
@register_transform
async def greet_person(input_entity: Phrase) -> Phrase:
return Phrase(f"Hi {input_entity.value}, nice to meet you!")The input annotation tells the SDK which entity type the transform accepts. The return annotation tells the SDK which result entity type to serialize. The SDK uses those annotations for registration and execution.
Entity classes such as Phrase are provided by maltego-transforms-std-entities:
pip install maltego-transforms-std-entitiesFor custom entity properties, display fields, overlays, notes, and link metadata, see the SDK API Reference article (The Entity API section).
Classes vs. async functions
TRX transforms use classes with request and response objects. Current SDK transforms use async functions with typed parameters and typed return values.
Async functions let transform servers run I/O-bound work efficiently. The SDK also provides IntegrationClient, a wrapper around httpx that is designed for async transform execution:
from maltego.entities import Phrase, URL
from maltego.server import IntegrationClient, MaltegoContext, register_transform
client = IntegrationClient()
@register_transform
async def get_status_code(
input_entity: URL,
context: MaltegoContext,
) -> Phrase:
response = await client.get(input_entity.value, context=context)
return Phrase(
f"URL {input_entity.value} returned status code: {response.status_code}!"
)