Provider-agnostic OpenAI- and Anthropic-compatible HTTP adapter built on top of the AI SDK.
This repo now has a split package layout:
@mcpc-tech/aiyo: generic core adapter@mcpc-tech/aiyo-acp: ACP runtime integration for the core adapter@mcpc-tech/aiyo-ptc: Programmatic Tool Calling (PTC) plugin and Deno-backed runtime helpers@mcpc-tech/aiyo-cli: local launcher built on top of the ACP package
GET /v1/modelsPOST /v1/chat/completionsPOST /v1/responsesPOST /v1/messages- SSE streaming for chat completions
Use the core package when you want to plug in your own AI SDK runtime via runtimeFactory.
Install:
pnpm add @mcpc-tech/aiyo ai openai zodMinimal example:
import { Hono } from "hono";
import { createOpenAI } from "@ai-sdk/openai";
import { createAiyo } from "@mcpc-tech/aiyo";
const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY! });
const adapter = createAiyo({
defaultModel: "gpt-4o-mini",
runtimeFactory: ({ modelId }) => ({
model: openai.chat(modelId || "gpt-4o-mini"),
modelName: modelId || "gpt-4o-mini",
}),
listModels: ["gpt-4o-mini"],
});
const app = new Hono();
app.get("/v1/models", adapter.honoHandler());
app.post("/v1/chat/completions", adapter.honoHandler());
app.post("/v1/responses", adapter.honoHandler());
app.post("/v1/messages", adapter.honoHandler());Core config highlights:
runtimeFactory: required unless you use a provider integration package such as@mcpc-tech/aiyo-acplistModels: optional model list resolver forGET /v1/modelsmiddleware: request / params / result rewrite hooksplugins: unified final-result plugins, including PTCtransformTools: provider-specific tool wrapping hooknormalizeToolCall: provider-specific tool-call normalization hook
Use the ACP package when you want the old ACP-backed experience:
pnpm add @mcpc-tech/aiyo-acpimport { Hono } from "hono";
import { createAiyo } from "@mcpc-tech/aiyo-acp";
const adapter = createAiyo({
defaultModel: "default",
defaultACPConfig: {
command: "opencode",
args: ["acp"],
session: {
cwd: process.cwd(),
mcpServers: [],
},
},
});
const app = new Hono();
app.get("/v1/models", adapter.honoHandler());
app.post("/v1/chat/completions", adapter.honoHandler());The ACP package injects:
- ACP runtime creation
- ACP tool wrapping
- ACP tool-call unwrapping
- ACP-backed model discovery for
GET /v1/models
It also still supports request-level ACP config through extra_body.acpConfig.
Use the PTC package when you want programmatic tool calling:
pnpm add @mcpc-tech/aiyo-ptcimport { createAiyo } from "@mcpc-tech/aiyo";
import { createJavaScriptCodeExecutionPlugin } from "@mcpc-tech/aiyo-ptc";
const adapter = createAiyo({
defaultModel: "gpt-4o-mini",
runtimeFactory: ({ modelId }) => ({
model: openai.chat(modelId || "gpt-4o-mini"),
modelName: modelId || "gpt-4o-mini",
}),
listModels: ["gpt-4o-mini"],
plugins: [
createJavaScriptCodeExecutionPlugin({
name: "ptc",
toolNames: ["read_file", "write_file", "list_dir"],
}),
],
});For architecture details, see docs/ptc-architecture.md.
The Hono example directory now keeps only two maintained servers:
examples/hono-server/basic-server.ts: ACP-backed serverexamples/hono-server/ptc-server.ts: direct OpenAI-compatible provider + PTC
From the repo root:
pnpm install
pnpm run example:hono
pnpm run example:hono:ptcpnpm run example:expresspnpm run client:generate
pnpm run client:streamThe workspace also ships @mcpc-tech/aiyo-cli.
From the repo root:
pnpm install
pnpm run launch opencode
pnpm run launch claudeThe basic Hono example reads examples/hono-server/aiyo.config.json by default.
You can override that with:
export AIYO_CONFIG=/path/to/config.jsonExample config:
{
"port": 3456,
"defaultModel": "default",
"acp": {
"command": "opencode",
"args": ["acp"],
"cwd": "/path/to/workspace"
}
}Main commands:
pnpm run typecheck
pnpm run typecheck:workspace
pnpm run build
pnpm run build:workspace
pnpm run test
pnpm run test:integrationFor more detail, see TEST.md.
MIT