Skip to main content
Glama

memory_agent_network

Enables multi-agent systems to share memories, synchronize knowledge, and collaborate by managing memory registration, sharing, and insight generation across agents.

Instructions

Manage multi-agent memory sharing and collaboration

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform
agentInfoNo
memoryIdNoMemory ID for sharing operations
targetAgentNoTarget agent for sync operations
optionsNo

Implementation Reference

  • Tool schema definition including name, description, and detailed inputSchema with actions for multi-agent memory management.
    {
      name: "memory_agent_network",
      description: "Manage multi-agent memory sharing and collaboration",
      inputSchema: {
        type: "object",
        properties: {
          action: {
            type: "string",
            enum: [
              "register_agent",
              "share_memory",
              "sync_request",
              "get_insights",
              "network_status",
            ],
            description: "Action to perform",
          },
          agentInfo: {
            type: "object",
            properties: {
              name: { type: "string" },
              capabilities: { type: "array", items: { type: "string" } },
              specializations: { type: "array", items: { type: "string" } },
              trustLevel: {
                type: "string",
                enum: ["low", "medium", "high", "trusted"],
              },
            },
          },
          memoryId: {
            type: "string",
            description: "Memory ID for sharing operations",
          },
          targetAgent: {
            type: "string",
            description: "Target agent for sync operations",
          },
          options: {
            type: "object",
            properties: {
              anonymize: { type: "boolean", default: false },
              requireValidation: { type: "boolean", default: false },
            },
          },
        },
        required: ["action"],
      },
    },
  • Primary implementation class providing all functionality for the memory_agent_network tool. Methods directly correspond to the schema's action enum values, handling agent registration, memory sharing, synchronization, insights generation, and network status.
    export class MultiAgentMemorySharing extends EventEmitter {
      private memoryManager: MemoryManager;
      private agentId: string;
      private knownAgents: Map<string, AgentIdentity>;
      private sharedMemories: Map<string, SharedMemory>;
      private syncRequests: Map<string, SyncRequest>;
      private conflicts: Map<string, ConflictResolution>;
      private collaborativeInsights: Map<string, CollaborativeInsight>;
      private syncInterval: NodeJS.Timeout | null = null;
    
      constructor(
        memoryManager: MemoryManager,
        agentIdentity: Partial<AgentIdentity>,
      ) {
        super();
        this.memoryManager = memoryManager;
        this.agentId = agentIdentity.id || this.generateAgentId();
        this.knownAgents = new Map();
        this.sharedMemories = new Map();
        this.syncRequests = new Map();
        this.conflicts = new Map();
        this.collaborativeInsights = new Map();
    
        // Register self
        this.registerAgent({
          id: this.agentId,
          name: agentIdentity.name || "DocuMCP Agent",
          version: agentIdentity.version || "1.0.0",
          capabilities: agentIdentity.capabilities || [
            "analysis",
            "recommendation",
            "deployment",
          ],
          lastSeen: new Date().toISOString(),
          trustLevel: "trusted",
          specializations: agentIdentity.specializations || [],
        });
      }
    
      /**
       * Initialize multi-agent sharing
       */
      async initialize(): Promise<void> {
        await this.loadSharedMemories();
        await this.loadKnownAgents();
        await this.loadPendingSyncRequests();
    
        // Start periodic sync
        this.startPeriodicSync();
    
        this.emit("initialized", { agentId: this.agentId });
      }
    
      /**
       * Register a new agent in the network
       */
      async registerAgent(agent: AgentIdentity): Promise<void> {
        this.knownAgents.set(agent.id, {
          ...agent,
          lastSeen: new Date().toISOString(),
        });
    
        await this.persistAgentRegistry();
        this.emit("agent-registered", agent);
      }
    
      /**
       * Share a memory entry with other agents
       */
      async shareMemory(
        memoryId: string,
        targetAgents?: string[],
        options?: {
          anonymize?: boolean;
          requireValidation?: boolean;
          trustLevel?: number;
        },
      ): Promise<SharedMemory> {
        const memory = await this.memoryManager.recall(memoryId);
        if (!memory) {
          throw new Error(`Memory ${memoryId} not found`);
        }
    
        // Create shared memory wrapper
        const sharedMemory: SharedMemory = {
          originalEntry: this.anonymizeIfRequired(memory, options?.anonymize),
          sharingMetadata: {
            sourceAgent: this.agentId,
            sharedAt: new Date().toISOString(),
            accessCount: 0,
            trustScore: this.calculateInitialTrustScore(memory),
            validatedBy: [],
            conflicts: [],
          },
          transformations: [],
        };
    
        // Apply anonymization transformation if required
        if (options?.anonymize) {
          sharedMemory.transformations.push({
            agentId: this.agentId,
            transformationType: "anonymization",
            appliedAt: new Date().toISOString(),
            details: { level: "standard", preserveStructure: true },
          });
        }
    
        this.sharedMemories.set(memoryId, sharedMemory);
    
        // Create sync requests for target agents
        if (targetAgents) {
          for (const targetAgent of targetAgents) {
            await this.createSyncRequest(targetAgent, "selective", {
              memoryIds: [memoryId],
            });
          }
        } else {
          // Broadcast to all trusted agents
          await this.broadcastToTrustedAgents(sharedMemory);
        }
    
        await this.persistSharedMemories();
        this.emit("memory-shared", { memoryId, sharedMemory });
    
        return sharedMemory;
      }
    
      /**
       * Receive shared memory from another agent
       */
      async receiveSharedMemory(
        sharedMemory: SharedMemory,
        sourceAgent: string,
      ): Promise<{
        accepted: boolean;
        conflicts?: ConflictResolution[];
        integrationResult?: string;
      }> {
        // Validate source agent trust level
        const sourceAgentInfo = this.knownAgents.get(sourceAgent);
        if (!sourceAgentInfo || sourceAgentInfo.trustLevel === "untrusted") {
          return { accepted: false };
        }
    
        // Check for conflicts with existing memories
        const conflicts = await this.detectConflicts(sharedMemory);
    
        if (conflicts.length > 0) {
          // Store conflicts for resolution
          for (const conflict of conflicts) {
            this.conflicts.set(conflict.conflictId, conflict);
            await this.resolveConflict(conflict);
          }
    
          this.emit("conflict-detected", { conflicts, sharedMemory });
        }
    
        // Integrate the shared memory
        const integrationResult = await this.integrateSharedMemory(
          sharedMemory,
          sourceAgent,
        );
    
        // Update sharing metadata
        sharedMemory.sharingMetadata.accessCount++;
    
        this.emit("memory-received", {
          sharedMemory,
          sourceAgent,
          integrationResult,
        });
    
        return {
          accepted: true,
          conflicts: conflicts.length > 0 ? conflicts : undefined,
          integrationResult,
        };
      }
    
      /**
       * Request synchronization with another agent
       */
      async requestSync(
        targetAgent: string,
        syncType: SyncRequest["requestType"] = "incremental",
        criteria?: SyncRequest["criteria"],
      ): Promise<SyncRequest> {
        const syncRequest: SyncRequest = {
          id: this.generateSyncId(),
          fromAgent: this.agentId,
          toAgent: targetAgent,
          requestType: syncType,
          criteria,
          requestedAt: new Date().toISOString(),
          status: "pending",
        };
    
        this.syncRequests.set(syncRequest.id, syncRequest);
        await this.persistSyncRequests();
    
        this.emit("sync-requested", syncRequest);
        return syncRequest;
      }
    
      /**
       * Process incoming sync request
       */
      async processSyncRequest(syncRequest: SyncRequest): Promise<{
        approved: boolean;
        memories?: SharedMemory[];
        reason?: string;
      }> {
        // Validate requesting agent
        const requestingAgent = this.knownAgents.get(syncRequest.fromAgent);
        if (!requestingAgent || requestingAgent.trustLevel === "untrusted") {
          return { approved: false, reason: "Untrusted agent" };
        }
    
        // Update request status
        syncRequest.status = "in_progress";
        this.syncRequests.set(syncRequest.id, syncRequest);
    
        try {
          // Get memories based on sync type and criteria
          const memories = await this.getMemoriesForSync(syncRequest);
    
          syncRequest.status = "completed";
          this.emit("sync-completed", {
            syncRequest,
            memoriesCount: memories.length,
          });
    
          return { approved: true, memories };
        } catch (error) {
          syncRequest.status = "failed";
          this.emit("sync-failed", { syncRequest, error });
    
          return {
            approved: false,
            reason: error instanceof Error ? error.message : "Unknown error",
          };
        }
      }
    
      /**
       * Generate collaborative insights from shared memories
       */
      async generateCollaborativeInsights(): Promise<CollaborativeInsight[]> {
        const insights: CollaborativeInsight[] = [];
    
        // Analyze trends across agents
        const trends = await this.analyzeTrends();
        insights.push(...trends);
    
        // Find consensus patterns
        const consensus = await this.findConsensusPatterns();
        insights.push(...consensus);
    
        // Identify disagreements that need attention
        const disagreements = await this.identifyDisagreements();
        insights.push(...disagreements);
    
        // Detect anomalies
        const anomalies = await this.detectAnomalies();
        insights.push(...anomalies);
    
        // Store insights
        for (const insight of insights) {
          this.collaborativeInsights.set(insight.id, insight);
        }
    
        await this.persistCollaborativeInsights();
        this.emit("insights-generated", { count: insights.length });
    
        return insights;
      }
    
      /**
       * Validate shared memory against local knowledge
       */
      async validateSharedMemory(sharedMemory: SharedMemory): Promise<{
        isValid: boolean;
        confidence: number;
        issues: string[];
        recommendations: string[];
      }> {
        const issues: string[] = [];
        const recommendations: string[] = [];
        let confidence = 1.0;
    
        // Check data consistency
        if (!this.validateDataStructure(sharedMemory.originalEntry)) {
          issues.push("Invalid data structure");
          confidence *= 0.7;
        }
    
        // Cross-validate with local memories
        const similarMemories = await this.findSimilarLocalMemories(
          sharedMemory.originalEntry,
        );
        if (similarMemories.length > 0) {
          const consistencyScore = this.calculateConsistency(
            sharedMemory.originalEntry,
            similarMemories,
          );
          if (consistencyScore < 0.8) {
            issues.push("Inconsistent with local knowledge");
            confidence *= consistencyScore;
          }
        }
    
        // Check source agent reliability
        const sourceAgent = this.knownAgents.get(
          sharedMemory.sharingMetadata.sourceAgent,
        );
        if (sourceAgent) {
          if (sourceAgent.trustLevel === "low") {
            confidence *= 0.8;
            recommendations.push("Verify with additional sources");
          } else if (
            sourceAgent.trustLevel === "high" ||
            sourceAgent.trustLevel === "trusted"
          ) {
            confidence *= 1.1;
          }
        }
    
        // Validate transformations
        for (const transformation of sharedMemory.transformations) {
          if (transformation.transformationType === "anonymization") {
            // Check if anonymization preserved essential information
            if (!this.validateAnonymization(transformation)) {
              issues.push("Anonymization may have removed critical information");
              confidence *= 0.9;
            }
          }
        }
    
        return {
          isValid: issues.length === 0 || confidence > 0.6,
          confidence: Math.min(confidence, 1.0),
          issues,
          recommendations,
        };
      }
    
      /**
       * Get network statistics
       */
      getNetworkStatistics(): {
        connectedAgents: number;
        sharedMemories: number;
        activeSyncs: number;
        resolvedConflicts: number;
        trustDistribution: Record<string, number>;
        collaborativeInsights: number;
        networkHealth: number;
      } {
        const trustDistribution: Record<string, number> = {};
        for (const agent of this.knownAgents.values()) {
          trustDistribution[agent.trustLevel] =
            (trustDistribution[agent.trustLevel] || 0) + 1;
        }
    
        const activeSyncs = Array.from(this.syncRequests.values()).filter(
          (req) => req.status === "pending" || req.status === "in_progress",
        ).length;
    
        const resolvedConflicts = Array.from(this.conflicts.values()).filter(
          (conflict) => conflict.resolvedAt,
        ).length;
    
        // Calculate network health (0-1)
        const trustedAgents = Array.from(this.knownAgents.values()).filter(
          (agent) => agent.trustLevel === "high" || agent.trustLevel === "trusted",
        ).length;
        const totalAgents = this.knownAgents.size;
        const networkHealth = totalAgents > 0 ? trustedAgents / totalAgents : 0;
    
        return {
          connectedAgents: this.knownAgents.size,
          sharedMemories: this.sharedMemories.size,
          activeSyncs,
          resolvedConflicts,
          trustDistribution,
          collaborativeInsights: this.collaborativeInsights.size,
          networkHealth,
        };
      }
    
      // Private helper methods
    
      private generateAgentId(): string {
        return `agent_${crypto.randomBytes(8).toString("hex")}`;
      }
    
      private generateSyncId(): string {
        return `sync_${Date.now()}_${crypto.randomBytes(4).toString("hex")}`;
      }
    
      private anonymizeIfRequired(
        memory: MemoryEntry,
        anonymize?: boolean,
      ): MemoryEntry {
        if (!anonymize) return memory;
    
        // Create anonymized copy
        const anonymized = JSON.parse(JSON.stringify(memory));
    
        // Remove/hash sensitive information
        if (anonymized.metadata.repository) {
          anonymized.metadata.repository = this.hashSensitiveData(
            anonymized.metadata.repository,
          );
        }
    
        if (anonymized.metadata.projectId) {
          anonymized.metadata.projectId = this.hashSensitiveData(
            anonymized.metadata.projectId,
          );
        }
    
        // Remove file paths and specific identifiers
        if (anonymized.data.files) {
          delete anonymized.data.files;
        }
    
        return anonymized;
      }
    
      private hashSensitiveData(data: string): string {
        return crypto
          .createHash("sha256")
          .update(data)
          .digest("hex")
          .substring(0, 16);
      }
    
      private calculateInitialTrustScore(memory: MemoryEntry): number {
        let score = 0.5; // Base score
    
        // Boost for successful outcomes
        if (memory.data.status === "success") score += 0.2;
    
        // Boost for rich metadata
        if (memory.metadata.tags && memory.metadata.tags.length > 2) score += 0.1;
    
        // Boost for recent data
        const daysSince =
          (Date.now() - new Date(memory.timestamp).getTime()) /
          (1000 * 60 * 60 * 24);
        if (daysSince <= 30) score += 0.1;
    
        // Boost for complete data
        if (memory.checksum) score += 0.1;
    
        return Math.min(score, 1.0);
      }
    
      private async detectConflicts(
        sharedMemory: SharedMemory,
      ): Promise<ConflictResolution[]> {
        const conflicts: ConflictResolution[] = [];
    
        // Check for duplicates
        const similarLocal = await this.findSimilarLocalMemories(
          sharedMemory.originalEntry,
        );
        for (const similar of similarLocal) {
          if (this.isLikelyDuplicate(sharedMemory.originalEntry, similar)) {
            conflicts.push({
              conflictId: `conflict_${Date.now()}_${crypto
                .randomBytes(4)
                .toString("hex")}`,
              conflictType: "duplicate",
              involvedEntries: [sharedMemory.originalEntry.id, similar.id],
              involvedAgents: [
                sharedMemory.sharingMetadata.sourceAgent,
                this.agentId,
              ],
              resolutionStrategy: "merge",
            });
          }
        }
    
        return conflicts;
      }
    
      private async resolveConflict(conflict: ConflictResolution): Promise<void> {
        // Implement conflict resolution based on strategy
        switch (conflict.resolutionStrategy) {
          case "merge":
            await this.mergeConflictingEntries(conflict);
            break;
          case "prioritize_trusted":
            await this.prioritizeTrustedSource(conflict);
            break;
          case "temporal_precedence":
            await this.useTemporalPrecedence(conflict);
            break;
          default:
            // Mark for manual review
            conflict.resolutionStrategy = "manual_review";
        }
    
        conflict.resolvedAt = new Date().toISOString();
        this.conflicts.set(conflict.conflictId, conflict);
      }
    
      private async integrateSharedMemory(
        sharedMemory: SharedMemory,
        sourceAgent: string,
      ): Promise<string> {
        // Add transformation for integration
        sharedMemory.transformations.push({
          agentId: this.agentId,
          transformationType: "enrichment",
          appliedAt: new Date().toISOString(),
          details: { integratedFrom: sourceAgent },
        });
    
        // Store in local memory with special metadata
        const enrichedEntry = {
          ...sharedMemory.originalEntry,
          metadata: {
            ...sharedMemory.originalEntry.metadata,
            sharedFrom: sourceAgent,
            integratedAt: new Date().toISOString(),
            tags: [
              ...(sharedMemory.originalEntry.metadata.tags || []),
              "shared",
              "collaborative",
            ],
          },
        };
    
        await this.memoryManager.remember(
          enrichedEntry.type,
          enrichedEntry.data,
          enrichedEntry.metadata,
        );
    
        return "integrated_successfully";
      }
    
      private async getMemoriesForSync(
        syncRequest: SyncRequest,
      ): Promise<SharedMemory[]> {
        const allMemories = await this.memoryManager.search("", {
          sortBy: "timestamp",
        });
        let filteredMemories = allMemories;
    
        // Apply criteria filtering
        if (syncRequest.criteria) {
          if (syncRequest.criteria.types) {
            filteredMemories = filteredMemories.filter((m) =>
              syncRequest.criteria!.types!.includes(m.type),
            );
          }
    
          if (syncRequest.criteria.tags) {
            filteredMemories = filteredMemories.filter(
              (m) =>
                m.metadata.tags?.some((tag) =>
                  syncRequest.criteria!.tags!.includes(tag),
                ),
            );
          }
    
          if (syncRequest.criteria.timeRange) {
            const start = new Date(syncRequest.criteria.timeRange.start);
            const end = new Date(syncRequest.criteria.timeRange.end);
            filteredMemories = filteredMemories.filter((m) => {
              const memTime = new Date(m.timestamp);
              return memTime >= start && memTime <= end;
            });
          }
        }
    
        // Convert to shared memories
        return filteredMemories.map((memory) => ({
          originalEntry: memory,
          sharingMetadata: {
            sourceAgent: this.agentId,
            sharedAt: new Date().toISOString(),
            accessCount: 0,
            trustScore: this.calculateInitialTrustScore(memory),
            validatedBy: [],
            conflicts: [],
          },
          transformations: [],
        }));
      }
    
      private async analyzeTrends(): Promise<CollaborativeInsight[]> {
        // Analyze shared memories to identify trends
        return []; // Placeholder implementation
      }
    
      private async findConsensusPatterns(): Promise<CollaborativeInsight[]> {
        // Find patterns where multiple agents agree
        return []; // Placeholder implementation
      }
    
      private async identifyDisagreements(): Promise<CollaborativeInsight[]> {
        // Find areas where agents disagree
        return []; // Placeholder implementation
      }
    
      private async detectAnomalies(): Promise<CollaborativeInsight[]> {
        // Detect unusual patterns in shared data
        return []; // Placeholder implementation
      }
    
      private validateDataStructure(entry: MemoryEntry): boolean {
        return Boolean(entry.id && entry.timestamp && entry.type && entry.data);
      }
    
      private async findSimilarLocalMemories(
        entry: MemoryEntry,
      ): Promise<MemoryEntry[]> {
        // Find similar memories in local storage
        return this.memoryManager.search(entry.metadata.projectId || "", {
          sortBy: "timestamp",
        });
      }
    
      private calculateConsistency(
        _entry: MemoryEntry,
        _similar: MemoryEntry[],
      ): number {
        // Calculate consistency score (placeholder)
        return 0.8;
      }
    
      private validateAnonymization(_transformation: any): boolean {
        // Validate anonymization transformation (placeholder)
        return true;
      }
    
      private isLikelyDuplicate(entry1: MemoryEntry, entry2: MemoryEntry): boolean {
        // Simple duplicate detection
        return (
          entry1.type === entry2.type &&
          entry1.metadata.projectId === entry2.metadata.projectId &&
          Math.abs(
            new Date(entry1.timestamp).getTime() -
              new Date(entry2.timestamp).getTime(),
          ) < 60000
        ); // 1 minute
      }
    
      private async mergeConflictingEntries(
        _conflict: ConflictResolution,
      ): Promise<void> {
        // Merge conflicting entries (placeholder)
      }
    
      private async prioritizeTrustedSource(
        _conflict: ConflictResolution,
      ): Promise<void> {
        // Prioritize trusted source (placeholder)
      }
    
      private async useTemporalPrecedence(
        _conflict: ConflictResolution,
      ): Promise<void> {
        // Use temporal precedence (placeholder)
      }
    
      private async broadcastToTrustedAgents(
        _sharedMemory: SharedMemory,
      ): Promise<void> {
        // Broadcast to trusted agents (placeholder)
      }
    
      private startPeriodicSync(): void {
        this.syncInterval = setInterval(
          async () => {
            await this.performPeriodicSync();
          },
          5 * 60 * 1000,
        ); // Every 5 minutes
      }
    
      private async performPeriodicSync(): Promise<void> {
        // Perform periodic synchronization with trusted agents
      }
    
      private async loadSharedMemories(): Promise<void> {
        // Load shared memories from persistence
      }
    
      private async loadKnownAgents(): Promise<void> {
        // Load known agents from persistence
      }
    
      private async loadPendingSyncRequests(): Promise<void> {
        // Load pending sync requests from persistence
      }
    
      private async persistSharedMemories(): Promise<void> {
        // Persist shared memories
      }
    
      private async persistAgentRegistry(): Promise<void> {
        // Persist agent registry
      }
    
      private async persistSyncRequests(): Promise<void> {
        // Persist sync requests
      }
    
      private async persistCollaborativeInsights(): Promise<void> {
        // Persist collaborative insights
      }
    
      private async createSyncRequest(
        _targetAgent: string,
        _type: SyncRequest["requestType"],
        _options: any,
      ): Promise<void> {
        // Create sync request (placeholder)
      }
    
      /**
       * Cleanup and shutdown
       */
      async shutdown(): Promise<void> {
        if (this.syncInterval) {
          clearInterval(this.syncInterval);
        }
    
        await this.persistSharedMemories();
        await this.persistAgentRegistry();
        await this.persistSyncRequests();
        await this.persistCollaborativeInsights();
    
        this.emit("shutdown", { agentId: this.agentId });
      }
    }
    
    export default MultiAgentMemorySharing;
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but only states 'manage' without clarifying behavioral traits. It doesn't disclose whether operations are read-only or destructive, authentication needs, rate limits, or what 'collaboration' entails, leaving significant gaps in understanding tool behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with no wasted words. It's front-loaded with the core purpose, though it could be more specific. The structure is clear but lacks depth.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (5 parameters, nested objects, no output schema, and no annotations), the description is inadequate. It doesn't explain return values, error conditions, or the scope of 'multi-agent' operations, leaving the agent poorly equipped to use this tool effectively in context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 60%, with the 'action' parameter well-documented via enum values. The description adds no parameter-specific semantics beyond the generic 'manage' statement, failing to explain what parameters like 'agentInfo' or 'options' do. Baseline 3 is appropriate as the schema provides moderate coverage without description enhancement.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Manage multi-agent memory sharing and collaboration' states a general purpose but is vague about specific operations. It mentions 'memory sharing and collaboration' which aligns with the tool name, but doesn't specify what 'manage' entails or distinguish it from sibling memory tools like memory_cleanup or memory_export.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives is provided. The description doesn't mention any prerequisites, context for use, or comparisons to sibling tools like memory_contextual_search or memory_insights, leaving the agent with no usage direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tosin2013/documcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server