← Docs Hub

Code Agents Guide

Write TypeScript agents, deploy from GitHub

What are Code Agents?

Code Agents let you write custom TypeScript functions that have full access to all 118 MCP tools, an LLM for analysis, and persistent key-value storage. Your code runs in a secure V8 sandbox with no file system or network access — all external calls go through the SDK.

Quick Start

  1. Connect GitHub — Go to Settings → GitHub and connect your account.
  2. Create a repository with two files:
    osf-agent.yaml
    name: My First Agent
    description: Analyzes OEE data
    icon: "📊"
    entry: src/main.ts
    timeout: 60
    src/main.ts
    export default async function main(ctx) {
      const oee = await ctx.mcp.call('factory_get_latest_oee');
      ctx.log('OEE data received');
    
      const analysis = await ctx.llm.chat(
        `Analyze this OEE data and suggest improvements: ${JSON.stringify(oee)}`
      );
      ctx.log(analysis);
    
      return { analysis };
    }
  3. Deploy — Go to Agents → Deploy from GitHub, select your repo, and click Deploy.
  4. Run — Open your agent's detail page and click Run. Watch the output stream in real time.

The SDK Context (ctx)

Your main(ctx) function receives a context object with these modules:

ctx.mcp

MethodDescription
ctx.mcp.call(name, args?)Call any MCP tool. Returns parsed JSON result.
ctx.mcp.listTools()List all available MCP tools with descriptions.

ctx.llm

MethodDescription
ctx.llm.chat(prompt)Send a prompt to the LLM. Returns the text response.

ctx.storage

MethodDescription
ctx.storage.get(key)Read a stored value (scoped per agent + user).
ctx.storage.set(key, value)Store any JSON-serializable value.
ctx.storage.delete(key)Remove a stored value.

ctx.log

MethodDescription
ctx.log(message)Log a message to the live output terminal.

Using osf-ts in Flows

Code agents can also be used as osf-ts nodes inside Node-RED flows. The osf-ts node supports multi-output — configure 1 to 5 output ports and return an array to route different results to different downstream paths.

osf-ts node (2 outputs)
// Return an array — each element goes to a different output port
const oee = await ctx.mcp.call('factory_get_latest_oee');
const isGood = oee.oee_percent > 85;

return [
  isGood ? oee : null,     // Port 0: good OEE → continue
  !isGood ? oee : null,    // Port 1: bad OEE → alert path
];

Manifest Reference (osf-agent.yaml)

FieldRequiredDefaultDescription
nameYesDisplay name of the agent
descriptionNoShort description shown in the UI
iconNo💻Emoji icon
entryNosrc/main.tsPath to the entry file
timeoutNo60Max execution time in seconds (max 300)

Auto-Sync via Webhooks

When you push to your repository, OpenShopFloor automatically re-syncs your agent. The platform fetches the latest osf-agent.yaml and entry file, re-bundles the code, and updates the deployment. You can also manually trigger a sync from the agent detail page.

Security & Limits

  • Code runs in an isolated V8 sandbox (isolated-vm) — no filesystem, no network, no require/import
  • Memory limit: 128 MB per execution
  • Timeout: configurable up to 300 seconds
  • Rate limit: 3 runs per minute
  • All MCP and storage calls are scoped to your user ID
  • GitHub tokens are encrypted with AES-256-GCM
  • Repository must be public (open source)

Examples

Machine Status Monitor

src/main.ts
export default async function main(ctx) {
  const machines = await ctx.mcp.call('factory_get_all_machines');
  const stopped = machines.filter(m => m.status === 'stopped');

  if (stopped.length > 0) {
    const report = await ctx.llm.chat(
      `These machines are stopped. Analyze possible causes: ${JSON.stringify(stopped)}`
    );
    ctx.log(`⚠ ${stopped.length} machines stopped`);
    ctx.log(report);
  } else {
    ctx.log('All machines running normally');
  }
}

Daily Quality Report

src/main.ts
export default async function main(ctx) {
  const defects = await ctx.mcp.call('factory_get_quality_notifications');
  const previous = await ctx.storage.get('last_defects');

  const report = await ctx.llm.chat(`
    Create a quality report comparing current defects with previous data.
    Current: ${JSON.stringify(defects)}
    Previous: ${JSON.stringify(previous)}
  `);

  await ctx.storage.set('last_defects', defects);
  ctx.log(report);
  return { report, defectCount: defects.length };
}

This site uses a cookie to remember your preferences. Analytics are anonymous and cookie-free. Privacy Policy