SkillPort interface, skill loading, content scanning, and the MCP integration layer.
SkillPort Interface
Every skill in Comis implements theSkillPort interface, the hexagonal architecture boundary for skill execution. The port handles permission validation, timeout enforcement, and structured output.
manifest— Metadata describing the skill (name, description, parameters, permissions, timeout)validate()— Checks input before execution. Verifies parameter types, required fields, and permission constraints. Returnsok(true)orerr()with a descriptive error.execute()— Runs the skill and returns structured output. Implementations must enforce timeout limits and returnResult— no thrown exceptions.
Supporting Types
Skill Manifest
TheSkillManifest type in @comis/core is the internal TypeScript representation used by SkillPort implementations. The on-disk SKILL.md frontmatter is parsed and validated against SkillManifestSchema (in @comis/skills); the parsed result is then mapped to SkillManifest for execution. The two shapes overlap but are not identical — see the frontmatter field table below for what the parser actually accepts.
| Field | Type | Description |
|---|---|---|
name | string | Required. Unique skill identifier |
description | string | Required. What the skill does (shown to agent) |
type | string | Skill type: prompt (default) |
version | string | Semantic version |
license | string | License identifier |
userInvocable | boolean | Whether users can trigger directly (default: true) |
disableModelInvocation | boolean | Prevent agent from calling autonomously |
allowedTools | string[] | Restrict which tools the skill can use |
argumentHint | string | Hint for the argument format |
inputSchema | object | JSON Schema for parameters |
permissions | object | Security permissions: fsRead, fsWrite, net, env |
metadata | object | Arbitrary string-to-string key-value metadata |
comis | object | Comis-only namespace block: os, requires (bins + env), skill-key, primary-env, command-dispatch |
Comis-platform-only fields (
os, requires, skill-key, primary-env, command-dispatch) live exclusively under the comis: namespace block in frontmatter. Other pi-coding-agent hosts ignore this block. The full schema is SkillManifestSchema in packages/skills/src/manifest/schema.ts.For the user-facing SKILL.md format and examples, see Skill Manifest Reference. This page focuses on the internal TypeScript types and processing pipeline.
Prompt Skills
Prompt skills are the most common skill type. They are Markdown files (SKILL.md) that instruct the agent how to perform a task. Here is how they work internally:- Discovery — SKILL.md files are found in the workspace’s
skills/directory at startup - Parsing — YAML frontmatter is parsed as
SkillManifest, the Markdown body becomes the skill prompt - Template substitution — Variables in the body are replaced with user-provided arguments:
- Named placeholders:
{variable_name}— mapped positionally to arguments - Positional syntax:
$1,$2(1-indexed),$@(all arguments),${@:N}(arguments from index N)
- Named placeholders:
- System prompt injection — The processed skill body is wrapped in XML and injected into the agent’s context
Processing Pipeline
Before a prompt skill reaches the agent, it passes through a four-stage pipeline:Content Scanner
Inspects the skill body for security violations across six categories:
Skills with CRITICAL findings are rejected. The scanner is a pure function — it accepts a string and returns structured findings without side effects.
| Category | Severity | Examples |
|---|---|---|
| Exec injection | CRITICAL | $(command), backtick injection, eval() |
| Environment harvesting | WARN | printenv, /proc/environ, mass dumps |
| Crypto mining | CRITICAL | stratum:// protocols, miner binaries |
| Network exfiltration | WARN/CRITICAL | curl | bash, reverse shells |
| Obfuscated encoding | WARN/CRITICAL | Long base64 strings, decode-and-execute chains |
| XML breakout | CRITICAL | Closing </skill> tags, <system> injection |
Sanitizer
Cleans the skill body through a strict pipeline:
- Strip HTML comments — Removes hidden content (
<!-- ... -->) - NFKC normalization — Decomposes fullwidth and ligature characters
- Strip invisible characters — Removes zero-width joiners, tag block bypass characters
- Enforce size limits — Truncates to maximum body length with a
[TRUNCATED]marker
Template Processor
Substitutes variables with actual values from user arguments:
- Named placeholders (
{topic},{language}) are mapped positionally to arguments - Positional references (
$1,$@) follow shell-like conventions - Unmatched placeholders are left as-is (safe behavior)
- Extra arguments beyond placeholder count are appended as “Additional arguments”
MCP Integration
MCP (Model Context Protocol) servers integrate as skill providers, exposing external tools to Comis agents.- MCP servers are configured in
config.yamlunder theskills.mcpsection - Each MCP server exposes tools that become available to agents
- Tools from MCP servers are namespaced by server name to avoid conflicts (e.g.,
github.create_issue) - The MCP client handles connection lifecycle, tool discovery, and execution
SkillPort interface, so agents interact with MCP tools the same way they interact with built-in tools and prompt skills.
For MCP server configuration and setup, see MCP Integration. This page covers only the integration architecture.
Plugin-Provided Tools
Plugins can register tools viaregistry.registerTool() (documented in the Plugins page). These tools become available alongside built-in tools and skill-provided tools.
SkillPort interface. The agent sees them identically and selects tools based on the task description matching the tool’s description.
Skill Loading and Caching
TheSkillRegistry manages skill discovery and lifecycle:
- Discovery — Skills are loaded from the workspace’s
skills/directory on startup. Each subdirectory with aSKILL.mdfile is treated as a skill. - Validation — Manifest frontmatter is validated to ensure required fields (
name,description) are present and well-formed. - Caching — Skills are cached in memory after first load. Subsequent requests use the cached version.
- Hot reload — When enabled, file changes in the skills directory trigger re-parsing and cache invalidation. Skills that fail validation on reload are kept at their previous version.
- Visibility — Skills with
disableModelInvocation: trueare hidden from the model’s available skills listing but can still be invoked directly by users.
Skill Manifest Reference
User-facing SKILL.md format
MCP Integration
Connecting MCP servers
Plugins
registerTool for plugin-provided tools
Tool Policy
Controlling which tools agents can use
