All Products
Search
Document Center

:AgentCore Node.js SDK User Guide

Last Updated:Sep 17, 2026

An Agent application usually connects to cloud models, external tools, and long-term memory at the same time. Maintaining a separate endpoint, credential, and session state for each capability quickly makes application code hard to maintain. The AgentCore Node.js SDK lets you call model connections, MCP tools, Skills, memories, and credentials by name from JavaScript or TypeScript code. These resources are configured in your Workspace. You can publish your Agent as an AG-UI or OpenAI Chat Completions service through framework adapters. This topic describes how to install the SDK, call cloud and custom resources, build and deploy an Agent service with LangChain, call the Agent service, and troubleshoot common issues.

This topic is the Node.js volume of AgentCore SDK Overview, which covers language selection, capability boundaries, and an overview of the preparations. The cloud resource examples run in the AgentCore managed runtime, and the custom resource examples use connection settings that your application provides.

Prerequisites

Runtime environment

Item Requirement
Node.js version The base SDK supports Node.js 20.3 and later. The LangChain service example in this topic uses Node.js 22.22 and later.
Application runtime The cloud resource examples run in the AgentCore managed application runtime. The SDK obtains the access configuration from the runtime, so you do not need to put platform access keys in your application code.
Module type The LangChain service example in this topic uses ES modules. Set "type": "module" in the package.json of your application.

Platform resources

Before you write code, activate AgentCore and create a Workspace as described in Manage Workspace. All resources in the examples in this topic belong to the Workspace of the Agent. Make sure that you have prepared the required resources and that the Agent has access to them.

This topic uses the following example resource names. Replace them with the names of the resources that you created.

Resource Example value Usage
Model connection my-model-connection Calls a model. Enter the name of a model connection that you created as described in Manage Models.
Model qwen3.8-max Must already be configured in the selected model connection. The framework tool example also requires a model that supports tool calls.
MCP server my-mcp Calls a tool. Enter the name of an MCP server that you created as described in Manage MCP Servers.
Skill my-skill Uses a Skill that is enabled and has a version in the Published state. You create, enable, and publish Skill versions as described in Manage Skill.
MemoryStore my-memory Required when you use the memory feature.
Credential my-api-key, my-mcp-header Create an API key credential or an MCP header credential as described in Manage credentials, and grant it to your application.

If you only call models, you do not need to create an MCP server, a Skill, a MemoryStore, or additional credentials.

Install the SDK

Install the base SDK:

npm install alibabacloud-agentcore-sdk@0.1.2

Install framework dependencies separately. The LangChain example in this topic requires Node.js 22.22 or later and uses the following dependencies:

npm install langchain@^1 @langchain/core@^1 @langchain/langgraph@^1 @langchain/openai@^1 zod@^4
npm install --save-dev tsx typescript @types/node

The examples in this topic use Node.js SDK 0.1.2. For later versions, see the alibabacloud-agentcore-sdk npm package page.

Choose an integration path based on where your resources come from. When your resources are registered in AgentCore as platform resources (model connections, MCP servers, Skills, MemoryStores, and credentials), you call them by name and the examples run in the AgentCore managed runtime. See the sections from "Call cloud models" through "Use credentials and MCP headers". When your resources come from your own services or ship with your application, your application provides the connection settings and no platform registration is required. See "Connect custom resources".

Call cloud models

Specify the model connection name and the model name in your code. The SDK looks up the model connection in the Workspace that the current Agent belongs to, so you do not need to construct the model endpoint yourself.

import { AgentCore } from 'alibabacloud-agentcore-sdk';

const core = AgentCore.auto();
try {
  const model = await core.model('my-model-connection', { model: 'qwen3.8-max' });
  const response = await model.completion(
    [{ role: 'user', content: 'Describe Hangzhou in one sentence.' }],
    { temperature: 0.2 },
  );
  console.log(response);
} finally {
  await core.close();
}
Parameter Description
my-model-connection The name of the model connection. This is not the model name or the model connection ID.
model The name of a model that is already configured in that connection.
temperature A generation parameter for this request. Whether the model supports this parameter and its valid range depend on the model.

