{
  "id": "osc-stack-run-agents-no-lock-in",
  "job": "Run your own AI coding agents (Claude Code or Codex) as the workload, from your own git repository and on your own model keys, on infrastructure you can leave.",
  "aliases": [
    "run ai agents without vendor lock-in",
    "deploy multiple ai agents without vendor lock-in",
    "host claude code agents on open source infrastructure",
    "run codex agents from a git repo on a schedule"
  ],
  "inputs": [
    {
      "protocol": "git",
      "source": "a repository holding the agent's CLAUDE.md, skills, prompt files or code (SourceUrl; GitToken for a private repo)"
    },
    {
      "protocol": "api-key",
      "source": "your own model credential: AnthropicApiKey or ClaudeCodeOauthToken for Claude Runner, CodexApiKey or OpenaiApiKey for Codex Runner"
    }
  ],
  "outputs": [
    {
      "protocol": "git",
      "consumer": "the agent's changes, written back to your repository by the agent itself"
    },
    {
      "protocol": "postgres",
      "consumer": "optional: agent state in a PostgreSQL instance"
    },
    {
      "protocol": "S3",
      "consumer": "optional: files in a MinIO bucket"
    }
  ],
  "distinctFrom": [
    {
      "id": "osc-stack-provision-agent-backend",
      "descriptorUrl": "https://www.osaas.io/stacks/provision-agent-backend.json",
      "why": "In that recipe the agent is the operator: it provisions a database and storage for an app. In this one the agent itself is the workload that runs here."
    },
    {
      "id": "osc-stack-media-library-agent",
      "descriptorUrl": "https://www.osaas.io/stacks/media-library-agent.json",
      "why": "That recipe is one scheduled agent with one job (tagging a media library). This one is the general way to run any agent from your own repo."
    }
  ],
  "recommendedPath": {
    "chain": [
      {
        "step": 1,
        "serviceId": "birme-claude-runner",
        "role": "runs Claude Code headless against the cloned repo, then stops (Job-type service)",
        "requiredConfig": ["name", "Prompt", "SourceUrl"],
        "requiresCredential": true,
        "note": "Auth: AnthropicApiKey or ClaudeCodeOauthToken. Optional: Model, MaxTurns, AllowedTools, DisallowedTools, SubPath, OscAccessToken (adds the OSC MCP server), ConfigSvc."
      },
      {
        "step": 1,
        "alternative": true,
        "serviceId": "birme-codex-runner",
        "role": "runs Codex against the cloned repo, then stops (Job-type service)",
        "requiredConfig": ["name", "Prompt", "SourceUrl"],
        "requiresCredential": true,
        "note": "Auth: CodexApiKey or OpenaiApiKey."
      },
      {
        "step": 2,
        "action": "schedule",
        "role": "optional: put the prompt on a schedule in My Agent Tasks (an OSC app feature, Personal and up; not open source)"
      },
      {
        "step": 3,
        "serviceId": "birme-osc-postgresql",
        "role": "optional: state the agent reads and writes",
        "requiredConfig": ["name", "PostgresPassword"],
        "requiresCredential": true
      },
      {
        "step": 4,
        "serviceId": "minio-minio",
        "role": "optional: files the agent reads and writes",
        "requiredConfig": ["name"],
        "requiresCredential": false
      }
    ],
    "tokensPerDay": null,
    "tokensPerDayMeasured": false,
    "tokensPerDayNote": "Model usage is billed to your Anthropic or OpenAI account, not to OSC tokens. Runner and optional service token cost not measured for this recipe.",
    "measuredWallClockSeconds": null,
    "wallClockMeasured": false,
    "gapNote": "No end-to-end run of this recipe has been timed. The runner schemas and the exit path (docker build / docker run in each runner README) were read live; an agent run was not executed for this page."
  },
  "exitPath": {
    "runner": "docker build and docker run -e SOURCE_URL=... from https://github.com/birme/claude-runner or https://github.com/birme/codex-runner (both MIT)",
    "data": "pg_dump and any S3 copy tool",
    "repo": "unchanged; the agent definition never left it",
    "model": "unchanged; usage was billed to your own Anthropic or OpenAI account"
  },
  "doesNotMove": [
    "My Agent Tasks schedules: an OSC app feature, not open source; recreate the schedule with cron or any scheduler that can run docker run",
    "the Claude Code and Codex CLIs: vendor tools inside the runner images, not covered by the open-source claim"
  ],
  "notVerified": [
    "a timed agent run from start to finish on this recipe",
    "token cost per run for the runners",
    "running the runner images outside OSC (documented in each README, not executed for this page)"
  ],
  "servicesVerifiedLive": {
    "date": "2026-10-23",
    "method": "osc_call_tool wrap: list-available-services (category ai), get-service-schema on birme-claude-runner and birme-codex-runner, list-service-instances on both (answer: Job-type, no persistent instances). gh api on birme/claude-runner and birme/codex-runner (public, MIT).",
    "catalogTotal": 198,
    "catalogTotalSource": "list-available-services via osc_call_tool on 2026-10-23: '10 of 198 total services match category ai'"
  },
  "gateCheck": {
    "gatedServiceId": "eyevinn-just-go-live",
    "usesGatedService": false,
    "note": "This stack does not name or link eyevinn-just-go-live."
  },
  "verifiedOn": "2026-10-23",
  "publishedAt": "https://www.osaas.io/use-cases/ai-dev-team",
  "descriptorUrl": "https://www.osaas.io/stacks/run-agents-no-lock-in.json"
}
