This document provides a complete reference for the Model Context Interface (MCI) schema v1. It describes all fields, types, execution configurations, authentication options, and templating syntax supported by the MCI Python adapter.
- Overview
- Top-Level Schema Structure
- Metadata
- Tool Definition
- Execution Types
- Authentication
- Templating Syntax
- Execution Result Format
MCI (Model Context Interface) uses a schema to define tools that AI agents can execute. The schema can be written in either JSON or YAML format - both are fully supported and produce identical results.
Each tool specifies:
- What it does (metadata and description)
- What inputs it accepts (JSON Schema)
- How to execute it (execution configuration)
The schema is designed to be platform-agnostic, secure (secrets via environment variables), and supports multiple execution types.
Schema Version: 1.0
Supported File Formats:
- JSON (
.json) - YAML (
.yaml,.yml)
The root MCI context file has these main fields:
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion |
string | Required | MCI schema version (e.g., "1.0") |
metadata |
object | Optional | Descriptive metadata about the tool collection |
tools |
array | Optional* | Array of tool definitions |
toolsets |
array | Optional* | Array of toolset references to load from library |
mcp_servers |
object | Optional | MCP servers to register and cache (see MCP Servers) |
libraryDir |
string | Optional | Directory to find toolset files (default: "./mci") |
enableAnyPaths |
boolean | Optional | Allow any file path (default: false) |
directoryAllowList |
array | Optional | Additional allowed directories (default: []) |
Note: Either tools, toolsets, or mcp_servers (or any combination) must be provided.
toolsets (array, optional)
- Array of toolset definitions that reference tool collections in the library directory
- Each toolset can optionally apply schema-level filtering to control which tools are loaded
- Allows organizing tools into reusable, modular collections
libraryDir (string, default: "./mci")
- Directory path where toolset files are located, relative to the main schema file
- Can be customized to use a different directory structure
Each toolset object supports these fields:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Required | Name of toolset file/directory in libraryDir |
filter |
string | Optional | Filter type: "only", "except", "tags", or "withoutTags" |
filterValue |
string | Required* | Comma-separated list of tool names or tags |
* Required when filter is specified
Toolset Name Resolution:
- First checks for a directory:
{libraryDir}/{name}/- If found, loads all
.mci.jsonfiles in the directory
- If found, loads all
- Then checks for direct file:
{libraryDir}/{name} - Then checks with extension:
{libraryDir}/{name}.mci.json - Also supports
.mci.yamland.mci.ymlextensions
Schema-Level Filters:
only: Include only tools with specified namesexcept: Exclude tools with specified namestags: Include only tools with at least one matching tagwithoutTags: Exclude tools with any matching tag
enableAnyPaths (boolean, default: false)
- When
true, disables all path validation for file and CLI execution - When
false(default), restricts access to schema directory and allowed directories - Can be overridden per-tool
- Use with caution - enables access to any file on the system
directoryAllowList (array of strings, default: [])
- List of additional directories to allow for file/CLI access
- Can be absolute paths (e.g.,
/home/user/data) or relative to schema directory (e.g.,./configs) - Schema directory is always allowed by default
- Can be overridden per-tool
The mcp_servers field enables integration with Model Context Protocol servers.
mcp_servers (object, optional)
- Object mapping server names to MCP server configurations
- Allows integration with Model Context Protocol (MCP) servers
- Tools from MCP servers are automatically cached in
{libraryDir}/mcp/directory - Each server configuration can include filtering and expiration settings
- Supports both STDIO (local command-based) and HTTP (web-based) servers
Each server in the mcp_servers object has a unique name as the key and a configuration object with these fields:
STDIO Configuration:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
command |
string | Yes | - | Command to execute (e.g., "npx", "uvx") |
args |
array of strings | No | [] |
Arguments to pass to the command |
env |
object | No | {} |
Environment variables for the server process |
config |
object | No | - | Optional caching and filtering configuration |
HTTP Configuration:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type |
string | Yes | - | Must be "http" |
url |
string | Yes | - | Server URL endpoint |
headers |
object | No | {} |
HTTP headers (e.g., for authentication) |
config |
object | No | - | Optional caching and filtering configuration |
Config Object Fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
expDays |
integer | No | 30 |
Number of days until cached toolset expires |
filter |
string | No | - | Filter type: "only", "except", "tags", "withoutTags" |
filterValue |
string | No | - | Comma-separated list of tool names or tags (required if filter) |
STDIO Server with Filtering:
{
"mcp_servers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"],
"env": {
"DEBUG": "1"
},
"config": {
"expDays": 7,
"filter": "except",
"filterValue": "delete_file,format_disk"
}
}
}
}HTTP Server with Authentication:
{
"mcp_servers": {
"api_server": {
"type": "http",
"url": "https://api.example.com/mcp/",
"headers": {
"Authorization": "Bearer {{env.API_TOKEN}}"
},
"config": {
"expDays": 30
}
}
}
}Multiple MCP Servers:
{
"mcp_servers": {
"memory": {
"command": "uvx",
"args": ["mcp-server-memory"]
},
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer {{env.GITHUB_MCP_PAT}}"
},
"config": {
"expDays": 14,
"filter": "tags",
"filterValue": "read,search"
}
}
}
}How MCP Servers Work:
- First Load: When the schema is loaded, MCI connects to each MCP server and fetches all available tools
- Caching: Tools are saved as standard MCI toolset files in
{libraryDir}/mcp/{serverName}.mci.json - Subsequent Loads: Cached toolsets are used instead of connecting to the server (much faster)
- Expiration: When cache expires (based on
expDays), tools are re-fetched from the server - Filtering: Optional filters are applied when tools are registered
- Templating: Server configurations support
{{env.VAR}}templating for credentials
{
"schemaVersion": "1.0",
"metadata": {
"name": "My API Tools",
"description": "Tools for interacting with my API",
"version": "1.0.0",
"license": "MIT",
"authors": ["John Doe"]
},
"enableAnyPaths": false,
"directoryAllowList": ["/home/user/data", "./configs"],
"tools": []
}{
"schemaVersion": "1.0",
"metadata": {
"name": "My Application",
"description": "Main application with multiple tool libraries"
},
"libraryDir": "./mci",
"tools": [
{
"name": "main_tool",
"description": "Main application tool",
"execution": {
"type": "text",
"text": "Main tool output"
}
}
],
"toolsets": [
{
"name": "weather",
"filter": "only",
"filterValue": "get_weather, get_forecast"
},
{
"name": "database",
"filter": "withoutTags",
"filterValue": "destructive"
},
{
"name": "github"
}
]
}schemaVersion: '1.0'
metadata:
name: My API Tools
description: Tools for interacting with my API
version: 1.0.0
license: MIT
authors:
- John Doe
enableAnyPaths: false
directoryAllowList:
- /home/user/data
- ./configs
tools: []Toolset files are MCI schema files stored in the library directory (default: ./mci). They provide a way to organize and reuse tool collections across different main schemas.
Toolset files have a simplified structure compared to main schemas:
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion |
string | Required | MCI schema version (must match main schema) |
metadata |
object | Optional | Descriptive metadata about the toolset |
tools |
array | Required | Array of tool definitions |
Important Differences from Main Schema:
toolsfield is required in toolset files (optional in main schema)- Cannot contain
toolsets,libraryDir,enableAnyPaths, ordirectoryAllowListfields - These are purely tool definition files, not configuration files
File: ./mci/weather.mci.json
{
"schemaVersion": "1.0",
"metadata": {
"name": "Weather Toolset",
"description": "Tools for weather information",
"version": "1.0.0"
},
"tools": [
{
"name": "get_weather",
"description": "Get current weather",
"tags": ["weather", "read"],
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or location"
}
},
"required": ["location"]
},
"execution": {
"type": "http",
"method": "GET",
"url": "https://api.weather.com/current",
"params": {
"location": "{{props.location}}"
}
}
},
{
"name": "get_forecast",
"description": "Get weather forecast",
"tags": ["weather", "read"],
"execution": {
"type": "http",
"method": "GET",
"url": "https://api.weather.com/forecast",
"params": {
"location": "{{props.location}}",
"days": "{{props.days}}"
}
}
}
]
}You can organize related toolsets in subdirectories:
project/
├── main.mci.json # Main schema
└── mci/ # Library directory
├── weather.mci.json # Single-file toolset
├── database.mci.json # Single-file toolset
└── github/ # Directory-based toolset
├── prs.mci.json # GitHub PR tools
└── issues.mci.json # GitHub issue tools
When referencing a directory-based toolset:
{
"toolsets": [
{"name": "github"} // Loads all .mci.json files in mci/github/
]
}Important notes for directory-based toolsets:
- Only tools are merged from toolset files; metadata is not merged
- All files in a directory must use the same schema version
- Schema version mismatch will raise an error to ensure compatibility
Metadata in toolset files:
- Metadata in toolset files is for demonstration and documentation purposes only
- It helps credit toolset authors and provides human-friendly descriptions
- Metadata is never merged into the main schema from toolset files }
---
## Metadata
Optional metadata about the tool collection.
| Field | Type | Required | Description |
| ------------- | ------ | -------- | -------------------------------------------------- |
| `name` | string | Optional | Name of the tool collection |
| `description` | string | Optional | Description of the tool collection |
| `version` | string | Optional | Version of the tool collection (e.g., SemVer) |
| `license` | string | Optional | License identifier (e.g., `"MIT"`, `"Apache-2.0"`) |
| `authors` | array | Optional | Array of author names |
### Example (JSON)
```json
{
"name": "Weather API Tools",
"description": "Tools for fetching weather information",
"version": "1.2.0",
"license": "MIT",
"authors": ["Weather Team", "API Team"]
}
name: Weather API Tools
description: Tools for fetching weather information
version: 1.2.0
license: MIT
authors:
- Weather Team
- API TeamEach tool in the tools array represents a single executable operation.
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Required | Unique identifier for the tool |
disabled |
boolean | Optional | If true, the tool is ignored (default: false) |
annotations |
object | Optional | Metadata and behavioral hints (see Annotations) |
description |
string | Optional | Description of what the tool does |
inputSchema |
object | Optional | JSON Schema describing expected inputs |
execution |
object | Required | Execution configuration (see Execution Types) |
enableAnyPaths |
boolean | Optional | Override schema-level path restriction (default: false) |
directoryAllowList |
array | Optional | Override schema-level allowed directories (default: []) |
tags |
array | Optional | Array of string tags for filtering (default: []) |
tags (array of strings, default: [])
- List of tags for categorizing and filtering tools
- Tags are case-sensitive and matched exactly as provided
- Used with
tags()andwithoutTags()filter methods in MCIClient and ToolManager - Tools can have zero or more tags
- Common tag examples:
"api","database","internal","external","deprecated"
disabled (boolean, default: false)
- When
true, the tool is excluded from all listing, filtering, and lookup operations - Disabled tools cannot be executed and behave as if they do not exist
- Useful for temporarily deactivating tools without removing them from the schema
The annotations object provides optional metadata and behavioral hints about the tool. All fields are optional.
| Field | Type | Description |
|---|---|---|
title |
string | Human-readable title for the tool |
readOnlyHint |
boolean | If true, the tool does not modify its environment |
destructiveHint |
boolean | If true, the tool may perform destructive updates |
idempotentHint |
boolean | If true, repeated calls with same args have no additional effect |
openWorldHint |
boolean | If true, the tool interacts with external entities |
Note: These hints are advisory and do not enforce any behavior. They help AI agents understand the tool's characteristics for better decision-making.
enableAnyPaths (boolean, default: false)
- Overrides schema-level setting for this specific tool
- When
true, disables path validation for this tool - Takes precedence over schema-level
enableAnyPaths
directoryAllowList (array of strings, default: [])
- Overrides schema-level setting for this specific tool
- List of additional directories allowed for this tool only
- Takes precedence over schema-level
directoryAllowList - Can be absolute or relative paths
{
"name": "get_weather",
"annotations": {
"title": "Get Weather Information",
"readOnlyHint": true,
"openWorldHint": true
},
"description": "Fetch current weather for a location",
"tags": ["api", "external", "weather"],
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or zip code"
},
"units": {
"type": "string",
"enum": ["metric", "imperial"],
"default": "metric"
}
},
"required": ["location"]
},
"execution": {
"type": "http",
"method": "GET",
"url": "https://api.weather.com/v1/current",
"params": {
"location": "{{props.location}}",
"units": "{{props.units}}"
}
}
}{
"name": "legacy_api",
"disabled": true,
"annotations": {
"title": "Legacy API Tool (Deprecated)"
},
"description": "This tool is disabled and will not be available",
"execution": {
"type": "http",
"url": "https://api.example.com/legacy"
}
}{
"name": "read_system_file",
"description": "Read a file with unrestricted access",
"enableAnyPaths": true,
"execution": {
"type": "file",
"path": "{{props.file_path}}"
}
}name: read_config
description: Read configuration from allowed directories
annotations:
title: Read Config
readOnlyHint: true
directoryAllowList:
- /etc/myapp
- ./configs
execution:
type: file
path: "{{props.config_path}}"name: delete_resource
annotations:
title: Delete Resource
readOnlyHint: false
destructiveHint: true
idempotentHint: false
openWorldHint: true
description: Delete a resource from the remote server
execution:
type: http
method: DELETE
url: "https://api.example.com/resources/{{props.id}}"The inputSchema field uses JSON Schema to define the expected properties for a tool. When executing a tool, the MCI adapter processes properties as follows:
- Required Properties: Must be provided, or execution will fail with a validation error
- Optional Properties with Defaults: If not provided, the default value is used
- Optional Properties without Defaults: If not provided, they are skipped (not included in template context)
This behavior prevents template substitution errors for optional properties that aren't needed for a particular execution.
{
"name": "search_files",
"description": "Search for text in files",
"inputSchema": {
"type": "object",
"properties": {
"pattern": {
"type": "string",
"description": "Search pattern"
},
"directory": {
"type": "string",
"description": "Directory to search in"
},
"include_images": {
"type": "boolean",
"description": "Include image files in search",
"default": false
},
"case_sensitive": {
"type": "boolean",
"description": "Use case-sensitive search",
"default": true
},
"max_results": {
"type": "number",
"description": "Maximum number of results",
"default": 100
},
"file_extensions": {
"type": "array",
"description": "Optional list of file extensions",
"items": {
"type": "string"
}
}
},
"required": ["pattern", "directory"]
},
"execution": {
"type": "http",
"method": "POST",
"url": "https://api.example.com/search",
"body": {
"type": "json",
"content": {
"pattern": "{{props.pattern}}",
"directory": "{{props.directory}}",
"include_images": "{!!props.include_images!!}",
"case_sensitive": "{!!props.case_sensitive!!}",
"max_results": "{!!props.max_results!!}",
"file_extensions": "{!!props.file_extensions!!}"
}
}
}
}Note: Use {!! ... !!} syntax for non-string types (boolean, number, array, object) to preserve their native JSON types. See JSON-Native Placeholders for more details.
Execution with minimal properties:
# Only required properties provided
client.execute("search_files", properties={
"pattern": "TODO",
"directory": "/home/user/projects"
})
# Result: include_images=false, case_sensitive=true, max_results=100 (defaults used)
# file_extensions is skipped (not in template, no default)Execution with overridden defaults:
# Some defaults overridden
client.execute("search_files", properties={
"pattern": "FIXME",
"directory": "/tmp",
"include_images": True,
"max_results": 50,
"file_extensions": [".py", ".js"]
})
# Result: include_images=true, max_results=50 (overridden), case_sensitive=true (default)
# file_extensions=[".py", ".js"] (provided)Property Resolution Rules:
- Properties provided at execution time always take precedence over defaults
- Default values can be any valid JSON type: boolean, number, string, array, object, null
- Optional properties without defaults are not included in the template context if not provided
- This prevents
{{props.optional_prop}}from causing errors whenoptional_propis not provided
MCI supports four execution types: http, cli, file, and text. The type field in the execution object determines which executor is used.
Execute HTTP requests to external APIs.
Type: "http"
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type |
string | Required | - | Must be "http" |
method |
string | Optional | "GET" |
HTTP method: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS |
url |
string | Required | - | Target URL (supports templating) |
headers |
object | Optional | - | HTTP headers as key-value pairs (supports templating) |
auth |
object | Optional | - | Authentication configuration (see Authentication) |
params |
object | Optional | - | Query parameters as key-value pairs (supports templating) |
body |
object | Optional | - | Request body configuration |
timeout_ms |
integer | Optional | 30000 |
Request timeout in milliseconds (must be ≥ 0) |
retries |
object | Optional | - | Retry configuration |
The body field defines the request body:
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Required | Body type: "json", "form", or "raw" |
content |
object/string | Required | Body content (object for json/form, string for raw) |
The retries field configures retry behavior:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
attempts |
integer | Optional | 1 |
Number of retry attempts (must be ≥ 1) |
backoff_ms |
integer | Optional | 500 |
Backoff delay in milliseconds (must be ≥ 0) |
GET Request with Query Parameters
{
"type": "http",
"method": "GET",
"url": "https://api.example.com/weather",
"params": {
"location": "{{props.location}}",
"units": "metric"
},
"headers": {
"Accept": "application/json"
},
"timeout_ms": 5000
}POST Request with JSON Body
{
"type": "http",
"method": "POST",
"url": "https://api.example.com/reports",
"headers": {
"Content-Type": "application/json",
"Accept": "application/json"
},
"body": {
"type": "json",
"content": {
"title": "{{props.title}}",
"content": "{{props.content}}",
"timestamp": "{{env.CURRENT_TIMESTAMP}}"
}
},
"timeout_ms": 10000
}POST Request with Form Data
{
"type": "http",
"method": "POST",
"url": "https://api.example.com/upload",
"body": {
"type": "form",
"content": {
"filename": "{{props.filename}}",
"category": "documents"
}
}
}Request with Retry Logic
{
"type": "http",
"method": "GET",
"url": "https://api.example.com/data",
"retries": {
"attempts": 3,
"backoff_ms": 1000
}
}Execute command-line tools and scripts.
Type: "cli"
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type |
string | Required | - | Must be "cli" |
command |
string | Required | - | Command to execute |
args |
array | Optional | - | Fixed positional arguments |
flags |
object | Optional | - | Dynamic flags mapped from properties |
cwd |
string | Optional | - | Working directory (supports templating) |
timeout_ms |
integer | Optional | 30000 |
Execution timeout in milliseconds (must be ≥ 0) |
Each flag in the flags object has:
| Field | Type | Required | Description |
|---|---|---|---|
from |
string | Required | Property path (e.g., "props.ignore_case") |
type |
string | Required | Flag type: "boolean" or "value" |
boolean: Flag is included only if the property is truthy (e.g.,-i)value: Flag is included with the property value (e.g.,--file=myfile.txt)
Basic CLI Command
{
"type": "cli",
"command": "grep",
"args": ["-r", "-n"],
"flags": {
"-i": {
"from": "props.ignore_case",
"type": "boolean"
}
},
"cwd": "{{props.directory}}",
"timeout_ms": 8000
}CLI with Value Flags
{
"type": "cli",
"command": "convert",
"args": ["input.png"],
"flags": {
"--resize": {
"from": "props.size",
"type": "value"
},
"--quality": {
"from": "props.quality",
"type": "value"
}
},
"cwd": "/tmp"
}Read and parse file contents with optional templating.
Type: "file"
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type |
string | Required | - | Must be "file" |
path |
string | Required | - | File path (supports templating) |
enableTemplating |
boolean | Optional | true |
Whether to process templates in file content |
When enableTemplating is true, the file contents are processed with the full templating engine (basic placeholders, loops, and conditionals).
Load Template File
{
"type": "file",
"path": "./templates/report-{{props.report_id}}.txt",
"enableTemplating": true
}Load Raw File
{
"type": "file",
"path": "/etc/config/settings.json",
"enableTemplating": false
}Return templated text directly.
Type: "text"
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Required | Must be "text" |
text |
string | Required | Text template (supports templating) |
The text is processed with the full templating engine (basic placeholders, loops, and conditionals).
Simple Message
{
"type": "text",
"text": "Hello {{props.username}}! This message was generated on {{env.CURRENT_DATE}}."
}Report with Conditionals
{
"type": "text",
"text": "Report for {{props.username}}\n@if(props.premium)Premium features enabled@else Standard features available @endif"
}HTTP execution supports four authentication types: API Key, Bearer Token, Basic Auth, and OAuth2.
Pass an API key in headers or query parameters.
Type: "apiKey"
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Required | Must be "apiKey" |
in |
string | Required | Where to send the key: "header" or "query" |
name |
string | Required | Header/query parameter name |
value |
string | Required | API key value (supports templating, typically {{env.API_KEY}}) |
API Key in Header
{
"type": "http",
"method": "GET",
"url": "https://api.example.com/data",
"auth": {
"type": "apiKey",
"in": "header",
"name": "X-API-Key",
"value": "{{env.API_KEY}}"
}
}API Key in Query Parameter
{
"type": "http",
"method": "GET",
"url": "https://api.example.com/data",
"auth": {
"type": "apiKey",
"in": "query",
"name": "api_key",
"value": "{{env.API_KEY}}"
}
}Pass a bearer token in the Authorization header.
Type: "bearer"
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Required | Must be "bearer" |
token |
string | Required | Bearer token (supports templating, typically {{env.BEARER_TOKEN}}) |
{
"type": "http",
"method": "POST",
"url": "https://api.example.com/reports",
"auth": {
"type": "bearer",
"token": "{{env.BEARER_TOKEN}}"
},
"body": {
"type": "json",
"content": {
"title": "{{props.title}}"
}
}
}Use HTTP Basic Authentication with username and password.
Type: "basic"
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Required | Must be "basic" |
username |
string | Required | Username (supports templating, typically {{env.USERNAME}}) |
password |
string | Required | Password (supports templating, typically {{env.PASSWORD}}) |
{
"type": "http",
"method": "GET",
"url": "https://api.example.com/private-data",
"auth": {
"type": "basic",
"username": "{{env.USERNAME}}",
"password": "{{env.PASSWORD}}"
}
}Authenticate using OAuth2 client credentials flow.
Type: "oauth2"
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Required | Must be "oauth2" |
flow |
string | Required | OAuth2 flow type (e.g., "clientCredentials") |
tokenUrl |
string | Required | Token endpoint URL |
clientId |
string | Required | OAuth2 client ID (supports templating) |
clientSecret |
string | Required | OAuth2 client secret (supports templating) |
scopes |
array | Optional | Array of scope strings |
{
"type": "http",
"method": "GET",
"url": "https://api.example.com/weather",
"auth": {
"type": "oauth2",
"flow": "clientCredentials",
"tokenUrl": "https://auth.example.com/token",
"clientId": "{{env.CLIENT_ID}}",
"clientSecret": "{{env.CLIENT_SECRET}}",
"scopes": ["read:weather", "read:forecast"]
}
}The MCI templating engine supports placeholder substitution, loops, and conditional blocks. Templating is available in:
- Execution configurations (URLs, headers, params, body, etc.)
- File contents (when
enableTemplating: true) - Text execution
The templating engine has access to three contexts:
props: Properties passed toexecute()methodenv: Environment variables passed to the adapterinput: Alias forprops(for backward compatibility)
Replace placeholders with values from the context.
Syntax: {{path.to.value}}
{{props.location}}
{{env.API_KEY}}
{{input.username}}
{{props.user.name}}
{{env.DATABASE_URL}}
In JSON:
{
"url": "https://api.example.com/users/{{props.user_id}}",
"headers": {
"Authorization": "Bearer {{env.ACCESS_TOKEN}}",
"X-Request-ID": "{{props.request_id}}"
}
}Resolve placeholders to their native JSON types (boolean, number, array, object, null) instead of strings.
Syntax: {!!path.to.value!!}
Important: JSON-native placeholders must be the only content in a field. They cannot be mixed with other text.
- Boolean:
trueorfalse(not"true"or"false") - Number: Integer or float (not string representation)
- Array: Native JSON array (not stringified)
- Object: Native JSON object (not stringified)
- Null:
nullvalue (not"null"string)
Boolean Properties:
{
"execution": {
"type": "http",
"body": {
"type": "json",
"content": {
"include_images": "{!!props.include_images!!}",
"case_sensitive": "{!!props.case_sensitive!!}"
}
}
}
}When executed with properties {"include_images": true, "case_sensitive": false}, the JSON body will be:
{
"include_images": true,
"case_sensitive": false
}Array Properties:
{
"execution": {
"type": "http",
"body": {
"type": "json",
"content": {
"urls": "{!!props.urls!!}",
"tags": "{!!props.tags!!}"
}
}
}
}When executed with properties {"urls": ["https://a.com", "https://b.com"], "tags": ["urgent", "review"]}, the JSON body will be:
{
"urls": ["https://a.com", "https://b.com"],
"tags": ["urgent", "review"]
}Object Properties:
{
"execution": {
"type": "http",
"body": {
"type": "json",
"content": {
"config": "{!!props.config!!}",
"metadata": "{!!props.metadata!!}"
}
}
}
}When executed with properties {"config": {"debug": false, "retries": 3}, "metadata": {"version": "1.0"}}, the JSON body will be:
{
"config": {
"debug": false,
"retries": 3
},
"metadata": {
"version": "1.0"
}
}Number Properties:
{
"execution": {
"type": "http",
"body": {
"type": "json",
"content": {
"max_results": "{!!props.max_results!!}",
"quality": "{!!props.quality!!}"
}
}
}
}When executed with properties {"max_results": 100, "quality": 0.95}, the JSON body will be:
{
"max_results": 100,
"quality": 0.95
}Mixed Native and String Placeholders:
{
"execution": {
"type": "http",
"body": {
"type": "json",
"content": {
"enabled": "{!!props.enabled!!}",
"count": "{!!props.count!!}",
"name": "{{props.name}}",
"description": "Search for {{props.query}}"
}
}
}
}When executed with properties {"enabled": true, "count": 50, "name": "My Search", "query": "testing"}, the JSON body will be:
{
"enabled": true,
"count": 50,
"name": "My Search",
"description": "Search for testing"
}✅ Valid Usage:
{
"enabled": "{!!props.enabled!!}",
"items": "{!!props.items!!}",
"config": "{!!env.CONFIG!!}"
}❌ Invalid Usage (will raise errors):
{
"message": "Status: {!!props.enabled!!}",
"url": "https://api.com/{!!props.path!!}",
"combined": "{!!props.value!!} and more text"
}Error Messages:
- Mixed Content: "Invalid JSON-native placeholder format: 'text {!!props.value!!}'. Must be exactly {!!path!!} with no surrounding content."
- Missing Property: "Failed to resolve JSON-native placeholder '{!!props.missing!!}': Path 'props.missing' not found in context"
- Invalid Syntax: "Invalid JSON-native placeholder format: '{{props.value}}'. Must be exactly {!!path!!} with no surrounding content."
Use {!! ... !!} when:
- Property must be a native boolean (
true/false) in JSON - Property must be a native number (integer or float) in JSON
- Property is an array that should remain an array in JSON
- Property is an object that should remain an object in JSON
- You need to preserve the exact type from input schema
Use {{ ... }} when:
- Building strings with multiple placeholders
- Concatenating values:
"User {{props.name}} has ID {{props.id}}" - Property should always be a string in the output
- Using in URLs, headers, or other string-only contexts
Iterate a fixed number of times using a range.
Syntax: @for(variable in range(start, end))...@endfor
variable: Loop variable namestart: Starting value (inclusive)end: Ending value (exclusive)
Template:
@for(i in range(0, 3))
Item {{i}}
@endfor
Output:
Item 0
Item 1
Item 2
Iterate over arrays or objects from the context.
Syntax: @foreach(variable in path.to.collection)...@endforeach
variable: Loop variable namepath.to.collection: Path to an array or object in the context
Context:
{
"props": {
"items": ["Apple", "Banana", "Cherry"]
}
}Template:
@foreach(item in props.items)
- {{item}}
@endforeach
Output:
- Apple
- Banana
- Cherry
Context:
{
"props": {
"users": [
{ "name": "Alice", "age": 30 },
{ "name": "Bob", "age": 25 }
]
}
}Template:
@foreach(user in props.users)
Name: {{user.name}}, Age: {{user.age}}
@endforeach
Output:
Name: Alice, Age: 30
Name: Bob, Age: 25
Execute code conditionally based on values in the context.
Syntax:
@if(condition)
...
@elseif(condition)
...
@else
...
@endif
- Truthy check:
@if(path.to.value) - Equality:
@if(path.to.value == "expected") - Inequality:
@if(path.to.value != "unexpected") - Greater than:
@if(path.to.value > 10) - Less than:
@if(path.to.value < 100)
Simple Conditional:
@if(props.premium)
You have premium access!
@else
Upgrade to premium for more features.
@endif
Multiple Conditions:
@if(props.status == "active")
Status: Active
@elseif(props.status == "pending")
Status: Pending approval
@else
Status: Inactive
@endif
Numeric Comparison:
@if(props.age > 18)
Adult content available
@else
Restricted content
@endif
All tool executions return a consistent result format.
| Field | Type | Description |
|---|---|---|
isError |
boolean | Whether an error occurred during execution |
content |
any | Result content (if successful) |
error |
string | Error message (if isError: true) |
metadata |
object | Optional metadata (e.g., HTTP status code, CLI exit code) |
Different execution types include specific metadata:
HTTP Execution Metadata:
status_code(integer): HTTP status coderesponse_time_ms(integer): Response time in milliseconds
CLI Execution Metadata:
exit_code(integer): Command exit code (0 for success, non-zero for failure)stdout_bytes(integer): Size of stdout in bytesstderr_bytes(integer): Size of stderr in bytesstderr(string): Standard error output (if any)stdout(string): Standard output (only included in error results)
{
"isError": false,
"content": [
{
"type": "text",
"text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy"
}
],
"metadata": {
"status_code": 200,
"response_time_ms": 245
}
}{
"isError": false,
"content": [
{
"type": "text",
"text": "Hello, World!\n"
}
],
"metadata": {
"exit_code": 0,
"stdout_bytes": 14,
"stderr_bytes": 0,
"stderr": ""
}
}{
"isError": true,
"error": "HTTP request failed: 404 Not Found",
"metadata": {
"status_code": 404
}
}{
"isError": true,
"error": "Command exited with code 1: permission denied",
"metadata": {
"exit_code": 1,
"stdout_bytes": 0,
"stderr_bytes": 18,
"stderr": "permission denied",
"stdout": ""
}
}Here's a complete MCI context file demonstrating all features:
{
"schemaVersion": "1.0",
"metadata": {
"name": "Example API Tools",
"description": "Comprehensive example of MCI features",
"version": "1.0.0",
"license": "MIT",
"authors": ["MCI Team"]
},
"tools": [
{
"name": "get_weather",
"title": "Get Weather",
"description": "Fetch weather with API key auth",
"inputSchema": {
"type": "object",
"properties": {
"location": { "type": "string" }
},
"required": ["location"]
},
"execution": {
"type": "http",
"method": "GET",
"url": "https://api.weather.com/v1/current",
"auth": {
"type": "apiKey",
"in": "header",
"name": "X-API-Key",
"value": "{{env.WEATHER_API_KEY}}"
},
"params": {
"location": "{{props.location}}"
}
}
},
{
"name": "search_logs",
"title": "Search Logs",
"description": "Search log files with grep",
"inputSchema": {
"type": "object",
"properties": {
"pattern": { "type": "string" },
"directory": { "type": "string" }
},
"required": ["pattern", "directory"]
},
"execution": {
"type": "cli",
"command": "grep",
"args": ["-r", "{{props.pattern}}"],
"cwd": "{{props.directory}}"
}
},
{
"name": "load_report",
"title": "Load Report",
"description": "Load report template",
"execution": {
"type": "file",
"path": "./templates/report.txt",
"enableTemplating": true
}
},
{
"name": "generate_greeting",
"title": "Generate Greeting",
"description": "Generate personalized greeting",
"inputSchema": {
"type": "object",
"properties": {
"name": { "type": "string" }
},
"required": ["name"]
},
"execution": {
"type": "text",
"text": "Hello {{props.name}}! Welcome to MCI."
}
}
]
}- API Reference - Python adapter API documentation
- Quickstart Guide - Getting started with MCI
- PRD.md - Product requirements and specifications
- PLAN.md - Implementation plan and architecture