Skip to content

2026

Elicitation vs Four-Eyes: Two Ways to Approve AI Actions

The choice at the heart of mcp elicitation approval vs four-eyes review is not "should this tool need a human?" — you already decided that when you marked it requires_approval=True. The real question is which human, and when: do you confirm with the person sitting behind the client that made the call, right now, mid-run — or do you park the call in a queue for an independent reviewer who was not the one who triggered it? Both are legitimate. They protect against different failures, and picking the wrong one either annoys your users or lets a caller wave through their own risky action. This post is a decision guide, and the good news is that in Promptise Foundry the two models sit behind one interchangeable handler, so choosing is a one-line change you can make per tool.

How to Build an MCP Server in Python (Tutorial)

Building an MCP server Python developers can actually ship usually stalls on one thing: hand-writing JSON Schema for every tool so clients know how to call it. This tutorial skips that entirely. With Promptise Foundry you decorate a normal Python function with type hints, and the framework generates the schema, validates every call, and serves the tool over stdio, streamable HTTP, or SSE. By the end you'll have a typed tool running, exposed over HTTP, and covered by an in-process test — no schema boilerplate, no network mocking.

One Stalled MCP Tool Can Exhaust Your Connection Pool

MCP tool connection pool exhaustion is what happens when one slow downstream API doesn't just fail its own call — its tool keeps handler coroutines and pooled DB or HTTP connections open through every timeout, the shared pool saturates, and unrelated healthy tools start queueing behind it. The failure is sneaky because the sick tool often works, just slowly. By the end of this post you'll be able to reproduce that cascade in-process and cap its blast radius with two composable middlewares, so a single stalled MCP tool can never consume the server's shared capacity.

MCP vs Function Calling: What's the Difference?

The MCP vs function calling debate confuses a lot of teams, because the two are not actually competitors — they operate at different layers. Function calling is how an LLM decides which tool to call and with what arguments. The Model Context Protocol (MCP) is how those tools get packaged, served, and shared. By the end of this post you'll know exactly where the crossover point sits, so you can keep raw function calling while your tools fit in one file and reach for MCP the moment they don't — without paying a token tax as your catalog grows.

Is Your Agent's Retrieved Memory a Prompt-Injection Risk?

Memory prompt injection is the attack most local-vector setups never see coming: you scan the user's message for "ignore your rules," wave it through, and then — one line later — your agent auto-injects a retrieved memory into the system prompt that says exactly that. A vector store is trivial to stand up. What is not trivial is remembering that everything you recall from it is untrusted text. Whoever could write to that store — a prior conversation, a scraped document, a support ticket that got summarized into long-term memory — planted an instruction that fires on a later, unrelated query. This post shows why the retrieval path needs its own defense, and how Promptise Foundry scans recalled memory before it ever reaches the model.

Migrate a Single-Tenant Agent to Multi-Tenant

To migrate a single-tenant agent to multi-tenant, you don't have to rewrite it — you have to find the one place where identity enters the system and make the tenant part of it. The trap is believing there are many such places. In a typical agent, per-customer state lives in at least three stores — long-term memory (a vector index), a semantic cache, and conversation history — and the naive migration path is to hunt down every read and write against all three and splice in a tenant filter. That's the retrofit tax, and it's where cross-tenant leaks come from: not the filters you add, but the one you forget. This how-to walks the Promptise Foundry migration seam end to end, where adding a tenant means setting a single field.

Migrating off LangChain to Promptise Foundry

Migrating off LangChain rarely fails because the new framework is worse — it fails because teams try to do it in one weekend, rip out everything at once, and lose the ability to tell whether the port is correct. This guide gives you the opposite: an incremental path where your existing LangChain tools keep working from day one, you move orchestration, memory, and auth one layer at a time, and you verify every step before the next. By the end you'll have a plan to migrate from LangChain to Promptise Foundry without a scary big-bang rewrite, plus a reproducible .superagent manifest that captures the finished agent.

Model-Agnostic AI Agents: Claude, GPT, Ollama & Local