The try/finally pattern in this example is the Core lifecycle that the snippets later in this topic reuse: AgentCore.auto() creates the Core, and await core.close() in the finally block releases its resources.

Streaming output

Within the Core lifecycle of the preceding example, replace the regular call with the following code. A regular call and a streaming call are two separate requests, so choose one based on your needs.

for await (const chunk of model.stream([{ role: 'user', content: 'Describe Hangzhou in one sentence.' }])) {
  console.log(chunk);
}
Note

The response data structure is determined by the protocol of the model connection. Anthropic models return the data structure of their own protocol, so do not parse them with choices. OpenAI/v1 connections can use responses() and responsesStream(), and the model must support the Responses API. The SDK does not fall back to Chat Completions when a call fails. The managed model client does not provide embedding calls. The embedding() method of a custom model client works only with services and models that support vector generation.

Use MCP tools

The following snippet runs within the lifecycle of an existing core. Listing tools only discovers them; it does not run any tool.

const mcp = await core.mcp('my-mcp');
const availableTools = await mcp.listTools();
for (const tool of availableTools) {
  console.log(tool.name, tool.description, tool.parameters);
}

// Replace these with the tool name and parameters that the MCP server actually provides.
const result = await mcp.callTool('<tool-name>', { '<parameter-name>': '<parameter-value>' });

To let the model select and run tools, use the framework integration example later in this topic. A model call by itself does not run MCP tools.

Use Skills

A Skill contains task instructions and optional supporting files or scripts. After you load a Skill, connect it to your Agent through a framework adapter.

const skill = await core.skills.managed('my-skill', '1.0.0');
console.log(skill.name, skill.version);

1.0.0 must be a version of the Skill that is in the Published state. If you omit the version, the platform resolves the default version. Specify a version explicitly when you need to keep the behavior of your application fixed.

Important

Loading a Skill is not the same as running it. Skill tools can run the scripts or commands inside the package, so use only Skills from trusted sources. If you do not need command execution, set ALLOW_EXECUTE_COMMAND=false in the application runtime. The programs and dependencies that a Skill needs must still be included in the application runtime.

Use memory

A MemoryStore saves and retrieves long-term memory. It is a different capability from the conversation history that you send to a model: after you retrieve memories, your application code or a framework adapter must pass them to the model as reference information.

Write and retrieve memories

The following snippet runs within the lifecycle of an existing core. The example writes data, so use a MemoryStore that is suitable for testing.

const store = core.memoryStore('my-memory');
await store.addMemories({
  scope: { userId: 'example-user', sessionId: 'example-session' },
  text: 'The user prefers short answers in Chinese.',
});

const result = await store.searchMemories('What response preferences does the user have?', {
  scope: { userId: 'example-user' },
  topK: 5,
});
for (const hit of result.memories) {
  console.log(hit.memory.content.text);
}
Parameter Description
userId The logical identifier of a business user. Use it to organize memories by user.
agentId The logical identifier of an Agent. Define it based on your business needs. You do not need to provide it in every call.
sessionId The session identifier. When you write a memory, it marks the source of the memory. When you search, passing it limits the results to that session.
topK The maximum number of results that a search returns.

Usage notes:

  • The Workspace that the MemoryStore belongs to comes from the resource context of the Core, so you usually do not need to pass it again in each memory call.

  • When you write, you can omit all three scope fields, and the fields that you do not pass fall into the server-side default scope. When you search, a field that you do not pass does not limit that dimension.

  • In a multi-user application, pass the scopes that you need explicitly to avoid retrieving memories that should not be shared.

  • To use user preferences across sessions, write memories by user and do not limit sessionId when you search.

  • Scope fields must come from a trusted business context. Do not let a model generate or change them freely. They provide logical partitioning and are not a replacement for access credentials or permission checks.

  • A newly written memory can take some time before it becomes searchable. Do not write the same content repeatedly just because the first search returns nothing.

  • To query session messages, use listMemorySessionMessages(). This method requires a session ID and at least one of the user ID and the Agent ID.

