Knowledge Base
A knowledge base gives your Agent private background knowledge: once your product docs, FAQs, or internal materials are connected, the Agent retrieves relevant content first and answers based on what it found, instead of relying only on the model's general knowledge.
In CloudBase, a knowledge base is connected to an Agent as an MCP tool: the retrieval service exposes an MCP server, the Agent declares that server in agent.yaml, and retrieval becomes callable during a conversation.
This page follows the actual order of work: pull the code, deploy the retrieval service, write the configuration, deploy, verify.
Prerequisites
- An Agent created in the CloudBase console using the official
cloudbase-agenttemplate (an OpenAgentKernel project) - CloudBase CLI installed locally, with
tcb logincompleted - Node.js ≥ 20
Step 1: Pull the Agent code
On the Agent detail page in the console, follow the instructions on the Local development tab to pull the code:

You can also pull it with the CLI, where <function-name> is the cloud function backing the Agent:
tcb fn code download <function-name> ./agent-code -e <env-id>
Project structure:
agent-code/
├── agent.yaml # Agent configuration, see Step 3
├── package.json
├── scf_bootstrap # Cloud function startup script
├── dist/ # Build output
├── node_modules/
└── src/
├── index.ts # HTTP entry point, listens on port 9000 by default
├── config.ts # Configuration loading
├── managed/
└── oak-runtime/
Step 2: Deploy the knowledge base MCP server
The knowledge base MCP server is a standalone HTTP service — Cloud Run, a cloud function, or any reachable address works. Here is a minimal implementation using @modelcontextprotocol/sdk in stateless mode:
import express from "express";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { z } from "zod";
function buildServer() {
const server = new McpServer({ name: "kb", version: "1.0.0" });
server.tool(
"search",
"Search the knowledge base. Use when the user asks product-specific questions.",
{ query: z.string().describe("Search keywords") },
async (args) => {
const hits = await searchKnowledge(args.query); // Replace with your own retrieval, see "Implementing retrieval" below
if (hits.length === 0) return { content: [{ type: "text", text: "No relevant documents found." }] };
return { content: [{ type: "text", text: hits.map((d) => `[${d.id}] ${d.title}\n${d.content}`).join("\n---\n") }] };
},
);
return server;
}
const app = express();
app.use(express.json());
app.post("/mcp", async (req, res) => {
// Stateless mode: build a new server + transport per request; handleRequest must receive req.body as its third argument
const server = buildServer();
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
res.on("close", () => { transport.close(); server.close(); });
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
});
app.listen(Number(process.env.PORT ?? 8080));
After deploying, check that the tool is registered. The Streamable HTTP protocol requires the Accept: application/json, text/event-stream header — omitting either value returns a 406:
curl -X POST https://your-kb-service.example.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
The response should include the search tool.
Implementing retrieval
How you implement searchKnowledge is up to you. Common choices:
- CloudBase database: split documents into chunks, store them with their vectors in the CloudBase database (PostgreSQL), and retrieve by vector similarity
- An existing Elasticsearch or other search service: forward the query from inside
searchKnowledge - Small knowledge sets (a few dozen entries): a plain array with keyword matching
Step 3: Declare the knowledge base in agent.yaml
agent.yaml sits in the project root. It is the Agent's configuration file and is deployed together with the code package. Declare the MCP server there and mount it on the Agent:
name: my-agent
model: deepseek-v4-pro
system: You are an assistant. Search the knowledge base before answering.
mcp_servers:
- type: url
name: kb
url: https://your-kb-service.example.com/mcp
tools:
- type: mcp_toolset
mcp_server_name: kb
default_config:
enabled: true
permission_policy:
type: always_allow
mcp_servers declares which MCP servers exist; tools declares which of them the Agent may use. The two must appear together — an entry in mcp_servers that is never mounted under tools will not be called.
If the project root does not have an agent.yaml yet, create one. The name, model, and system fields must all be present.
Field reference
| Field | Required | Description |
|---|---|---|
name | Yes | Agent name |
model | Yes | Model ID; must already be enabled in the console |
system | Yes | System prompt |
mcp_servers[].type | Yes | Only url is supported (remote HTTP MCP server); other values are ignored without an error |
mcp_servers[].name | Yes | Server alias, referenced from tools |
mcp_servers[].url | Yes | HTTP address of the MCP server |
tools[].mcp_server_name | Yes | Matches mcp_servers[].name |
tools[].default_config.enabled | No | Whether the toolset is enabled; enabled by default |
tools[].default_config.permission_policy.type | No | always_allow calls automatically, always_ask prompts every time |
Configuration sources and precedence
The runtime resolves configuration in a fixed order and stops at the first match:
- The
AGENT_CONFIG/AGENT_CONFIG_B64environment variables — a dynamic delivery channel intended for tooling; you do not need to set these by hand agent.yaml— the recommended approach; configuration travels with the code and can be version-controlled- The
AGENT_NAME/AGENT_MODEL/AGENT_SYSTEMenvironment variables — fallbacks for those three fields
Those same three environment variables also take precedence when present, overriding the matching fields from the layers above. The startup log prints only the final effective value.
If AGENT_MODEL is set on the function, changing model in agent.yaml has no effect — while name and system do change, which is easy to misread. Clearing these environment variables and managing everything from agent.yaml gives the most predictable behavior.
To view or change function environment variables, use Cloud Functions / Hosting → Function configuration → Environment variables in the console, or:
tcb agent update <agent-id> --env <KEY>=<VALUE>
Step 4: Deploy back to the cloud
agent.yaml only takes effect in the cloud when it is deployed together with the code package — the runtime reads /var/user/agent.yaml from the unpacked bundle. Creating it locally without deploying leaves the cloud unaware of it.
cd ./agent-code
tcb fn code update <function-name> --dir . -e <env-id>
The command asks for confirmation; choose Update with current config. While deploying, the function is in the Updating state and operations such as tcb fn code download are rejected.
Step 5: Verify
Trigger a cold start
Configuration is read when the process starts. After a deployment, existing instances may still be serving the previous configuration, so behavior will not change yet. Send one or two messages on the Integration & debugging tab to bring up a new instance.
Read the startup log
tcb logs search --query "function_name:\"<function-name>\" AND (\"[Agent]\" OR \"[Config]\")" \
--timeRange 30m -e <env-id>
A successful mount looks like this:
[Config] Loaded agent config from: /var/user/agent.yaml
[Agent] Name: my-agent
[Agent] Runtime: managed
[Agent] Model: deepseek-v4-pro
[Agent] Tools: 1 configured
[Agent] MCP Servers: 1 configured
[KernelAdapter] kernel Agent created (id=...)
Troubleshooting table:
| Symptom | Meaning |
|---|---|
No Init Report ... Coldstart in the log | The request was served by an old instance and the configuration has not been reloaded; send another message or two |
[Config] Loaded agent config from: /var/user/agent.yaml | Configuration was loaded from the yaml in the code package |
[Config] No agent.yaml or AGENT_CONFIG found, using environment variables | No yaml found, defaults are in use; check that the file was deployed with the code package |
[Agent] MCP Servers: 0 configured | mcp_servers is missing from the yaml, or type is not url and the entry was skipped |
[Agent] Tools: 0 configured | mcp_servers is declared but not mounted under tools |
Send a message
On the Integration & debugging tab, ask a question that can only be answered from the knowledge base. The Agent calls mcp__kb__search first, then answers based on what it retrieved — the corresponding tool_call appears in the event stream.
Client-side integration is unchanged for Mini Programs, Web, and other clients — keep following the existing integration guide.
FAQ
I changed agent.yaml and deployed, but nothing changed
Check in order:
- Whether the log contains
Init Report ... Coldstart. If not, an old instance is still serving; send another message or two to trigger a cold start - Whether the
[Config]line readsLoaded agent config from: /var/user/agent.yaml. If it readsNo agent.yaml or AGENT_CONFIG found, the file did not make it into the code package — confirm it sits at the root of the deployed directory
The system prompt changed but the model did not
The AGENT_MODEL environment variable on the function takes precedence over model in agent.yaml. See Configuration sources and precedence.
Does an undeployed MCP server prevent the Agent from starting
No. MCP servers are connected on demand; startup only registers the configuration and performs no connectivity check. If the address is temporarily unreachable, the Agent still starts and ordinary conversation is unaffected — only the retrieval tool call itself fails. You can finish the configuration before deploying the retrieval service.
Which MCP server types are supported
Only type: url, a remote MCP server reachable over HTTP. Other types are ignored silently without an error, showing up as a lower-than-expected [Agent] MCP Servers count.
Can configuration be changed without redeploying the code
Changes to agent.yaml require redeploying the code package. The runtime also has an environment-variable-based dynamic delivery channel (AGENT_CONFIG) intended for the accompanying tooling; setting it by hand is not recommended.