Quick Start
Put a Neocortex character on a website or browser game without exposing your API key
@neocortex-link/web has three entry points:
@neocortex-link/web/server: a proxy that holds your API key and checks every request.@neocortex-link/web/client: smart characters, group chat, quizzes, mic input and streamed speech.@neocortex-link/web/ui: Web Components such as<neocortex-chat>and<neocortex-quiz>, for any framework or none.
Browser Your server Neocortex
<neocortex-chat> ──fetch──▶ createNeocortexHandler() ──x-api-key──▶ api.neocortex.link/v3
◀───────── (auth, allowlist, limits) ◀────────────The browser never sees your key. Source: neocortex-link/neocortex-web-sdk (Apache-2.0).
Requirements
Setup
Install
npm install @neocortex-link/webAdd the proxy
authorize returns the signed-in visitor as { id }, or null to refuse. The id becomes the Neocortex playerId.
import { createNeocortexHandler } from "@neocortex-link/web/server";
import { auth } from "@/auth";
const handler = createNeocortexHandler({
apiKey: process.env.NEOCORTEX_API_KEY!,
characters: ["your-character-id"],
authorize: async () => {
const session = await auth();
return session?.user ? { id: session.user.id } : null;
},
});
export { handler as GET, handler as POST, handler as OPTIONS };import express from "express";
import { createNeocortexHandler, toNodeHandler } from "@neocortex-link/web/server";
const app = express();
const handler = createNeocortexHandler({
apiKey: process.env.NEOCORTEX_API_KEY!,
characters: ["your-character-id"],
authorize: (request) => {
const user = getUserFromCookie(request.headers.get("cookie"));
return user ? { id: user.id } : null;
},
});
app.use("/api/neocortex", toNodeHandler(handler));toNodeHandler also works with Connect and node:http.
import { createNeocortexHandler } from "@neocortex-link/web/server";
let handler: ((request: Request) => Promise<Response>) | undefined;
export default {
fetch(request: Request, env: { NEOCORTEX_API_KEY: string }) {
handler ??= createNeocortexHandler({
apiKey: env.NEOCORTEX_API_KEY,
basePath: "",
characters: ["your-character-id"],
authorize: async (request) => {
const user = await getUserFromRequest(request);
return user ? { id: user.id } : null;
},
});
return handler(request);
},
};The same handler mounts in Hono, Bun and Deno. For a rate limit shared across instances, see Serverless hosts.
Add a chat
import "@neocortex-link/web/ui/auto";Or without a bundler:
<script type="module" src="https://cdn.jsdelivr.net/npm/@neocortex-link/web@0.2/dist/ui/auto.js"></script>Then:
<neocortex-chat endpoint="/api/neocortex" character-id="your-character-id" voice></neocortex-chat>Handle actions
const chat = document.querySelector("neocortex-chat");
chat.agent.registerAction("OPEN_DOOR", (action) => door.open(action.targetId));No login?
authorize still needs a stable id per visitor. Issue one in a signed, httpOnly cookie, see Anonymous visitors.
Self-hosting the UI bundle
<script type="importmap">
{ "imports": { "@neocortex-link/web/ui/auto": "/vendor/neocortex/ui/auto.js" } }
</script>
<script type="module">
import "@neocortex-link/web/ui/auto";
</script>/vendor/neocortex/ serves the package's dist folder.
Example
examples/quickstart: one HTML page and a node:http server, with anonymous visitor cookies and buildContext.