Skip to main content

Multi-Agent Collaboration

The Problem

In a multi-agent system, each agent operates in isolation. Agent A researches a topic, Agent B writes content based on it, and Agent C handles QA — but they can't share what they learn. Every handoff requires manually passing context through the orchestrator, which is fragile and doesn't scale.

The Solution

Use a shared Memsolus workspace as the common memory space. Each agent writes memories under its own userId, and all agents can search the full workspace to find what any other agent has stored. No orchestrator plumbing required.

How It Works

Agent A stores a memory under its userId in the shared workspace

Memsolus processes and indexes it

Agent B searches the workspace and finds Agent A's memory

Agent B stores its own findings under its own userId

All agents have access to the growing shared knowledge

Implementation

Install the SDK

npm install @memsolus/sdk

Initialize the client

import { Memsolus } from '@memsolus/sdk';

const memsolus = new Memsolus({
apiKey: process.env.MEMSOLUS_API_KEY,
});

Define agent identifiers

Each agent gets its own userId. All agents share the same workspace — determined by the API key.

const AGENTS = {
researcher: 'agent_researcher',
writer: 'agent_writer',
qa: 'agent_qa',
};

Agent A stores findings in the shared workspace

// Researcher agent stores findings
await memsolus.memories.add({
content:
'Research finding: TypeScript 5.5 introduces native type narrowing for ' +
'array filter predicates. No more manual type assertions after .filter().',
userId: AGENTS.researcher,
metadata: {
topic: 'typescript',
source: 'typescript-blog',
agent: 'researcher',
},
});

await memsolus.memories.add({
content:
'Research finding: The TypeScript 5.5 release also improves performance ' +
'of the language server by approximately 20% for large projects.',
userId: AGENTS.researcher,
metadata: {
topic: 'typescript',
source: 'typescript-blog',
agent: 'researcher',
},
});

Agent B reads Agent A's memories from the shared workspace

// Writer agent searches the workspace — finds what the researcher stored
const researchFindings = await memsolus.memories.search({
query: 'TypeScript 5.5 new features',
mode: 'hybrid',
limit: 10,
});

researchFindings.data.forEach((memory) => {
console.log(`[${memory.metadata?.agent}] ${memory.content}`);
});
// => [researcher] TypeScript 5.5 introduces native type narrowing...
// => [researcher] The TypeScript 5.5 release also improves performance...

// Writer stores its draft based on the research
await memsolus.memories.add({
content:
'Draft section written: "TypeScript 5.5 ships two major improvements — ' +
'smarter type narrowing for array filters and a 20% language server speedup."',
userId: AGENTS.writer,
metadata: {
agent: 'writer',
type: 'draft',
},
});

Agent C reviews everything in the workspace

// QA agent retrieves the compiled knowledge for the workspace
const workspaceKnowledge = await memsolus.knowledge.get({
merged: true,
});

console.log(workspaceKnowledge.content);
// => Structured document with all research findings and draft content

// QA agent stores feedback
await memsolus.memories.add({
content:
'QA feedback: The draft is accurate. Add a code example showing the ' +
'filter predicate narrowing before publishing.',
userId: AGENTS.qa,
metadata: {
agent: 'qa',
type: 'feedback',
},
});

MCP Configuration for Multi-Agent Systems

If your agents use the MCP server, configure each agent with its own MEMSOLUS_USER_ID pointing at the same workspace:

{
"mcpServers": {
"memsolus-researcher": {
"command": "npx",
"args": ["-y", "@memsolus/mcp"],
"env": {
"MEMSOLUS_API_KEY": "msk_live_...",
"MEMSOLUS_USER_ID": "agent_researcher"
}
},
"memsolus-writer": {
"command": "npx",
"args": ["-y", "@memsolus/mcp"],
"env": {
"MEMSOLUS_API_KEY": "msk_live_...",
"MEMSOLUS_USER_ID": "agent_writer"
}
}
}
}

Each agent has its own MEMSOLUS_USER_ID so memories are attributed correctly. They share the same API key so all memories are stored in and retrieved from the same workspace.

Complete Pipeline Example

import { Memsolus } from '@memsolus/sdk';

const memsolus = new Memsolus({ apiKey: process.env.MEMSOLUS_API_KEY });

const AGENTS = {
researcher: 'agent_researcher',
writer: 'agent_writer',
qa: 'agent_qa',
};

async function runContentPipeline(topic: string): Promise<void> {
// Step 1: Researcher stores findings
await researcherAgent(AGENTS.researcher, topic);

// Step 2: Writer reads findings and produces draft
await writerAgent(AGENTS.writer, topic);

// Step 3: QA reviews everything
await qaAgent(AGENTS.qa);

// Final: Get the full compiled output
const result = await memsolus.knowledge.get({ merged: true });

console.log('Pipeline complete:\n', result.content);
}

async function researcherAgent(agentId: string, topic: string): Promise<void> {
// In production: call a research tool, web search, or LLM
await memsolus.memories.add({
content: `Research on "${topic}": [findings would go here]`,
userId: agentId,
metadata: { agent: 'researcher', topic },
});
}

async function writerAgent(agentId: string, topic: string): Promise<void> {
const findings = await memsolus.memories.search({
query: topic,
mode: 'hybrid',
limit: 20,
});

const researchContext = findings.data.map((m) => m.content).join('\n');

// In production: call LLM with researchContext to generate draft
await memsolus.memories.add({
content: `Draft for "${topic}": [draft based on ${findings.data.length} research findings]`,
userId: agentId,
metadata: { agent: 'writer', topic, type: 'draft' },
});
}

async function qaAgent(agentId: string): Promise<void> {
const allContent = await memsolus.knowledge.get({ merged: true });

// In production: call LLM to review the compiled content
await memsolus.memories.add({
content: 'QA review complete. Content approved for publishing.',
userId: agentId,
metadata: { agent: 'qa', type: 'approval' },
});
}

What's Next