How to Manage Teams, Agents, and ACLs Using the Meta-Plane API in TencentDB Agent Memory

The meta-plane API (/v3/meta/*) provides the control-plane for TencentDB Agent Memory, exposing CRUD operations for teams, agents, tasks, and access-control lists through the MetadataClient class located in MemoryProxy/src/meta/client.ts.

All administrative and runtime operations in TencentDB Agent Memory flow through the meta-plane. This lightweight control layer handles authentication, pagination, and envelope unwrapping while exposing endpoints to manage multi-tenant teams, agent inventories, and fine-grained ACLs. According to the TencentDB-Agent-Memory source code, the MetadataClient abstracts the HTTP complexity, allowing services to query team contexts, filter assets by permission, and orchestrate agent tasks with minimal boilerplate.

Meta-Plane Architecture and Core Components

The meta-plane implementation centers on a single HTTP client wrapper that manages stateful connections to the kernel's administrative endpoints.

MetadataClient serves as the primary interface in MemoryProxy/src/meta/client.ts. This class handles the three required authentication headers—Authorization, x-tdai-service-id, and x-tdai-user-key—while automatically paginating results up to the PAGINATION_HARD_LIMIT of 500 records. The client unwraps JSON envelopes (code === 0 checks) and maps HTTP 404 responses to NotFoundError exceptions, simplifying error handling for upstream consumers.

getMetadataClient() acts as the factory singleton used throughout the proxy services. This helper accepts a CoreSkillConfig object, a kernel instance ID (serviceId), and a user key, returning a configured MetadataClient instance ready to execute meta-plane operations.

Authenticating Meta-Plane Requests

Every request to the meta-plane requires three headers injected by the MetadataClient:

  • Authorization: Bearer <serviceToken> – The kernel service token granting proxy-level access.
  • x-tdai-service-id: <serviceId> – The tenant identifier extracted from the incoming request path, isolating teams at the kernel instance level.
  • x-tdai-user-key: <userKey> – The caller's identity token; omitted for system-level operations.

The client automatically appends Content-Type: application/json and respects the configured timeoutMs setting, aborting requests that exceed the threshold.

Managing Teams and Agents

The meta-plane organizes resources hierarchically: users belong to teams, teams contain agents, and agents bind to tasks and assets.

Listing Teams and Membership

To retrieve all teams associated with a specific user, invoke the listTeams(userId) method. This returns an array of team objects containing identifiers, display names, and membership metadata.

const teams = await metadataClient.listTeams("u-abcdef1234");
console.log("User belongs to teams:", teams.map(t => t.team_id));

Querying Agent Inventories

Once you have a teamId, fetch the agents within that team using listAgents(teamId, ownerUserId?). The optional second parameter filters agents by owner, enabling scoped visibility for multi-user teams.

// List only agents owned by the current user within a specific team
const agents = await metadataClient.listAgents("t-12345", "u-abcdef1234");

Enforcing Access Control with ACLs

Access control in TencentDB Agent Memory operates at the asset level, determining which skills, datasets, and configurations a user may read, write, or bind to agents.

Querying Accessible Assets

The listAccessibleAssets(input) method performs kernel-side ACL evaluation. It accepts filters for asset_type (e.g., "skill"), action ("read" or "write"), and visibility ("team" or "private"), returning only assets the caller is permitted to use.

const assets = await metadataClient.listAccessibleAssets({
  user_id: "u-abcdef1234",
  team_id: "t-12345",
  asset_type: "skill",
  action: "read",
  visibility: "team",  // Excludes private assets owned by other users
});

console.log("Permitted skill IDs:", assets.map(a => a.asset_id));

Binding Assets to Agents

When configuring an agent, retrieve its fixed assets with visibility filtering applied via getAgentFixedAssets(agentId, {applyVisibilityFilter}). Setting applyVisibilityFilter: true (the default) removes assets the caller cannot bind, preventing runtime permission errors.

const { items: boundAssets } = await metadataClient.getAgentFixedAssets(
  "a-9876",
  { applyVisibilityFilter: true }
);

Task Lifecycle Management

Tasks represent executable workloads assigned to agents. The meta-plane supports full CRUD operations for task entities.

Creating and Updating Tasks

Instantiate a new task using createTask(input), providing the team_id, creator_user_id, and task metadata. Modify existing tasks via updateTask(taskId, patch), passing partial objects to modify status, priority, or description fields.

// Create a task
const task = await metadataClient.createTask({
  team_id: "t-12345",
  creator_user_id: "u-abcdef1234",
  title: "Database optimization analysis",
  description: "Analyze slow query logs from production cluster",
});

// Update status upon completion
await metadataClient.updateTask(task.task_id, { 
  status: "completed",
  result_summary: "Indexes recommended"
});

Complete Implementation Workflow

Initializing the Client

First, obtain a configured client using the factory function. The serviceId typically derives from the request path, while the userKey comes from session authentication.

import { getMetadataClient } from "./meta/client.js";
import type { CoreSkillConfig } from "../types.js";

const coreConfig: CoreSkillConfig = {
  endpoint: "https://kernel.example.com",
  serviceToken: "svc-xxxxxxxxxxxx",
  timeoutMs: 5000,
};

const metadataClient = getMetadataClient(
  coreConfig, 
  "mem-prod001",              // serviceId from request path
  "sk-mem-1234567890abcdef"   // userKey from session
);

Orchestrating Team Discovery and Agent Configuration

Combine team listing with ACL queries to build a complete operational context:

const userId = "u-abcdef1234";

// Discover teams
const teams = await metadataClient.listTeams(userId);

for (const team of teams) {
  // List agents in this team
  const agents = await metadataClient.listAgents(team.team_id, userId);
  
  // Query accessible skills for this team context
  const skills = await metadataClient.listAccessibleAssets({
    user_id: userId,
    team_id: team.team_id,
    asset_type: "skill",
    action: "read"
  });
  
  console.log(`Team ${team.team_id}: ${agents.length} agents, ${skills.length} accessible skills`);
}

Recording Participation Logs

Audit operational events using appendParticipationLog(input) to track which users interact with specific agents and tasks. Query historical participation via listParticipationLogs(input) for compliance reporting.

await metadataClient.appendParticipationLog({
  team_id: "t-12345",
  task_id: "task-67890",
  agent_id: "a-9876",
  user_id: "u-abcdef1234",
  action: "task_completed"
});

Summary

  • The MetadataClient in MemoryProxy/src/meta/client.ts encapsulates all meta-plane communication, handling authentication headers, pagination, and error mapping for TencentDB Agent Memory.
  • Team and agent management relies on listTeams() and listAgents() methods, which support user-scoped filtering for multi-tenant environments.
  • ACL enforcement occurs server-side via listAccessibleAssets(), which evaluates user permissions against asset visibility settings before returning results.
  • Task orchestration uses createTask() and updateTask() to manage agent workloads, while getAgentFixedAssets() ensures only permissible resources bind to agents.
  • All meta-plane routes require three authentication headers—Authorization, x-tdai-service-id, and x-tdai-user-key—validated by the underlying TDAIClient in MemoryProxy/src/tdai/client.ts.

Frequently Asked Questions

What is the difference between the meta-plane API and the data-plane API in TencentDB Agent Memory?

The meta-plane API (/v3/meta/*) serves as the control-plane for administrative operations—managing teams, agents, tasks, and ACLs—while the data-plane handles actual agent execution and skill invocation. The MetadataClient exclusively targets the meta-plane endpoints defined in MemoryProxy/src/meta/client.ts, whereas skill execution flows through separate bridges found in MemoryProxy/src/skill/skill-bridge.ts.

How does the meta-plane API handle pagination for large team or agent lists?

The MetadataClient automatically aggregates paginated results by making sequential requests using limit and offset parameters until reaching the PAGINATION_HARD_LIMIT of 500 records. Consumers receive the complete dataset as a single array without manually handling pagination tokens, as implemented in the request loop within MemoryProxy/src/meta/client.ts.

Can I use the meta-plane API for system-level operations without a user key?

Yes. While most operations require the x-tdai-user-key header for user-contextual ACL evaluation, system-level calls may omit this header when performing administrative tasks across all tenants. However, the Authorization and x-tdai-service-id headers remain mandatory for all requests to authenticate the proxy service and isolate kernel instances.

Where does the proxy service obtain the team and agent context during session initialization?

The session initialization logic in MemoryProxy/src/session/workbuddy/init.ts demonstrates the standard pattern: it calls getMetadataClient() to instantiate a client, then invokes listTeams() and listAgents() to build the session context. This file also queries listAccessibleAssets() to construct the whitelist of visible skills before handing control to the skill bridge.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →