Skip to content

Using the App

This document describes common use-cases and scenarios for this App.

General Usage

The app holds two registries under one AI Tools menu.

  • AI Tools → AI Models lists AI Providers and AI Models, the LLM endpoints and the models each one offers.
  • AI Tools → MCP Models lists MCP Servers and MCP Tools, the MCP servers and what each one advertises.

Neither registry calls anything. Both record what exists so that other apps read one place.

The AI Tools navigation tab The AI Tools navigation tab

The AI Providers list The AI Providers list

AI providers and models

Add a provider

  1. Go to AI Tools → AI Models → AI Providers, then select Add.
  2. Enter a Name.
  3. Choose an External Integration. If the one you need does not exist yet, select the + button beside the field. A modal opens, you create the External Integration in place, and the new record is selected for you. You never leave the provider form.
  4. Leave OpenAI-compatible checked if the endpoint serves GET /v1/models.
  5. Optionally set a default num_predict and temperature.

Add an AI Provider Add an AI Provider

The + button beside the field opens this modal. Fill it in, select Create, and the new External Integration is selected on the provider form behind it.

Creating an External Integration without leaving the page Creating an External Integration without leaving the page

Discover the models a provider offers

Run Jobs → AI Models → Discover AI Models.

The job reads GET <remote_url>/v1/models from each OpenAI-compatible provider and syncs the result. It is safe to run repeatedly:

  • A model in the response that is not in the database is created.
  • A model already in the database keeps its enabled, num_predict, and temperature values. A user may have set them by hand, so the job never overwrites them.
  • A model in the database that the provider no longer offers is logged and kept. The job never deletes a record.

Leave AI Provider empty to run against every provider. Uncheck Enable new models to create new records in the disabled state for review.

A provider that is not OpenAI-compatible is skipped, and the job says so. No standard discovery endpoint exists for those.

The Discover AI Models job result The Discover AI Models job result

The provider detail view lists everything the job found.

An AI Provider after discovery An AI Provider after discovery

Override an inference parameter for one model

num_predict and temperature exist on both models. The provider value is the default. The model value is an override. Leave the model value empty to inherit.

Read the effective value from the ORM:

ai_model.resolved_num_predict
ai_model.resolved_temperature

Retire a model without deleting it

Clear the Enabled checkbox. The record stays, its history stays, and the discovery job leaves the flag alone. Consumers should skip a disabled model.

Record what a model costs

Set Input cost per million tokens and Output cost per million tokens on the model, so that a consumer can price a call before it makes one, or account for one afterwards. Output is usually several times dearer than input, which is why the two are separate fields.

An empty price means nobody has recorded one. Treat it as unknown, not as free.

An AI Model detail view An AI Model detail view

Browse every model at once

The AI Models list shows every model across every provider. Filter it by provider, by enabled state, or by name.

The AI Models list The AI Models list

MCP servers and tools

Register a server

  1. Go to AI Tools → MCP Models → MCP Servers and select Add.
  2. Give the server a name and pick its External Integration.

    If the integration does not exist yet, select the + button beside the field. The External Integration form opens in a modal over the page. Save it, and the new integration is selected without losing anything already typed. This needs the extras.add_externalintegration permission; without it, Nautobot hides the button.

  3. Choose the Transport. Almost every remote server is streamable-http, which is the only transport discovery reads. A stdio server runs as a subprocess of its client, so a worker cannot reach one; sse is deprecated by the MCP specification and this app speaks none of it. Discovery skips both and says so, and their tools are entered by hand.

  4. Save.

The MCP Servers list The MCP Servers list

Discover what a server offers

Open the server and select Run Discovery, or run Jobs → MCP Models → MCP Server Discovery directly. Leave the server blank to discover every enabled server, which is the form to schedule.

Discovery writes down what the server said. It never enables a tool and never sets writable.

A discovered server shows what the operator set, what the server reported about itself, its advertised capabilities, its own instructions, and every tool it offers:

An MCP Server after discovery An MCP Server after discovery

Review the tools

A newly discovered tool arrives enabled and marked writable=True. Assume it writes until somebody has read what it does.

Go to AI Tools → MCP Models → MCP Tools, read each new tool's description and input schema, select the ones that only read, and use Edit Selected to clear writable on all of them at once.

The Advertised Read Only column shows what the server itself claimed. Treat it as a hint from an unverified party: the MCP specification requires that a client not decide from it. It is there so a reviewer can compare the claim against the description.

The MCP Tools list The MCP Tools list

Opening a tool shows both JSON Schemas the server advertised, and the fingerprint that says whether its contract has moved since the review:

An MCP Tool with both advertised schemas An MCP Tool with both advertised schemas

Register a server Nautobot cannot reach

A stdio server has no endpoint for a worker to open. Register the server, then add its tools by hand from AI Tools → MCP Models → MCP Tools → Add. Everything else about the record works normally.

Reading a registry from another app

This is what the app exists for. Both registries are plain Nautobot models, so another app reads them through the ORM or the REST API.

The AI registry

from nautobot_ai_models.models import AIModel

# Every model on offer, with its provider and endpoint ready to read.
available = AIModel.objects.filter(
    enabled=True,
).select_related("provider__external_integration")

# The effective inference parameters, with the provider default filled in.
for ai_model in available:
    print(ai_model.name, ai_model.resolved_num_predict, ai_model.resolved_temperature)

# What a million tokens cost. None means nobody recorded a price, not that it is free.
priced = available.exclude(input_cost_per_million=None)

The MCP registry

from nautobot_ai_models.models import MCPTool

# Every tool that is on offer, with its server and endpoint ready to read.
available = MCPTool.objects.filter(
    enabled=True,
    mcp_server__enabled=True,
).select_related("mcp_server__external_integration")

# The read-only subset, for a caller that runs without approval.
read_only = available.filter(writable=False)

Build the connection from the server's integration. Render the templated fields rather than reading them raw, because all three support Jinja2:

integration = tool.mcp_server.external_integration
url = integration.render_remote_url({"obj": tool.mcp_server})
headers = integration.render_headers({"obj": tool.mcp_server})

Notice that a tool's contract changed

definition_fingerprint is a digest of the tool's title, description, and both schemas. Record it alongside whatever approval you granted. When it differs from the current value, the server changed what the tool is after somebody reviewed it, and the review is stale.