Skip to main content
MeshAgent allows you to deploy any code as a service. Services can be anything from pre-built agents to custom code to external integrations and can be deployed as either a room service (scoped to a specific MeshAgent room) or a project service (available in every room in your project). To deploy a service in MeshAgent, you write a YAML configuration file that describes what to run and how to connect it to MeshAgent. Services can be deployed with the MeshAgent CLI, from MeshAgent Studio, or by sharing a Powerboards install link. This page covers the key concepts behind service configuration, explains how a manifest is organized, and provides a complete field reference for the required configuration YAML file. The examples on this page are complete manifests you can copy into meshagent.yaml and adapt.

Key Concepts

Before deploying your service there are three decisions to make about your service.

1. Who can use the service: Project vs Room Scope

This determines who can use your service. The YAML is the same in both cases — the scope is set by how you deploy.
  • Project service — Available in every room in your project. Changes require a room restart to take effect. Deploy with meshagent service create --file meshagent.yaml --global.
  • Room service — Scoped to a single room. Auto-updates if changed during an active session. Deploy with meshagent service create --file meshagent.yaml --room myroom.

2. Is the service user-configurable: Service vs ServiceTemplate

This determines whether configuration is fixed or user-provided.
  • Service (kind: Service) — A concrete spec that MeshAgent can run immediately. Configuration is baked into the YAML. Deploy with meshagent service create --file meshagent.yaml plus either --room myroom or --global.
  • ServiceTemplate (kind: ServiceTemplate) — A parameterized spec that collects user inputs (API keys, names, settings) at deploy time, then renders a Service from them. Uses {{ variable_name }} placeholders (Jinja templating) and an additional variables section to define what users provide. Deploy with meshagent service create-template --file meshagent.yaml plus either --room myroom or --global.

3. What kind of service is running: Container vs External

Each YAML configuration file can run either a containerized service or an external service.
  • Container — MeshAgent pulls a container image and runs it inside the room. The container can run anything: a MeshAgent CLI agent, a Python script, or other custom code. MeshAgent handles the lifecycle — starting, stopping, injecting credentials, and connecting it to the room.
  • External - Your service is already running somewhere else. You provide a URL and MeshAgent routes traffic to it.

Fast CLI Deploy or Custom Manifest?

If you are deploying a standard process-backed agent, you do not have to start by hand-writing YAML.
  • Use meshagent process deploy ... when the built-in CLI flags already describe what you want to run.
  • Use meshagent process spec ... > meshagent.yaml when you want MeshAgent to generate a complete manifest for you and then adapt it.
For example:
bash
# Fastest path for a standard process-backed agent
meshagent process deploy \
  --service-name my-chatbot \
  --agent-name my-chatbot \
  --channel chat \
  --require-web-search \
  --require-storage \
  --room my-room

# Generate a complete manifest you can review and customize
meshagent process spec \
  --service-name my-chatbot \
  --agent-name my-chatbot \
  --channel chat \
  --require-web-search \
  --require-storage > meshagent.yaml
In general:
  • Start with deploy for simpler use cases.
  • Start with spec when you want to review the generated manifest or adapt it before deployment.
  • Move to a hand-edited manifest when you need more advanced behavior such as a custom image, custom ports, or additional mounts not covered by the CLI flags.

Example 1: Deploying a Service

Let’s deploy a simple process-backed agent with web search and storage tools. This is a kind: Service where configuration is fixed and it runs as-is. This is a complete manifest. You can copy it into meshagent.yaml and deploy it directly.
kind: Service
version: v1
metadata:
  name: my-chatbot
  description: "A chatbot with web search and storage"
  annotations:
    meshagent.service.id: "my-chatbot"
agents:
  - name: my-chatbot
    description: "A helpful chatbot"
    annotations:
      meshagent.agent.type: "ChatBot"
container:
  image: "meshagent/cli:default"
  command: >-
    meshagent process join
    --agent-name my-chatbot
    --channel chat
    --require-web-search
    --require-storage
    --rule "You are a helpful assistant. Use web search to find current information and save important findings to storage."
    --room-rules "agents/my-chatbot/rules.txt"
  environment:
    - name: MESHAGENT_TOKEN
      token:
        identity: my-chatbot
  storage:
    room:
      - path: /data
        read_only: false

You can easily extend the agent with additional channels and toolkits using CLI flags as needed, see meshagent process join --help for more options. Validate and deploy to a room:
bash
meshagent service validate --file "meshagent.yaml"

