Ikanos — Schema — Exposes¶
The exposes array declares the server adapters that surface a capability to
the outside world. Each entry is a discriminated object on type: —
rest, mcp, skill, or control.
capability:
exposes:
- type: mcp
port: 3001
namespace: shipyard-tools
tools: { ... } # keyed map by tool name
- type: rest
port: 3002
namespace: shipyard-api
resources: { ... } # keyed map by resource name
- type: skill
port: 3003
namespace: shipyard-skills
skills: [...]
- type: control
port: 9090
namespace: control
observability: {...}
REST Expose (type: rest)¶
| Field | Required | Description |
|---|---|---|
type |
✅ | "rest" |
port |
✅ | TCP port (1–65535) |
namespace |
✅ | Unique identifier for this exposed API |
address |
Hostname, IPv4, or IPv6; default 0.0.0.0 |
|
authentication |
Bearer, API key, Basic, Digest | |
resources |
✅ | At least one exposed resource (keyed map) |
ExposedResource¶
resources: # keyed map; key IS the resource name
ships:
path: "/ships"
description: "Fleet of ships"
operations: { ... }
# — or, for pure pass-through:
forward:
targetNamespace: registry
ExposedOperation (simple mode)¶
operations: # keyed map; key IS the operation name
get-ship:
method: GET
path: "/ships/{imo}"
inputParameters: # keyed map
imo: { in: path, required: true }
call: registry.get-ship
with:
imo_number: shipyard-api.imo
outputParameters: [...]
ExposedOperation (orchestrated mode)¶
operations:
build-manifest:
method: GET
path: "/manifests/{voyageId}"
inputParameters:
voyageId: { in: path, required: true }
steps: { ... } # keyed map (see Steps page)
mappings: [...]
Exactly one of call: or steps: must be present. Using ref: is a
third option — see Aggregates.
Binary responses (REST)¶
New in Beta 1
First-class binary REST responses are available starting with Ikanos
1.0.0-beta1. Earlier releases could only forward binary entities through
the forward pass-through path, which produced no exhaustive OpenAPI
contract.
When the backing operation is declared binary on
consumes (outputRawFormat: binary), a REST
operation can declare its binary response contract directly. At runtime the
adapter returns the buffered bytes with the declared or upstream Content-Type;
at export time the OpenAPI generator emits
responses.<status>.content.<mediaType>.schema as type: string,
format: binary.
operations:
get-photo-image:
method: GET
path: "/photos/{id}/image"
inputParameters:
id: { in: path, required: true }
call: photoLibrary.download-photo
with: { id: shipyard-api.id }
responses:
'200':
description: Original image bytes
content:
image/jpeg:
schema:
type: string
format: binary
outputParameters are not applied on a binary operation — JSONPath mapping over
raw bytes is meaningless.
MCP Expose (type: mcp)¶
| Field | Required | Description |
|---|---|---|
type |
✅ | "mcp" |
port |
✅ | TCP port (omit for stdio transport) |
namespace |
✅ | Unique identifier |
transport |
"http" (default) or "stdio" |
|
description |
Server-level description shown to MCP clients | |
authentication |
Bearer or API key | |
tools |
MCP tools (keyed map by tool name) | |
resources |
MCP static resources | |
prompts |
MCP prompt templates |
McpTool¶
tools: # keyed map; key IS the tool name
get-ship:
description: "Retrieve a ship's details by IMO"
inputParameters: # keyed map
imo: { type: string, required: true, description: "IMO number" }
call: registry.get-ship
with: { imo_number: shipyard-tools.imo }
outputParameters:
- type: object
properties:
imo: { type: string, mapping: "$.imo_number" }
name: { type: string, mapping: "$.vessel_name" }
hints:
readOnly: true
idempotent: true
Mock-mode tools omit call:, with:, and mapping: — they declare
outputParameters with literal or Mustache-templated value::
tools:
greet:
inputParameters:
who: { type: string, required: true }
outputParameters:
- { name: message, type: string, value: "Hello, !" }
MCP transport¶
transport |
Listens on | Use case |
|---|---|---|
http (default) |
TCP port | Remote MCP clients, AI gateways |
stdio |
stdin/stdout | Local IDE/agent integrations |
Binary results and resources (MCP)¶
New in Beta 1
Binary MCP tool results and binary resource reads are available starting
with Ikanos 1.0.0-beta1. Earlier releases emitted only TextContent and
read resources as UTF-8 text, corrupting any binary payload.
When a tool's backing call (or its terminal orchestration step) yields a binary
entity — i.e. the consumed operation is declared
outputRawFormat: binary — the engine returns
the MCP content block that matches the resolved media type:
| Resolved media type | MCP content block |
|---|---|
image/* |
ImageContent (base64 data + mimeType) |
audio/* |
AudioContent (base64 data + mimeType) |
anything else (application/pdf, application/zip, application/octet-stream, …) |
EmbeddedResource referencing a transient BlobResourceContents |
tools:
get-photo:
description: "Fetch a photo as an image"
inputParameters:
id: { type: string, required: true }
call: photoLibrary.download-photo # outputRawFormat: binary on consumes
with: { id: shipyard-tools.id }
The tool spec stays compact: authors annotate that the upstream is binary
(on consumes); the result block is derived from the resolved MIME type, never
declared on the tool.
MCP resources follow the symmetric resource model — resources/read returns
BlobResourceContents (blob: <base64> + mimeType) instead of
TextResourceContents when the backing content is binary. This applies to both
dynamic resources (binary consumed call) and static resources that point at a
binary file (the media type is detected from the file extension).
Skill Expose (type: skill)¶
- type: skill
port: 3003
namespace: shipyard-skills
skills: # keyed map; key IS the skill name
fleet-ops:
description: "Fleet management tools"
tools: # keyed map; key IS the tool name
list-ships:
from: { sourceNamespace: shipyard-tools, action: list-ships }
Skill tools are references to MCP tools defined in another expose. The Skill adapter auto-exposes a discovery API:
GET /skillsGET /skills/{name}GET /skills/{name}/downloadGET /skills/{name}/contents
Control Expose (type: control)¶
- type: control
port: 9090
namespace: control
observability:
tracing:
exporter: otlp
endpoint: http://otel-collector:4317
metrics:
exporter: prometheus
Exposes operational endpoints:
| Endpoint | Purpose |
|---|---|
GET /health |
Liveness + readiness |
GET /metrics |
Prometheus RED metrics |
GET /status |
Runtime diagnostics |
GET /traces |
In-memory trace summary |
Only one Control expose per capability is allowed.
Authentication on exposes¶
Authentication on exposes validates incoming requests. Authentication on
consumes provides credentials for outgoing requests. Both use the same
Authentication object schema.