TS · 04

Neuron - sources, contract & clarify()

A Neuron is a plain function - NeuronFn - wrapping anything that interacts with the real world. Write your own, or use a source factory: mcpNeuron(opts) wraps any stdio MCP server, and the unified neuron(source, opts) mirrors Python’s Neuron(source=…). An HTTP API is not a Neuron - keep Express/Fastify at the edge and dispatch TASKs from its routes via an orchestrator Dendrite. To ask for more information instead of producing a result, return clarify(); the Axon converts it into a CLARIFICATION signal. To ask permission before acting, return permissionRequest() - same return-and-resume shape - and the Axon emits a PERMISSION signal.

Source factories

functionmcpNeuron(opts): CloseableNeuronFn

MCP source. Spawns any stdio MCP server (command+args or a server preset) via @modelcontextprotocol/sdk and exposes its tools. Input is {tool, arguments} or {__list_tools__:true}. Wrapper only - does not implement a server. The SDK is an optional peer dependency, imported lazily.

functionneuron(source, opts): CloseableNeuronFn

Unified dispatcher. source = "mcp" | "ollama" | "huggingface" | "hf". Mirrors Python’s Neuron(source=…).

conststandardMcpServers

Launch presets for well-known published MCP servers (filesystem, fetch, git, memory, everything, sequentialthinking, time). Pass server="filesystem" and your args are appended to the preset.

neuron_sources.ts
import { Axon, mcpNeuron, neuron } from "@cosmonapse/sdk";

// An HTTP API is NOT a Neuron. Keep Express/Fastify on the OUTSIDE as an
// HTTP boundary and dispatch TASKs from its routes via an orchestrator
// Dendrite  -  see the real-world-neurons example.

// MCP server  -  wrap any stdio MCP server's tools as a Neuron
const files = new Axon({
  neuronId: "files",
  neuronFn: mcpNeuron({ server: "filesystem", args: ["/data"], tool: "read_file" }),
});

// Or use the unified factory  -  mirrors Python's Neuron(source=…)
const sameFiles = neuron("mcp", { server: "filesystem", args: ["/data"] });

Contract, clarify() & permissionRequest()

Every source - and any hand-written Neuron - satisfies the same NeuronFn signature, so the Axon treats them identically.

functionclarify(question: string, context?: Json): ClarificationOutput

Build a clarification marker for a Neuron to return.

functionisClarification(output: unknown): output is ClarificationOutput

Type guard that detects a clarify() marker.

functionpermissionRequest(action: string, opts?: { scope?, reason?, context? }): PermissionRequestOutput

Build a permission-request marker for a Neuron to return. Typically returned only after an Engram recall misses.

functionisPermissionRequest(output: unknown): output is PermissionRequestOutput

Type guard that detects a permissionRequest() marker.

functionerrorResult(message: string, opts?: { code?, recoverable? }): ErrorOutput

Build an error marker for a Neuron to return instead of throwing - the Axon emits ERROR with the given code (default NEURON_ERROR) and recoverable flag.

functionisErrorOutput(output: unknown): output is ErrorOutput

Type guard that detects an errorResult() marker.

neuron.ts
import { clarify, isClarification } from "@cosmonapse/sdk";

const neuronFn: NeuronFn = async (input, context) => {
  if (!input.topic) return clarify("Which topic?", { hint: "e.g. billing" });
  return { summary: summarise(input.topic, context) };
};

// The Axon turns a clarify() return into a CLARIFICATION signal for you.
isClarification(await neuronFn({}, []));   // true

Have a feature in mind?

The protocol, SDKs, and CLI are still pre-1.0. If something here is missing, ambiguous, or wrong - open an issue and propose a change. Every breaking change is debated in DECISIONS.md first.