meshagent service create --file "meshagent.yaml" --room myroom
To deploy as a project service use --global instead of --room myroom

Example 2: Deploying a ServiceTemplate

Now let’s convert the chatbot from Example 1 into a ServiceTemplate. We’ll add a variables section so users can choose a language for the chatbot to respond in at install time. This is also a complete manifest. Copy it into meshagent.yaml when you want installer-provided values.
kind: ServiceTemplate
version: v1
metadata:
  name: my-language-chatbot
  description: "A chatbot with web search and storage that responds in your chosen language"
  annotations:
    meshagent.service.id: "my-language-chatbot"
variables:
  - name: language
    description: "The language the chatbot should respond in (e.g. English, Spanish, French)"
agents:
  - name: my-language-chatbot
    description: "A helpful chatbot"
    annotations:
      meshagent.agent.type: "ChatBot"
container:
  image: "meshagent/cli:default"
  command: >-
    meshagent process join
    --agent-name my-language-chatbot
    --channel chat
    --require-web-search
    --require-storage
    --rule "You are a helpful assistant. Always respond in {{ language }}. Use web search to find current information and save important findings to storage."
    --room-rules "agents/my-language-chatbot/rules.txt"
  environment:
    - name: MESHAGENT_TOKEN
      token:
        identity: my-language-chatbot
  storage:
    room:
      - path: /data
        read_only: false

The differences from Example 1 are:
  • kind changed from Service to ServiceTemplate.
  • variables added with a single variable, language. This is what users provide at deploy time.
  • container.command now includes {{ language }} in the --rule flag. MeshAgent substitutes the user’s value when rendering the template into a Service.
Validate and deploy, providing the variable value:
bash
meshagent service validate-template --file "meshagent.yaml"

meshagent service create-template --file "meshagent.yaml" --value language=Spanish --room myroom
ServiceTemplate is the right choice when the manifest shape stays the same but one or more values need to be supplied when the service is created. When creating shareable install links for other users to add your agent to Powerboards, use ServiceTemplate.

Deploying and Managing Services CLI Reference

Deploy commands

Deploy a Service:
bash
# To a specific room
meshagent service create --file meshagent.yaml --room myroom

# To the entire project (available in every room)
meshagent service create --file meshagent.yaml --global
Deploy a ServiceTemplate:
bash
# To a specific room
meshagent service create-template --file meshagent.yaml --value key=value --room myroom

# To the entire project
meshagent service create-template --file meshagent.yaml --value key=value --global

List services

View services deployed to a room:
meshagent service list --room myroom
This returns each service’s ID, name, and the applicable image associated to it. You’ll need the service ID for update and delete commands. View globally deployed services when you do not pass --room:
meshagent service list

Update a service

bash
# Update a room Service
meshagent service update --file meshagent.yaml --room myroom --id SERVICE_ID

# Update a project Service
meshagent service update --file meshagent.yaml --global --id SERVICE_ID

# Update a room ServiceTemplate
meshagent service update-template --file meshagent.yaml --value key=value --room myroom --id SERVICE_ID

# Update a project ServiceTemplate
meshagent service update-template --file meshagent.yaml --value key=value --global --id SERVICE_ID

Delete a service

bash
# Delete a room Service or ServiceTemplate
meshagent service delete SERVICE_ID --room myroom

# Delete a project Service or ServiceTemplate
meshagent service delete SERVICE_ID

Managing Services from MeshAgent Studio

You can also manage deployed services from MeshAgent Studio. Navigate to your room or project to view, edit, and remove services from the UI.

How Service Configuration Files Are Structured

Every service configuration starts with version: v1, a kind (Service or ServiceTemplate), and a metadata section. You must also include either container or external. At a high level, the major sections are:
  • metadata — The service’s name, description, and display information.
  • agents — The participant identities this service provides to the room.
  • container or external — What actually runs. container tells MeshAgent what image to run. external points to a service you already host elsewhere.
  • ports — Optional routing information for HTTP and MCP endpoints.
  • variables — User-supplied install-time values. ServiceTemplate only.

metadata

metadata identifies the service in the UI and in install flows. For most services, the minimum useful fields are name, description, and any annotations needed by Studio or Powerboards.

agents

agents declares the identities your service brings into the room. This is how MeshAgent knows which participants the service can connect as, and how clients know what kind of agent to display.

container or external