Integrate memory into the framework execution flow

A framework adapter can retrieve memories before the model runs and write memories back after the run, based on its configuration. Connecting only a model adapter or a tool adapter does not enable memory automatically. For the adapter entry point of each framework, see the "Framework integrations" section. Each framework has a different lifecycle, so connect memory writes to the corresponding middleware, node, or session persistence interface. Do not submit the entire history again after every model call.

Use credentials and MCP headers

Retrieve managed credentials

After you create a credential on the platform and complete authorization, you can read it by name. The following snippet runs within the core lifecycle.

const credential = await core.credentials.get('my-api-key');
const apiKey = credential.value; // Pass this to the client that needs the credential. Do not print it.

const headerCredential = await core.credentials.get('my-mcp-header');
const headers = headerCredential.asHeaders();

Use value for an API key credential and asHeaders() for an MCP header credential. Do not write credential values into source code, logs, or external responses.

Bind a credential to an MCP server

const mcp = await core.mcp('my-mcp', {
  credentialName: 'my-mcp-header',
  headers: { 'x-business-id': 'my-app' },
});

Both credentialName and headers are optional. The MCP header credential that you bind must be allowed to apply to that MCP server.

Important

headers is a fixed client-level setting that applies to the MCP handshake, tool discovery, and tool calls. It is not a per-request user identity parameter, so do not change headers on a shared client to switch users. Header names are case-insensitive. A conflict between platform headers, credential headers, and custom headers raises an error instead of overwriting a value. You cannot overwrite platform authentication fields such as Authorization, and you cannot manually set protocol fields such as Host and Mcp-Session-Id. The SDK does not automatically copy all inbound headers.

Connect custom resources

Your own models, MCP servers, and Skills that ship with your application do not need to be registered as platform resources. Your application provides the following settings, and the environment variables in the example are not configuration items that the SDK reads automatically.

import { AgentCore } from 'alibabacloud-agentcore-sdk';

const core = new AgentCore();
try {
  const model = core.directModel({
    provider: 'openai',
    model: process.env.CUSTOM_MODEL_NAME!,
    baseURL: process.env.CUSTOM_MODEL_BASE_URL!,
    apiKey: process.env.CUSTOM_MODEL_API_KEY!,
  });
  console.log(await model.completion([{ role: 'user', content: 'Hello' }]));

  const mcp = core.directMCP({ url: process.env.CUSTOM_MCP_URL! });
  console.log((await mcp.listTools()).map(tool => tool.name));
  const skills = await core.skills.local('./skills');
  console.log(skills.map(skill => skill.name));
} finally {
  await core.close();
}
Setting Description
CUSTOM_MODEL_NAME The name of a model that your own service supports.
CUSTOM_MODEL_BASE_URL The base URL of the model API. An OpenAI-compatible service usually includes /v1. Follow the documentation of your service.
CUSTOM_MODEL_API_KEY The API key of the model service. Provide it through the runtime environment or a secrets manager.
CUSTOM_MCP_URL The full access URL of the MCP server. The default transport is Streamable HTTP. For an SSE service, set transport: 'sse' explicitly.
./skills The directory of Skills that ship with your application. Each Skill must contain a SKILL.md file and the files that it references.

When a directly connected MCP server requires authentication, provide headers through headersProvider. The stdio transport does not use HTTP headers.

Build an Agent service with LangChain

The following example connects a cloud model, an MCP server, and a Skill to LangChain and serves them through AgentCoreServer. Before you start, prepare my-model-connection, my-mcp, and my-skill, install the framework dependencies described earlier, and make sure that the application runs on Node.js 22.22 or later.

The example handles only the latest user text message and does not store conversation history. For multi-turn conversations, your application or framework must maintain the history and the checkpoints.

Save the following code as app.ts. This example uses the ES module configuration that is described in the "Runtime environment" section.

