Generic Adapters
Turn HTTP, OpenAPI, GraphQL, webhooks, and MCP servers into tools without per-provider glue.
#Generic adapters
Most providers do not have a hand-written maivn-tools connector — and you should not have to wait for one. The generic adapters let you stand up a working, Agent-ready connector against almost any API in minutes, by describing the shape of the API rather than coding each call by hand.
They cover the API styles a provider connector almost always needs: REST/HTTP, OpenAPI, GraphQL, webhooks, and MCP servers. The HTTP adapters use the shared transport, retry policy and normalized errors. Rate limiting requires configuration. Webhook verification and MCP server execution have their own behavior; they do not inherit every HTTP feature.
#GenericHttpConnector
Turns a list of HttpEndpoint definitions into Agent-ready callables.
from maivn_tools import (
AuthMode,
BearerTokenAuth,
GenericHttpConnector,
HttpEndpoint,
PermissionFlag,
PermissionSet,
ProviderMetadata,
)
connector = GenericHttpConnector(
metadata=ProviderMetadata(
name="example",
display_name="Example API",
version="0.1.0",
auth_modes=(AuthMode("bearer"),),
),
base_url="https://api.example.com",
auth=BearerTokenAuth("token"),
endpoints=[
HttpEndpoint(name="ping", method="GET", path="/ping"),
HttpEndpoint(
name="create_widget",
method="POST",
path="/widgets",
body_params=("name", "color"),
permissions=PermissionSet(PermissionFlag.WRITE),
),
],
)Each endpoint declares:
pathplaceholders like/users/{user_id}— required keyword arguments.query_params— keyword arguments serialized into the URL.body_params— keyword arguments serialized into the JSON body. Not allowed onGET,HEAD, orDELETE.static_queryandstatic_headers— merged into every call.permissionsanddestructive— declared upfront so hosts can inspect them.
Unknown keyword arguments are rejected at call time so tool surfaces stay explicit.
#OpenAPIConnector
Imports an OpenAPI 3.x document and produces a list of HttpEndpoint definitions. Pass the parsed mapping (not a URL); the importer does not fetch documents over the network.
import json
from maivn_tools import (
GenericHttpConnector,
OpenAPIConnector,
PermissionFlag,
PermissionSet,
ProviderMetadata,
)
document = json.loads(spec_text)
importer = OpenAPIConnector(
document,
operation_allowlist={"listPets", "getPet", "createPet"},
permission_overrides={"createPet": PermissionSet(PermissionFlag.WRITE)},
)
connector = GenericHttpConnector(
metadata=ProviderMetadata(
name="petstore",
display_name="Petstore",
version="0.1.0",
),
base_url="https://petstore.example.com",
endpoints=importer.endpoints(),
)Defaults are conservative: safe methods (GET, HEAD, OPTIONS) get PermissionFlag.READ; DELETE gets PermissionFlag.DELETE and is marked destructive; everything else gets PermissionFlag.WRITE. Override per operation through permission_overrides / destructive_overrides.
#GraphQLConnector
Exposes a fixed catalog of GraphQL operations as callable tools. The connector forwards the query string verbatim — it never parses the GraphQL — and surfaces a stable ProviderError when the response contains an errors array.
from maivn_tools import (
GraphQLConnector,
GraphQLOperation,
PermissionFlag,
PermissionSet,
ProviderMetadata,
)
connector = GraphQLConnector(
metadata=ProviderMetadata(
name="example_gql",
display_name="Example GraphQL",
version="0.1.0",
),
endpoint="https://api.example.com/graphql",
operations=[
GraphQLOperation(
name="get_viewer",
query="query GetViewer { viewer { id name } }",
description="Return the authenticated viewer.",
),
GraphQLOperation(
name="create_post",
query="mutation CreatePost($title: String!) { createPost(title: $title) { id } }",
permissions=PermissionSet(PermissionFlag.WRITE),
destructive=False,
variables_allowlist=("title",),
),
],
)
create_post = connector.tools()[1]
create_post(variables={"title": "Hello"})When variables_allowlist is non-empty, the tool rejects unknown variables.
#WebhookListener
Verifies and normalizes provider webhook deliveries. The listener is transport-agnostic: pass raw headers and body, get back a normalized event.
from maivn_tools import SignatureAlgorithm, WebhookListener, WebhookVerifier
listener = WebhookListener(
provider="example",
verifier=WebhookVerifier(
secret="shared-secret",
signature_header="X-Example-Signature",
algorithm=SignatureAlgorithm.HMAC_SHA256,
timestamp_header="X-Example-Timestamp",
tolerance_seconds=300,
),
event_type_header="X-Example-Event",
)
event = listener.handle(request.headers, request.body)
# event.payload is the parsed JSON bodylistener.try_handle(...) returns None instead of raising on a signature mismatch, which is useful for endpoints that always return 204 and log failures asynchronously.
#MCP bridge
MCPBridge translates declarative MCPServerSpec definitions into maivn.MCPServer instances.
from maivn import Agent
from maivn_tools import MCPBridge, MCPHttpServer, MCPStdioServer
bridge = MCPBridge([
MCPStdioServer(
name="local-fs",
command="python",
args=("/srv/my_app/files_server.py",), # your MCP stdio server
),
MCPHttpServer(
name="search",
url="https://mcp.example.com",
bearer_token="token",
prefix="search.",
),
])
agent = Agent(name="mcp-agent", model="auto", mcp_servers=bridge.build())The bridge resolves SDK server classes when build() runs. The SDK is a required dependency of the current maivn-tools distribution.