This is the core runtime definition.
  • Use container when MeshAgent should pull an image and run it for you.
  • Use external when the service already exists somewhere else and MeshAgent only needs to route traffic to it.

container runtime behavior

The most important runtime fields are:
  • image — The container image to run. You almost always need this.
  • command — The command MeshAgent starts in the container. Set this when the image does not already start the right process by default.
  • working_dir — The absolute directory MeshAgent starts the command in. Set this only when your process expects to start from a specific path or uses relative file paths.
  • on_demand — Starts the container only when explicitly invoked instead of as an always-on room or project service.
  • private — Advanced setting for interactive container access. Leave the default true for most services. Only change this if you are intentionally building a shared interactive container workflow and understand how container access should be exposed.
Think of working_dir as “run this command after cd /some/path”. private does not control whether the service is visible in the room or project; it only affects interactive container access behavior.

container storage and write access

Most services should treat the container root filesystem as read-only and use mounts for any data they need to read or write.
  • storage.room — Room-scoped persistent storage. Best for files the service should keep with the room.
  • storage.project — Project-wide shared storage. Best for shared assets or reference data.
  • storage.files — Inline text content mounted as files.
  • storage.images — Static assets mounted from another image.
  • storage.empty_dirs — Writable scratch directories inside the container.
  • writable_root_fs — Makes the container root filesystem writable. Use this when the process expects to write under paths like /tmp, $HOME, or its own installed working area.
In practice:
  • Use storage.room for durable room data.
  • Use storage.empty_dirs for temporary writable workspaces.
  • Use writable_root_fs only when the process expects normal filesystem writes across the image and targeted mounts are not enough.
  • Treat writable_root_fs as ephemeral runtime state, not durable storage. Files written there are local to that container instance and are lost if the container is recreated.

container environment and secrets

Environment variables are how most services receive configuration and credentials at startup.
  • Use environment[].value for plain configuration.
  • Use environment[].token when the service needs a MeshAgent participant token.
  • Use environment[].secret when the service needs a room-scoped secret as a single environment variable.
  • Use container.secrets when you want to inject an entire project keys secret into the container as environment variables.
  • Use pull_secret only for authenticating to a private image registry when MeshAgent pulls the image.

ports

ports is only needed when MeshAgent must route HTTP or MCP traffic to the service. A process service that joins the room directly with meshagent process join ... usually does not need any ports section at all. ports is much more typical for endpoint-based services such as meshagent process service ..., custom HTTP services, MCP servers, or external services.

when to define ports

Use ports when:
  • the service is exposing endpoints for MeshAgent to call, such as with meshagent process service ...
  • the container exposes an HTTP server that MeshAgent needs to call
  • you are registering an MCP endpoint
  • you want liveness checks or internet-facing routing
Skip ports when:
  • the process connects directly to the room with meshagent process join ... and does not expose an HTTP service MeshAgent needs to reach

endpoint types and exposure

Within ports.endpoints:
  • meshagent endpoints represent MeshAgent-native agents or tools
  • mcp endpoints register MCP servers as toolkits
The main exposure controls are:
  • public — Whether requests require a participant token
  • published — Whether the port can receive traffic from the public internet
  • liveness — The HTTP path MeshAgent uses for health checks

variables

variables exists only on ServiceTemplate. It defines the values a user, installer, or automation provides when the template is rendered into a concrete Service. Common fields include:
  • name — The template variable name referenced as {{ name }}
  • title and description — Human-readable labels shown to installers
  • enum — Allowed choices
  • optional — Whether the value can be left blank
  • obscure — Whether the value should be hidden in install UI

Service Configuration Field Reference

The tables below document every field in the service configuration YAML.

Top-Level Fields

FieldRequiredDescription
versionYesSchema version. Always v1.
kindYesService or ServiceTemplate.
metadataYesService identity and display information.
agentsNoAgent identities exposed by this service.
portsNoNetwork ports and HTTP endpoints MeshAgent can route to.
container*Container configuration. Mutually exclusive with external.
external*External service URL. Mutually exclusive with container.
variablesNoUser-provided inputs for templating. ServiceTemplate only.
* Either container or external is required, but not both.

metadata

Identifies the service and provides information displayed in the UI.
FieldTypeRequiredDescription
namestringYesUnique service name.
descriptionstringNoDescription shown in UI.
repostringNoSource code repository URL.
iconstringNoIcon or emoji for UI display.
annotationsobjectNoKey-value metadata. See Annotations.