import { createAgent } from 'langchain';
import { HumanMessage } from '@langchain/core/messages';
import { AgentCore } from 'alibabacloud-agentcore-sdk';
import { AgentCoreServer } from 'alibabacloud-agentcore-sdk/server';
import {
  AgentCoreConverter, model, tools, skillTools,
} from 'alibabacloud-agentcore-sdk/integrations/langchain';

const core = AgentCore.auto({ logger: console });

async function buildAgent() {
  const client = await core.model('my-model-connection', { model: 'qwen3.8-max' });
  const mcp = await core.mcp('my-mcp');
  const skill = await core.skills.managed('my-skill');
  return createAgent({
    model: await model(client),
    tools: [...tools(await mcp.listTools()), ...skillTools([skill])],
    systemPrompt: 'Use the tools to complete the request. Do not fabricate tool results.',
  });
}

let agent: Awaited<ReturnType<typeof buildAgent>>;
const server = new AgentCoreServer({
  logger: console,
  startup: async () => {
    try { agent = await buildAgent(); }
    catch (error) { await core.close(); throw error; }
  },
  shutdown: () => core.close(),
  readiness: () => agent !== undefined,
  invoke: async function* (request) {
    const message = request.messages.at(-1);
    if (message?.role !== 'user' || typeof message.content !== 'string') {
      throw new Error('This example supports only user text messages.');
    }
    const events = agent.streamEvents(
      { messages: [new HumanMessage(message.content)] },
      { version: 'v2', signal: request.signal },
    );
    yield* new AgentCoreConverter().stream(events);
  },
});

await server.start({ port: 9000, hostname: '0.0.0.0' });
for (const signal of ['SIGINT', 'SIGTERM'] as const) {
  process.once(signal, () => {
    void server.close().catch(error => {
      console.error(error);
      process.exitCode = 1;
    });
  });
}

The example code has four logical parts: import the dependencies; build the Agent in buildAgent, which connects the model, MCP tools, and the Skill; configure the AgentCoreServer lifecycle and request handling with startup, shutdown, readiness, and invoke; and start the server and handle exit signals.

Run the following start command in the application runtime, and make sure that tsx is installed:

npx tsx app.ts

Deployment configuration

Package your application code and dependencies and deploy them to AgentCore. The runtime must include the SDK and framework dependencies described earlier. If you use a container image, install the dependencies when you build the image.

Setting Value in this topic
Listen address 0.0.0.0
Service port 9000
Node.js start command npx tsx app.ts
Liveness check GET /healthz
Readiness check GET /readyz

The port that you configure on the platform must match the port that your application listens on. The SDK does not upload code, build images, or deploy applications.

Call the Agent service

Replace https://<agent-endpoint> in the following examples with the actual access address of your application, and add the authentication information that your application requires. This address is the address of the Agent application, not the address of a model provider.

AG-UI

curl -N 'https://<agent-endpoint>/ag-ui/agent' \
  -H 'Content-Type: application/json' \
  -d '{
    "threadId": "example-thread-1",
    "runId": "example-run-1",
    "messages": [{"id": "message-1", "role": "user", "content": "List the available Skills and complete a demonstration as instructed."}],
    "state": {},
    "tools": [],
    "context": [],
    "forwardedProps": {}
  }'

Use a new runId for each run. You can reuse the same threadId for one conversation, but that does not make the preceding example save history automatically. The "tools": [] field in the request does not disable the tools that are configured in the Agent code.

A successful run starts with RUN_STARTED and ends with RUN_FINISHED. When a tool call occurs, the service emits tool call and tool result events and correlates them through the same toolCallId. Whether a tool is called depends on the model and the task. A failed run emits RUN_ERROR.

OpenAI Chat Completions

curl -N 'https://<agent-endpoint>/openai/v1/chat/completions' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "agentcore",
    "messages": [{"role": "user", "content": "Hello"}],
    "stream": true
  }'

A streaming response ends with [DONE]. Set stream to false to get a single JSON response.

model is a required field in the OpenAI request format. This example always uses the model connection that the application code specifies and does not switch the downstream model based on this field. To query the protocol model list of the application, use GET /openai/v1/models. This list is not the model catalog of the Workspace.

Choose a protocol

Capability AG-UI OpenAI Chat Completions
Text output Supported. Supported.
Multiple message boundaries Keeps the start, content, and end events of a text message. Aggregates the text of one completion into a single assistant message.
Tool calls Emits tool call events and keeps the call ID. Emits tool_calls.
Tool results Emits separate tool result events. Does not provide separate tool result response events.
Use cases Shows the multi-step execution process of an Agent, including tool calls and results. Integrates clients that use the Chat Completions format.

The SSE stream of both protocols sends a heartbeat comment after 15 seconds of idle output. A heartbeat is not model output and does not mean that the task has finished.

Important

The framework service example already runs tools on the server side, so the client must not run the received tool call trace again. When you need the complete execution process, pass the complete event stream of the framework to AgentCoreConverter instead of extracting only the text, and create a separate converter for each request. The converter keeps structured message boundaries and tool correlations, and does not guess the message type from the message body.

Framework integrations

Framework Entry point
LangChain integrations/langchain
LangGraph integrations/langgraph
Google ADK integrations/google-adk
Mastra integrations/mastra
AI SDK 6 integrations/ai-sdk

All entry points in the table are prefixed with alibabacloud-agentcore-sdk/. These framework entry points also provide execution event converters, and the input must be the complete event stream of the corresponding framework: LangChain and LangGraph use streamEvents(..., {version: 'v2'}), and AI SDK uses fullStream instead of textStream.

Different frameworks have different event inputs and output timing, so do not reuse the event handling approach of another framework directly.

FAQ

What do I do if a model connection, MCP server, or Skill cannot be found?

Check the Workspace that the application belongs to, the resource names, and the access permissions. The model connection name and the model name are two different parameters. For a Skill, also check whether it is enabled and whether the selected version is published. Do not substitute the resource ID of another Workspace for a name.

Why does the model not call tools after I load MCP tools and Skills?

listTools() and Skill loading only prepare the resources. You must also pass the tools to the Agent framework and select a model that supports tool calls. Even when tools are configured, a simple question might not require a tool call.

Why is a newly written memory not returned by the first search?

Memory processing and the searchable state can be delayed. First check whether the write succeeded and whether the read and write scopes match, and then query again later. Do not replay the write operation.

Does the same session ID automatically restore history?

No. AgentCoreServer handles protocol access and does not persist conversation history for your application. Your application or framework manages the session state, and long-term memory is not a replacement for complete conversation history or framework checkpoints.

Is AgentCoreServer required?

No. You can use the model, MCP, Skill, memory, and credential interfaces in an existing web service or Agent executor. Using AgentCoreServer only reuses its protocol encapsulation and is not a prerequisite for calling cloud resources.

What do I do if cross-origin requests from a browser fail?

The SDK does not open cross-origin access by default. Your application or the ingress gateway must configure CORS based on the actual frontend origins. Do not allow all origins as the default configuration for interfaces that use sensitive credentials.

How do I log troubleshooting information?

Use AgentCore.auto({ logger: console }) and set logger: console for AgentCoreServer. Keep error stacks, request IDs, and failed operations, and avoid printing access keys, complete headers, or sensitive user content.

How do I manage the Core lifecycle?

Reuse one Core within the application lifecycle, and call await core.close() to release resources when the application exits. Do not close a shared Core at the end of each HTTP request while other requests are still using it.

References

  • AgentCore SDK Overview: an overview of SDK capabilities, development language selection, and service protocol comparison.

  • Manage Workspace: create and switch Workspaces. All resources in the examples in this topic belong to a Workspace.

  • Manage Models: add a model connection and configure models in that connection.

  • Manage MCP Servers: create and manage MCP servers for a Workspace.

  • Manage Skill: create a Skill, enable it, and publish a version.

  • Manage credentials: create an API key credential or an MCP header credential and grant it to your application.

  • alibabacloud-agentcore-sdk npm package page: check the latest version of the Node.js SDK.

  • AgentCore product page: learn about the positioning and core features of AgentCore.