Skip to main content
These are AI features of the backend you ship: an agent your endpoint runs, or an MCP server other clients connect to. They are not the coding agent that writes your code. For that, see Coding agents and the Xano Engine’s MCP server. Four kinds work together: An MCP server also serves prompt() and resource() objects, and an agent or MCP server can have a connection trigger (agentTrigger, mcpServerTrigger) that decides what each connection sees.

A tool

An agent, called from an endpoint

Agents have no public endpoint of their own. You run one from any stack:
  • The answer is at .result. ref("answer") is the whole run envelope (finishReason, steps and more).
  • llm picks the provider: anthropic, openai, google-genai or xano-free, each with its own typed fields.
  • Structured output. Give the agent output: { schema: { ... } } with input.* fields and .result is typed from it at every call site.
  • Prompts are templates. String settings resolve {{ $args.NAME }} and {{ $env.NAME }} at run time.

Control each connection: agent triggers

An agentTrigger runs when a client connects to the agent it is bound to. t.toolset is the agent (t.toolset("name") reads one field) and t.tools is its list of tools, each { id, name, instructions }. What the trigger returns is the toolset and tools that connection gets, so the trigger can gate the connection, or log and annotate it on the way through:
  • The stack is a callback. A trigger has no input; its inputs arrive on t, typed to the trigger, so a wrong name is a compile error.
  • Bind with the handle. Pass the agent() def, not an id. A trigger bound to nothing deploys and never fires.
  • Omit response and the connection gets every tool unchanged.

An MCP server

An MCP server exposes tools, prompts and resources to any MCP client, such as Claude, ChatGPT or another agent. Prompts and resources are their own kinds: define them, then list them on the server.

A prompt

A prompt is a reusable message a client can ask for. Its input is the prompt’s arguments; an enum’s values also answer the client’s completion requests:
To send several messages, respond with a list of { role: "user" | "assistant", content }.

Resources

A resource is data a client reads by uri. A literal uri is a static resource. A uri with a {variable} is a template: each variable is one input field, and a client reads a concrete URI such as blog://posts/42.

The server, with sign-in

List the tools, prompts and resources on the server. Add oauth to make every MCP request carry a signed-in user from your auth table:
  • Entries. tools, prompts and resources each take handles, or a { tool | prompt | resource, enabled?, auth? } wrapper. auth names the auth table and is what gives that entry’s stack a caller for auth(). A bare handle is public.
  • blogMcp.getUrl(HOST) returns the Streamable HTTP URL a client connects to.
  • Names. An mcpServer and an agent with the same name collide, because both are stored as toolsets.

Hosted sign-in

With mode: "hosted", Xano is the authorization server. A client that connects is sent to your loginUrl with an mcp_request parameter. That page is also the consent screen: it shows who is asking, signs the user in, then calls an endpoint that completes the sign-in and redirects the browser to the URL it returns. Two endpoints back the page:
Declare MCP_LOGIN_URL in workspaceConfig({ env: { MCP_LOGIN_URL: "" } }) and set its value per environment in xano/.env (see Env and secrets). s.mcp.oauth.revoke ends a user’s sign-ins on a server.

Your own identity provider

To accept tokens from Auth0, Clerk, WorkOS, Entra, Okta or Cognito instead, use mode: "external". The token’s claim (default sub) is matched against a column in your auth table, here an auth0_id text column on users that holds each user’s provider id:

Control each connection: MCP server triggers

An mcpServerTrigger runs when an MCP client connects to the server it is bound to, and its response decides what that one connection lists. t carries the server’s toolset, tools, prompts and resources. Return a list filtered to narrow it; a key you leave out lists everything the server has. This one hides the resources from every connection:
  • t.auth is the signed-in user when the server has oauth: { dbo, id, extras } of the auth-table row, read as t.auth("id"). It is null on a server without sign-in, so check it before reading a field.
  • An entry you return can change its description. A returned prompt or resource’s description replaces the listed one for that connection.
  • Omit response and the connection lists all four unchanged.

Knowledge

A knowledge() item is a markdown file that Xano’s own AI reads before it acts: the workspace’s builder agent, and outside agents that read the workspace through the Meta API or MCP. It does not reach an agent() you run with s.ai.agent.run. Put what that agent must know in its llm.systemPrompt.
mode: "always" sends the whole body on every request, and a type: "agents.md" item is always sent in full. Write the description of an auto item to match the requests it should answer.

Register them

Next