agents

Declares the participant identities this service provides. MeshAgent uses this to route requests, apply policies, and display agents in the UI.
FieldTypeRequiredDescription
namestringYesUnique agent identity within the service.
descriptionstringNoDisplay text describing the agent.
annotationsobjectNoKey-value metadata. See Annotations.

container

Defines a container for MeshAgent to run. Fields marked are only available in Service, not ServiceTemplate.
FieldTypeRequiredDescription
imagestringYesContainer image (e.g. meshagent/cli:default).
commandstringNoCommand to execute when the container starts.
working_dirstringNoAbsolute working directory used when starting the container command.
environmentlistNoEnvironment variables to set in the container.
secretslistNoIDs of project keys secrets to inject as environment variables. Service only.
pull_secretstringNoProject secret ID for authenticating with a private container registry. Service only.
storageobjectNoStorage volumes to mount into the container.
api_keyobjectNoAuto-provision an admin API key and inject it into the container.
on_demandbooleanNoWhen true, the container runs only when explicitly invoked.
writable_root_fsbooleanNoAllow writes to the container’s root filesystem for the life of that container instance. Default: read-only.
privatebooleanNoAdvanced setting that keeps interactive container access private to the owning service. Default: true.

container.environment

Each entry sets an environment variable in the container. A variable can come from a literal value, a MeshAgent token, or a room secret.
FieldTypeRequiredDescription
namestringYesEnvironment variable name.
valuestringNoLiteral string value.
tokenobjectNoRequest a participant token to be generated and injected as the value.
secretobjectNoLoad a room secret for a specific identity and inject it as the value.
Use:
  • value for plain configuration
  • token for MeshAgent API access
  • secret for room-scoped credentials
token fields:
FieldTypeRequiredDescription
identitystringYesParticipant identity the token is issued for.
apiobjectNoAPI scope granted to the token. See API Scopes.
rolestringNoParticipant role (e.g. user, agent, tool).
secret fields:
FieldTypeRequiredDescription
identitystringYesParticipant or service identity that owns the room secret.
idstringYesRoom secret ID to load.
This pattern is common for room services: token gives the service access to MeshAgent, while secret gives it an external credential.

container.storage

Mounts storage volumes into the container.
FieldTypeDescription
roomlistPer-room storage. Read/write by default.
projectlistProject-wide shared storage. Read-only by default.
imageslistContent from another container image. Read-only by default.
fileslistInline text content mounted as a file. Read-only by default.
empty_dirslistWritable temporary directories mounted into the container.
Room and project mount fields:
FieldTypeRequiredDescription
pathstringYesMount path inside the container.
subpathstringNoSubdirectory within the storage volume.
read_onlybooleanNoWhether the mount is read-only.
Image mount fields:
FieldTypeRequiredDescription
imagestringYesSource container image.
pathstringYesMount path inside the container.
subpathstringNoSubdirectory within the image.
read_onlybooleanNoWhether the mount is read-only.
File mount fields:
FieldTypeRequiredDescription
pathstringYesMount path inside the container.
textstringYesFile contents.
read_onlybooleanNoWhether the mount is read-only.
Empty directory mount fields:
FieldTypeRequiredDescription
pathstringYesMount path inside the container.
read_onlybooleanNoWhether the temporary directory is read-only.

container.api_key

Provisions an admin API key and injects it into the container. Service only.
FieldTypeRequiredDescription
rolestringYesAlways admin.
namestringYesName for the API key.
auto_provisionbooleanNoAutomatically provision on deployment.

external

Routes traffic to a service running outside MeshAgent. Requires ports to define how MeshAgent reaches the service.
FieldTypeRequiredDescription
urlstringYesURL where the service is running.

ports

Defines network ports the service listens on and how MeshAgent routes HTTP traffic to them.
FieldTypeRequiredDescription
num"*" or intYesPort number, or "*" for auto-assignment.
typestringNoProtocol: http or tcp.
livenessstringNoHTTP path for health checks.
endpointslistNoEndpoints served on this port.
publishedbooleanNoExpose the port to the internet.
publicbooleanNoWhen false, requests must include a participant token.
annotationsobjectNoKey-value metadata.

ports.endpoints

