Skip to main content

Workflow: MCP Server (McpTool & McpResource)

Every organization gets its own MCP (Model Context Protocol) server whose tools and resources are defined as workflows. AI assistants and agents (Claude, Claude Code, and any other MCP-compatible client) connect to your organization's MCP endpoint and can only see and call what your organization has explicitly defined — none of the platform's built-in tools are exposed there.

Two workflow types drive the MCP server:

  • McpTool — exposes the workflow as an MCP tool the AI can call with arguments
  • McpResource — exposes the workflow as an MCP resource the AI can read (documentation, glossaries, live reference data)

MCP workflows are ideal when you need to:

  • Give AI assistants safe, curated access to your TMS data and actions
  • Build an org-specific AI toolset (order lookups, quote calculations, status updates) backed by workflow logic
  • Publish org knowledge (shipping terms, process guides, live reference data) that AI assistants can read as resources
  • Control exactly what an AI can do — the tool surface is precisely the set of McpTool workflows you activate

Endpoint

Each organization's MCP server is served at:

/public-api/v1/{orgUniqueId}/mcp

Where {orgUniqueId} is your organization's unique identifier (UUID format).

The server uses the MCP Streamable HTTP transport in stateless mode — clients POST JSON-RPC messages (initialize, tools/list, tools/call, resources/list, resources/read) directly to this URL.

Authentication

The MCP endpoint requires a Bearer token — either a user JWT or a Personal Access Token (PAT):

Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

In addition to a valid token, the caller must be a member of the organization in the URL. Access is rejected otherwise:

StatusCondition
401Missing or invalid token. The response includes a WWW-Authenticate: Bearer resource_metadata="..." challenge for OAuth-capable MCP clients
403Valid token, but the user is not a member of the organization (system administrators are exempt)
404Unknown organization identifier

Unlike Public API workflows, MCP workflows do not have a per-workflow authentication setting — authentication is enforced once at the connection level for the whole server.

Server Configuration

The MCP server's identity and instructions come from the organization configuration named tms.mcp:

KeyApplied toDefault
nameServer name shown to MCP clients"{orgUniqueId} MCP Server"
versionServer version"1.0.0"
instructionsServer instructions — guidance the AI receives about how to use your toolsnone

Use instructions to orient the AI: describe your organization's terminology, when to use which tool, and any conventions it should follow. The configuration is optional — missing values fall back to the defaults above.

MCP Tools (workflowType: McpTool)

An McpTool workflow becomes a callable MCP tool. The tool's name, description, and input schema are generated from the workflow manifest.

YAML Structure

mcp:
name: "get_order_status"
description: "Look up an order's current status by order number"
timeout: 60

workflow:
name: "MCP / Get Order Status"
workflowId: "00000000-0000-0000-0000-000000000000"
workflowType: "McpTool"
executionMode: "Sync" # Required: must be Sync
isActive: true

inputs:
- name: "orderNumber"
type: "string"
props:
required: true
description: "The TMS order number"

outputs:
- name: "response"
mapping: "stepName.result"

activities:
- name: myActivity
steps:
- task: "SomeTask@1"
name: "stepName"
# ...

The mcp Section (Tools)

PropertyTypeRequiredDefaultDescription
namestringYes-Tool name shown to the AI. Must match ^[a-zA-Z0-9_-]{1,64}$ (letters, digits, _, -). Must be unique within the organization
descriptionstringNo-Tool description — this is how the AI decides when to use the tool, so make it specific
timeoutnumberNo60Workflow execution timeout in seconds

If two active workflows declare the same tool name, the first one (by workflow ID) wins and a warning is logged.

Inputs → Tool Schema

The workflow's inputs section is translated into the tool's JSON Schema, which MCP clients show to the AI. Unlike Public API workflows, there is no props.in location — MCP tools take named arguments, and each input becomes a named schema property.

Input typeJSON Schema type
string (or omitted / unknown)string
integer / intinteger
number / decimal / float / doublenumber
boolean / boolboolean
objectobject
arrayarray

Input props:

PropertyTypeDescription
requiredbooleanMarks the argument as required in the tool schema. Calls missing a required argument are rejected before the workflow runs
descriptionstringArgument description shown to the AI

Argument values are validated and coerced the same way as Public API inputs: numbers and booleans accept native JSON values or parseable strings, and invalid values produce a per-argument error message. Extra arguments not declared in inputs are passed through to the workflow as-is.

Outputs

The workflow's response output becomes the tool result, serialized as JSON:

Output NameRequiredDescription
responseNoThe tool result returned to the AI. If omitted, the full outputs dictionary is returned instead
outputs:
- name: "response"
mapping: "fetchData.result"

Execution Semantics

  • Tools execute the workflow synchronously (executionMode: Sync is required).
  • If the workflow fails or times out, the tool returns an error result (isError: true) with the failure message — the AI sees the error and can react or retry.
  • If the arguments are invalid (missing required, wrong type), the tool returns an error result listing the problems and the workflow is not executed.
  • Calling an unknown tool name returns an MCP protocol error.

MCP Resources (workflowType: McpResource)

An McpResource workflow becomes a readable MCP resource. Reading the resource executes the workflow and returns its response output as the content.

YAML Structure

mcp:
uri: "tms://docs/shipping-terms"
name: "Shipping Terms Glossary"
description: "Org-specific shipping terminology used in orders"
mimeType: "text/markdown"
timeout: 60

workflow:
name: "MCP / Shipping Terms Glossary"
workflowId: "00000000-0000-0000-0000-000000000000"
workflowType: "McpResource"
executionMode: "Sync" # Required: must be Sync
isActive: true

outputs:
- name: "response"
mapping: "buildContent.result"

activities:
- name: content
steps:
- task: "Utilities/SetVariable@1"
name: "buildContent"
# ...

The mcp Section (Resources)

PropertyTypeRequiredDefaultDescription
uristringYes-Resource URI. Must be an absolute URI (any scheme, e.g. tms://docs/shipping-terms). Must be unique within the organization
namestringNoworkflow nameDisplay name shown to the AI
descriptionstringNo-Resource description
mimeTypestringNoapplication/jsonContent MIME type
timeoutnumberNo60Workflow execution timeout in seconds

Content Mapping

  • If the response output is a string and mimeType starts with text/ (e.g. text/markdown, text/plain), the string is returned as-is.
  • Otherwise, the response output (or the full outputs dictionary when there is no response) is JSON-serialized.
  • Resources execute with no input arguments.
  • Workflow failures and timeouts surface as MCP protocol (JSON-RPC) errors — resources have no isError result form.

Validation Rules

MCP workflows are validated at save time:

CodeRule
MCP_001mcp section is required
MCP_002mcp.name is required for McpTool workflows
MCP_003mcp.name must match ^[a-zA-Z0-9_-]{1,64}$
MCP_004mcp.uri is required for McpResource workflows
MCP_005mcp.uri must be an absolute URI
MCP_006mcp.timeout must be zero (use default) or positive
MCP_007executionMode must be Sync

See Workflow Validation Errors for details and solutions.

Connecting an MCP Client

Point any MCP-compatible client at your organization's endpoint with a Bearer token. For example, in Claude Code (.mcp.json):

{
"mcpServers": {
"my-org-tms": {
"type": "http",
"url": "https://your-domain.com/public-api/v1/{orgUniqueId}/mcp",
"headers": {
"Authorization": "Bearer ${TMS_PAT}"
}
}
}
}

You can also probe the server directly with curl:

curl -X POST "https://your-domain.com/public-api/v1/{orgUniqueId}/mcp" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Examples

Example 1: Tool - Get Order Status

mcp:
name: "get_order_status"
description: "Look up a TMS order's current status, dates, and customer by order number. Use when the user asks about a specific order."
timeout: 30

workflow:
name: "MCP / Get Order Status"
workflowId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
workflowType: "McpTool"
executionMode: "Sync"
isActive: true

inputs:
- name: "orderNumber"
type: "string"
props:
required: true
description: "The order number, e.g. ORD-2026-0001"

outputs:
- name: "response"
mapping: "fetchOrder.result"

activities:
- name: lookup
steps:
- task: "Query/GraphQL@1"
name: "fetchOrder"
inputs:
query: |
query {
orders(
organizationId: {{ organizationId }},
filter: { orderNumber: "{{ orderNumber }}" },
take: 1
) {
items {
orderId
orderNumber
orderDate
orderStatus { orderStatusName }
customer { name }
}
}
}
outputs:
- name: "result"
mapping: "orders.items"

When the AI calls get_order_status with {"orderNumber": "ORD-2026-0001"}, the workflow runs and the tool returns the serialized order data.

Example 2: Resource - Shipping Terms Glossary

mcp:
uri: "tms://docs/shipping-terms"
name: "Shipping Terms Glossary"
description: "Definitions of org-specific shipping terminology"
mimeType: "text/markdown"

workflow:
name: "MCP / Shipping Terms Glossary"
workflowId: "b2c3d4e5-f6a7-8901-bcde-f23456789012"
workflowType: "McpResource"
executionMode: "Sync"
isActive: true

outputs:
- name: "response"
mapping: "content.result"

activities:
- name: glossary
steps:
- task: "Utilities/SetVariable@1"
name: "content"
inputs:
variables:
- name: "result"
value: |
# Shipping Terms

- **FOB** — Free on Board: seller covers costs until goods are loaded
- **Linehaul** — Long-distance transport between terminals
- **Drayage** — Short-distance container transport, typically port to warehouse

Because the response is a string and the mimeType is text/markdown, the AI receives the markdown content as-is when it reads tms://docs/shipping-terms.

Best Practices

  • Write tool descriptions for the AI, not for humans — say when to use the tool and what it returns
  • Use snake_case tool names (get_order_status, create_quote) — the common MCP convention
  • Mark required arguments with props.required and describe every argument — the schema is all the AI sees
  • Set instructions in the tms.mcp config to give the AI org-level context that applies across tools
  • Keep timeouts realistic — AI clients wait synchronously for tool results
  • Use resources for stable knowledge (glossaries, guides) and tools for parameterized data access
  • Deactivate a workflow (isActive: false) to instantly remove its tool/resource from the server