Model-agnostic AI agents let you change the model behind your agent without touching the rest of your code. In Promptise Foundry the model is just a string you pass to build_agent(), so the same agent — same tools, same memory, same guardrails — can run on openai:gpt-5-mini today, anthropic:claude-sonnet-4.5 tomorrow, and a local ollama:llama3 in an air-gapped deployment, with no rewrite in between. By the end of this post you'll know exactly how that swap works, how to run entirely offline, and when pinning to one provider is actually the smarter choice.

Multi-Agent Audit: Who's the Principal After a Delegation Hop?

Multi-agent audit accountability is the question a compliance reviewer asks the moment your fleet stops being one agent: when Agent A — running on Alice's behalf — hands a subtask to Agent B, and B exports a record or issues a refund, which principal does the audit trail name as accountable? This is not the question of how B authenticates the delegation call — that is a separate topic with its own answer. It is the narrower, sharper compliance question that delegation raises: after the handoff, does your tamper-evident record still name the human who set the chain in motion, or does it name the sub-agent's service account? Get that wrong and every audited action taken past the first hop is attributed to a bot, and "the bot did it" is not an answer a SOC 2, HIPAA, or EU AI Act auditor accepts.

Multi-Agent Debate for Better LLM Reasoning

A multi-agent debate LLM setup runs the same question through three roles — one model proposes an answer, another attacks it, and a judge decides who was right — instead of trusting a single pass. The appeal is obvious: adversarial scrutiny catches mistakes that a lone model, confidently wrong, will happily ship. The catch is just as real: you pay for it in latency and tokens. By the end of this post you'll know exactly what the Proposer → Critic → Judge graph does in Promptise Foundry, how to stand one up in a few lines, and — just as importantly — the narrow set of queries where it earns its keep versus the far larger set where a single verify pass is the smarter buy.

How to Build Multi-Agent Systems in Python: 2026 Guide

Building multi-agent systems in Python is rarely blocked by the modeling — the hard part is coordinating several agents without turning your codebase into a tangle of ad-hoc HTTP calls and shared globals. Most guides stop at the word "orchestration" and hand you a box diagram. This one skips the hand-waving: you'll learn the four concrete coordination primitives Promptise Foundry gives you, see runnable code for cross-agent delegation over HTTP+JWT, and leave with a decision table so you can pick a topology instead of copying someone else's.

Multi-Tenant AI Agents: Architecture for SaaS

Shipping a multi-tenant AI agent means one deployment serves many customers, and the single worst thing that can happen is that Acme's data surfaces in Globex's session. If you are building AI features into a SaaS product, tenant separation is not a nice-to-have — it is the invariant your whole security story rests on. This post walks through why per-handler tenant checks fail, what a real isolation boundary looks like, and how to make cross-tenant leakage structurally impossible in Promptise Foundry with one server flag and a tenant_id that flows from your JWT all the way to storage.

Multi-Tenant RAG: Isolate Customer Data in a Shared Store

Multi-tenant RAG almost always ships as one shared vector store plus a hand-written metadata filter bolted onto every query — and the first query that forgets the filter quietly leaks Acme's documents into Globex's answer. There is no exception, no stack trace, no failing test. The retrieval just returns a neighbor from the wrong customer, the model summarizes it, and you find out when a support ticket arrives. This post is about the retrieval path specifically: why per-query filters are the wrong place to enforce a security boundary, what other frameworks hand you today, and how Promptise Foundry threads the tenant into retrieval automatically so a forgotten filter is structurally impossible.

Pass User Identity Through Agents to MCP Tools

Getting multi-user agent identity right is the difference between a demo and a product your auditors will sign off on. The moment two customers share one agent, you have to answer a hard question: when Alice asks "show my invoices," how does her identity reach the tool server so it returns her data and not Bob's — without the client simply asserting whatever roles it likes? This post traces the whole path in Promptise Foundry: from a per-request CallerContext in your app, to a bearer token on the wire, to server-side JWT extraction and role/tenant guards. By the end you'll be able to wire it end to end and know exactly where the trust boundary sits.