Each endpoint maps a URL path to either a MeshAgent-native service or an MCP server.
FieldTypeRequiredDescription
pathstringYesURL path for this endpoint.
meshagentobjectNoMeshAgent-native endpoint. Mutually exclusive with mcp.
mcpobjectNoMCP server endpoint. Mutually exclusive with meshagent.
annotationsobjectNoKey-value metadata.
meshagent endpoint
Connects the endpoint to a MeshAgent participant identity.
FieldTypeRequiredDescription
identitystringYesParticipant identity for this endpoint.
apiobjectNoAPI scope overrides. See API Scopes.
mcp endpoint
Registers an MCP server as a toolkit in the room.
FieldTypeRequiredDescription
labelstringYesToolkit display name.
descriptionstringNoDescription of what the toolkit provides.
allowed_toolslistNoFilters which tools are exposed.
headersobjectNoCustom HTTP headers to include in requests.
require_approvalstringNoalways or never.
oauthobjectNoOAuth client configuration.
openai_connector_idstringNoOpenAI connector ID.
allowed_tools entries:
FieldTypeRequiredDescription
tool_nameslistYesTool names to allow.
read_onlybooleanNoTreat the tools as read-only.
oauth fields:
FieldTypeRequiredDescription
client_idstringYesOAuth client ID.
client_secretstringNoOAuth client secret.
authorization_endpointstringYesAuthorization endpoint URL.
token_endpointstringYesToken endpoint URL.
no_pkcebooleanNoDisable PKCE (Proof Key for Code Exchange).
scopeslistNoOAuth scopes to request.

variables (ServiceTemplate only)

Defines user-provided inputs for a ServiceTemplate. Values are substituted into the YAML using {{ variable_name }} syntax (Jinja templating). Template values are rendered into the manifest before validation, so they can be used anywhere the resulting YAML remains valid.
FieldTypeRequiredDescription
namestringYesVariable identifier. Referenced as {{ name }} in templates.
titlestringNoHuman-readable label shown in install UI.
descriptionstringNoHelp text shown in UI and Powerboards.
enumlistNoRestricts input to specific values. Displayed as a dropdown.
optionalbooleanNoWhether the variable can be left blank.
obscurebooleanNoHides the value in UI. Use for sensitive data.
typestringNoType hint (e.g. email).
annotationsobjectNoKey-value metadata. See Annotations.
ServiceTemplate variables are the secure install-time input mechanism for installer-provided secrets. Powerboards can use variable annotations such as meshagent.secret.id and meshagent.secret.identity to collect a sensitive value during install and store it as a room secret for later use.

Annotations

Annotations are key-value strings attached to services, agents, or variables. MeshAgent and Powerboards use specific annotation keys to control behavior. You can also define custom annotations.

Service Annotations

Set in metadata.annotations.
KeyDescription
meshagent.service.idUnique identifier for the service.
meshagent.service.readmeURL or inline content for the service’s documentation.

Agent Annotations

Set in agents[].annotations.
KeyDescription
meshagent.agent.typeInternal agent type metadata used by service manifests and generated specs.
meshagent.agent.widgetUI widget to display for this agent.
meshagent.agent.scheduleJSON string defining a scheduled task and its payload.
meshagent.agent.shell.commandShell command for Shell-type agents.
meshagent.agent.database.schemaDatabase schema metadata for the agent.

Variable Annotations

Set in variables[].annotations.
KeyDescription
meshagent.secret.idSecret ID to create or update when Powerboards stores the value as a room secret.
meshagent.secret.identityIdentity that should own the created room secret.
meshagent.secret.nameDisplay name to use for the created room secret.
meshagent.secret.typeSecret type metadata for the stored room secret.

Event Annotations

Set in agents[].annotations. Subscribe an agent to room events. The value is the name of a queue that a queue-consuming agent can process.
KeyDescription
meshagent.events.service.createdFires when a service is created in the room.
meshagent.events.service.updatedFires when a service is updated.
meshagent.events.room.user.grant.createFires when a user is added to the room.
meshagent.events.room.user.grant.deleteFires when a user is removed from the room.
meshagent.events.room.user.grant.updateFires when a user’s room grant is updated.

Webhook Annotations

Set in agents[].annotations.
KeyDescription
meshagent.webhook.processorIdentifies the agent as a webhook processor.
meshagent.webhook.queueQueue name for incoming webhook payloads.
meshagent.webhook.validation.methodMethod used to validate webhook signatures.
meshagent.webhook.validation.secretSecret ID used for webhook signature validation.

Deployment Examples

Step-by-step guides for common deployment patterns: