Skip to content

Cookbook

Short, copy-paste recipes for the tasks you'll reach for most. Each is the minimal correct form; follow the link for the full guide.

Every agent capability is one parameter on build_agent() — enable only what you need; the rest has zero overhead.


Agent recipes

Add persistent memory

Remember context across invocations; relevant past context is auto-injected.

from promptise.memory import ChromaProvider
agent = await build_agent(model="openai:gpt-5-mini", servers=srv,
    memory=ChromaProvider(persist_directory="./memory"))
Memory

Persist conversations (with ownership)

chat() loads history, invokes, and saves — and enforces session ownership.

from promptise.conversations import SQLiteConversationStore
agent = await build_agent(model="openai:gpt-5-mini", servers=srv,
    conversation_store=SQLiteConversationStore("chat.db"))
reply = await agent.chat("hi", session_id="s1", caller=caller)
Conversations

Cache similar queries

Serve semantically-similar queries from cache (30–50% cost reduction).

from promptise.cache import SemanticCache
agent = await build_agent(model="openai:gpt-5-mini", servers=srv, cache=SemanticCache())
Semantic Cache

Add security guardrails

Block prompt injection on input; redact PII/credentials on output. Models run locally.

agent = await build_agent(model="openai:gpt-5-mini", servers=srv, guardrails=True)
Guardrails

Attach per-request identity

Carry the user through the whole invocation (cache/memory/conversation scope, audit).

from promptise import CallerContext
await agent.ainvoke(input, caller=CallerContext(user_id="alice", roles=["analyst"]))
Multi-User Systems

Isolate by tenant (multi-tenant SaaS)

Add tenant_id — every isolation surface (cache, memory, conversations) scopes to it.

caller = CallerContext(user_id="alice", tenant_id="acme")  # disjoint from any other tenant
Secure Multi-Tenant Platform

Compute over data with one program

For sums/joins/multi-hop aggregation, the model writes one sandboxed Python program.

agent = await build_agent(model="openai:gpt-5-mini", servers=srv, agent_pattern="code-action")
Code-Action

Sandbox code execution

Run agent-written code in a hardened Docker sandbox (seccomp, dropped caps, no network).

agent = await build_agent(model="openai:gpt-5-mini", servers=srv, sandbox=True)
Sandbox

Trace everything

Record every LLM turn, tool call, token, and latency.

agent = await build_agent(model="openai:gpt-5-mini", servers=srv, observe=True)
Observability


MCP server recipes

Define a tool

Schema is generated from type hints.

from promptise.mcp.server import MCPServer
server = MCPServer(name="api")

@server.tool()
async def search(query: str, limit: int = 10) -> list:
    """Search records."""
    return await db.search(query, limit)
Server Fundamentals

Require authentication + a role

from promptise.mcp.server import JWTAuth, AuthMiddleware
server.add_middleware(AuthMiddleware(JWTAuth(secret="...")))

@server.tool(auth=True, roles=["admin"])
async def delete_all() -> str: ...
Auth & Security

Rate-limit a tool

Declared limits are enforced automatically (per client, tenant-qualified).

@server.tool(rate_limit="100/min")
async def expensive() -> dict: ...
Caching & Performance

Require human approval for a tool

Server-side, for any MCP client. Fail-closed; four-eyes enforced.

from promptise.mcp.server import ApprovalGateMiddleware, PendingApprover
approver = PendingApprover(server, approver_role="approver")
server.add_middleware(ApprovalGateMiddleware(approver, timeout=300))

@server.tool(auth=True, requires_approval=True)
async def refund(order_id: str, amount: float) -> dict: ...
Approval Gates

Make tenancy a server-wide invariant

Every tool authenticates and must carry a tenant, or the call is denied.

server = MCPServer(name="api", require_tenant=True)
server.add_middleware(AuthMiddleware(JWTAuth(secret="..."), tenant_claim="org"))
Multi-Tenancy

Serve it

promptise serve myapp:server --transport http --port 8080
Deployment

Test it without a network

Full pipeline (validation → guards → middleware → handler) in-process.

from promptise.mcp.server import TestClient
result = await TestClient(server).call_tool("search", {"query": "revenue"})
Testing


See also