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"))
You need an API key first
Every model provider needs a credential. Put it in a .env file in your project — Promptise loads it automatically, in scripts and in the CLI — or pass it in code with Model(...) — explained in Models & Providers → In code: Model: Model("gpt-4o-mini", provider="openai", api_key="..."). The exact variable name for every provider (Azure AI Foundry, Bedrock, Gemini, Ollama, …) is in Configuration & Secrets → Every provider's variables; self-hosted and inference endpoints are in Models & Providers → Custom, self-hosted and inference endpoints. promptise models env <provider> prints the lines a provider needs and promptise models check <model> tells you what is still missing.
→ 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)
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())
Add security guardrails¶
Block prompt injection on input; redact PII/credentials on output. Models run locally (needs promptise[all]; without the model the guardrails block every message rather than pass it unchecked).
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"]))
Isolate by tenant (multi-tenant SaaS)¶
Add tenant_id — every isolation surface (cache, memory, conversations) scopes to it.
Compute over data with one program¶
For sums/joins/multi-hop aggregation, the model writes one sandboxed Python program.
→ Code-ActionSandbox code execution¶
Run agent-written code in a hardened Docker sandbox (seccomp, dropped caps, no network).
→ SandboxTrace everything¶
Record every LLM turn, tool call, token, and latency.
→ ObservabilityMCP server recipes¶
Turn my OpenAPI spec into an MCP server¶
One command, no model. You get an editable server.py, a reviewable tool plan, and a README.
Let Claude Desktop use my internal API safely¶
env-token sends one upstream credential; standard adds writes, each approval-gated server-side.
promptise mcpcast openapi.yaml --name myapi --no-curate --profile standard --auth env-token
export MCPCAST_UPSTREAM_TOKEN="Bearer <your API token>"
claude mcp add myapi -- python myapi-mcp/server.py
Find out whether an agent can actually drive my tools¶
A real agent runs generated tasks against the server in-process. Reads may hit the live API; everything else hits spec-derived mocks, so no real data changes.
→ Agent Readiness ScoreDefine 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)
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: ...
Rate-limit a tool¶
Declared limits are enforced automatically (per client, tenant-qualified).
→ Caching & PerformanceRequire 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: ...
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"))
Serve it¶
→ DeploymentTest 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"})
See also¶
- Quick Start — build your first agent in 5 minutes
- Guides — end-to-end, build-along tutorials
- Why Promptise — what ships and when to use it