OAuth for AI Agents: client_credentials & JWKS

Most guides to OAuth for AI agents drown you in redirect URLs, consent screens, and PKCE — none of which your agent uses. An autonomous agent is a machine calling another machine. There is no browser, no human clicking "Allow." The grant you actually want is client_credentials: the agent presents a signed token it got from your identity provider, and your server verifies that token against the issuer's public keys. By the end of this post you'll know exactly which OAuth flow agents use, and how to verify agent-presented tokens in a Promptise MCP server with JwksAuth and AsymmetricJWTAuth — no shared secret in sight.

Your Vector Store Is Local — Are Your Embeddings?

Running offline embeddings for AI agents is the difference between retrieval that is genuinely air-gapped and retrieval that quietly ships your entire private corpus to a third party twice. Most teams get the vector store right — they stand up Chroma, FAISS, Qdrant, or pgvector inside their own network, confirm the database never phones home, and check the box marked "on-prem." Then they wire an embeddings step in front of it that calls a hosted API, and every chunk of that private corpus egresses the moment it's indexed and again on every query. The vector math is local. The text that produces the vectors is not. This post walks through that embedding-egress trap and shows how Promptise Foundry pins both memory retrieval and semantic tool selection to a single local embedding model, so nothing leaves the host.

How to Pre-Load LLM Guardrail Models on an Air-Gapped Host

Running offline guardrail models on an air-gapped host sounds like it should be a config flag, but the failure mode is subtle: a guardrail or embedding model that expects to auto-download from a model hub does not gracefully degrade when the network is gone — it hard-fails or blocks on the first user message, in production, at the exact moment you least want a surprise. The DeBERTa injection classifier, GLiNER NER model, Llama Guard, and the all-MiniLM-L6-v2 embedding model that powers semantic tool selection all default to pulling weights from Hugging Face the first time they run. On a laptop that is fine. In a classified data center or a sovereign-cloud tenant with no egress, that first from_pretrained() call raises a connection error and takes your agent down with it.

Stop Rewriting Your Tools for Claude, Cursor, and ChatGPT

Write one MCP tool every AI client can call — Claude Desktop, Cursor, and ChatGPT included — and you never rewrite the same logic per framework again. That is the whole promise of the Model Context Protocol: a tool is a small server that speaks a standard wire format, and anything that speaks the protocol can discover and invoke it. Yet most agent frameworks quietly break that promise. They ask you to author tools as framework-native Python objects that only their own runtime understands, so the moment you want to reuse tools across AI clients you are back to standing up a separate MCP server anyway. This post shows why that gap exists, and how being MCP-native on both sides — a server SDK to write the tool and a native MCP client to consume it — collapses two artifacts into one.

Turn a REST or OpenAPI API into an MCP Server

Going from OpenAPI to MCP is the fastest way to make an API you already own callable by AI agents — and you can do it without touching a single route handler. If your service already ships a Swagger or OpenAPI document, Promptise Foundry can read that spec and generate one MCP tool per operation, complete with JSON Schema derived from your existing parameter definitions. By the end of this article you'll have an OpenAPI mcp server running that proxies real HTTP calls to your API, and you'll know how to layer authentication, rate limits, and endpoint filtering on top so agents only touch what you allow.

Per-Customer Chat History: Enforcing Session Ownership

Per-customer conversation isolation is the difference between persisting a chat thread and actually keeping one customer from reading another's — and the second is the part most stacks quietly skip. Wiring up a database to store messages by session_id is a solved problem: pick SQLite, Postgres, or Redis and you have durable history. The hard problem starts the moment a second customer exists, because a session id is just a string, and any authenticated caller who can produce that string can ask for the thread behind it. This post shows how Promptise Foundry turns "who is allowed to read this thread" from a check you have to remember into an invariant enforced on every read, write, and delete — keyed on the tenant::user isolation key so an enumerated session id from another customer is denied, not served.