Upstreet Docs
    SDK

    Create, configure, and manage NPCs via the SDK—CRUD, tools, and chat thread management.

    NPCs Subclient

    The client.npcs subclient lets you create, configure, and manage NPCs (Non-Player Characters)—persistent AI agents with chat, memory, and tools. Use it to list NPCs, create new ones with character references, configure tools like web search, and manage chat threads.


    Methods

    MethodSignatureDescription
    list() => Promise<NPC[]>List all your NPCs
    get(id: string) => Promise<NPC>Get a single NPC by ID
    create(params) => Promise<NPC>Create a new NPC
    update(id, params) => Promise<NPC>Update NPC configuration (tools, etc.)
    delete(id: string) => Promise<void>Delete an NPC
    listThreads(id: string) => Promise<Thread[]>List chat threads for an NPC
    getThread(id, threadId) => Promise<{ thread, messages }>Get thread with messages

    list()

    list(): Promise<NpcSummary[]>

    Returns all NPCs for the authenticated user.

    const npcs = await client.npcs.list();
    npcs.forEach(npc => console.log(`${npc.name} (${npc.id})`));

    get(id)

    get(id: string): Promise<NpcSummary>

    Fetches a single NPC by ID.

    const npc = await client.npcs.get('npc-uuid-here');
    console.log(npc.name, npc.tools);

    create(params)

    create(params: {
      name: string;
      src: string;
      refType?: string | null;
      refId?: string | null;
      voice?: string | null;
    }): Promise<NpcSummary>

    Creates a new NPC. The src defines the character appearance—typically a reference like characterlive:your-character-uuid.

    ParamTypeDescription
    namestringDisplay name for the NPC
    srcstringAgent source (e.g. characterlive:uuid)
    refTypestring | nullOptional reference type
    refIdstring | nullOptional reference ID
    voicestring | nullVoice ID, e.g. kittentts:expr-voice-5-m or elevenlabs:<id>
    const npc = await client.npcs.create({
      name: 'Luna',
      src: 'characterlive:abc123-def456',
      voice: 'kittentts:expr-voice-5-m',
    });

    update(id, params)

    update(id: string, params: UpdateNpcParams): Promise<NpcSummary>

    Updates an NPC. Use this to configure tools, text model, voice, and visibility.

    await client.npcs.update(npc.id, {
      tools: {
        web_search: { enabled: true },
        image_generation: { enabled: true },
      },
    });

    delete(id)

    delete(id: string): Promise<void>

    Deletes an NPC by ID.

    await client.npcs.delete('npc-uuid-here');

    listThreads(id)

    listThreads(npcId: string): Promise<MastraThreadRecord[]>

    Returns chat threads for an NPC. Each thread has id, title, and updatedAt.

    const threads = await client.npcs.listThreads(npc.id);
    threads.forEach(t => console.log(t.title, t.id));

    getThread(id, threadId)

    getThread(npcId: string, threadId: string): Promise<{
      thread: MastraThreadRecord;
      messages: MastraMessageRecord[];
    }>

    Fetches a specific chat thread with its message history.

    const { thread, messages } = await client.npcs.getThread(npc.id, threadId);
    messages.forEach(m => console.log(`${m.role}: ${m.content}`));

    NPC Tools Configuration

    Tools extend what an NPC can do—web search, image generation, marketplace access, and more. Pass a tools object to update():

    Let the NPC generate images from prompts.

    await client.npcs.update(id, {
      tools: { image_generation: { enabled: true } },
    });

    Enable marketplace access for trading assets.

    await client.npcs.update(id, {
      tools: { marketplace: { enabled: true } },
    });

    You can enable multiple tools at once. Pass all desired tools in a single update() call.


    Chat Thread Management

    Each NPC has multiple chat threads—isolated conversations with their own history. Use listThreads and getThread to inspect threads and messages.

    1. List threads

    const threads = await client.npcs.listThreads(npc.id);

    2. Get a thread with messages

    const { thread, messages } = await client.npcs.getThread(npc.id, threads[0].id);

    3. Send messages via the app

    Chat and send messages through the web app at /npcs/[id]/chat, or use the NpcAiClient for programmatic chat.


    Full Code Examples

    import { PUClient } from 'pu-client';
    
    const client = new PUClient({ apiKey: process.env.PU_API_KEY! });
    
    const npc = await client.npcs.create({
      name: 'Merchant',
      src: 'characterlive:your-character-uuid',
    });
    
    await client.npcs.update(npc.id, {
      tools: {
        web_search: { enabled: true },
        marketplace: { enabled: true },
      },
    });
    
    console.log(`NPC ${npc.name} ready with tools`);
    import { PUClient } from 'pu-client';
    
    const client = new PUClient({ apiKey: process.env.PU_API_KEY! });
    
    const npcs = await client.npcs.list();
    const npc = npcs[0];
    
    const threads = await client.npcs.listThreads(npc.id);
    const { messages } = await client.npcs.getThread(npc.id, threads[0].id);
    
    console.log(`Thread has ${messages.length} messages`);

    NpcSummary Fields

    FieldTypeDescription
    idstringNPC ID
    namestringDisplay name
    srcstringAgent source
    toolsanyTools configuration
    voicestring | nullVoice ID
    refTypestring | nullReference type
    refIdstring | nullReference ID
    publicbooleanPublic visibility
    created_atstringCreation timestamp

    Next Steps