Skip to content

stdiobus/mcp-agentic

MCP Agentic — Multi-Agent Orchestration Server

Agent orchestration server that connects MCP clients to ACP-compatible agents through stdio Bus.

npm MCP ACP stdioBus Node Build Platform License TypeScript Tests E2E

Agents run in-process (via AgentHandler) or as external worker processes (via @stdiobus/node StdioBus). The single entry point is McpAgenticServer, which owns the MCP server, tool registration, and executor lifecycle.

This is a public sandbox for a broader agent infrastructure platform. The repository serves as an open proving ground for experimenting with MCP-accessible ACP agent orchestration, validating protocol integrations, and stress-testing runtime boundaries before selected capabilities are considered for the broader stdio Bus ecosystem.

Contributions, forks, and production experiments are welcome.

Features

  • Provider Factory API — declarative openAI(), anthropic(), gemini() factories with Zod validation and createMultiProviderAgent() helper
  • Custom providersdefineProvider() contract for third-party and private LLM integrations with discoverable metadata
  • Enriched discoveryagents_discover returns provider kind, capabilities, displayName, and description
  • In-process agents — implement AgentHandler and register directly
  • Worker agents — route to external ACP processes via stdio Bus
  • Multi-provider AI — OpenAI, Anthropic, Google Gemini through native SDKs with a unified AIProvider interface
  • Runtime parameter control — dynamically adjust model, temperature, systemPrompt, and more through MCP tools on every request
  • Provider discovery — discover available providers and their models via agents_discover
  • 8 MCP tools — health, discovery, sessions, cancellation, one-shot delegation
  • Session management — TTL, idle expiry, lifecycle hooks
  • Backpressure — configurable concurrent request limiting
  • Input validation — prompt and metadata size limits
  • Typed errorsBridgeError categories with retryability info

Basic Quick Start

Create a custom entry point that registers your agents before starting the server:

npm install @stdiobus/mcp-agentic
import { McpAgenticServer } from '@stdiobus/mcp-agentic';

const server = new McpAgenticServer({ defaultAgentId: 'my-agent' })
  .register({
    id: 'my-agent',
    capabilities: ['code-analysis'],
    async prompt(sessionId, input) {
      return { text: `Analyzed: ${input}`, stopReason: 'end_turn' };
    },
  });

await server.start();

This is the primary usage path. Without register() calls, no agents are available and delegation tools (tasks_delegate, sessions_create, etc.) will fail.

Multi-Provider Quick Start

Use the factory API to serve multiple AI providers through a single MCP server. Install the provider SDKs you need:

npm install @stdiobus/mcp-agentic
npm install openai @anthropic-ai/sdk @google/generative-ai
import {
  McpAgenticServer,
  openAI,
  anthropic,
  gemini,
  createMultiProviderAgent,
} from '@stdiobus/mcp-agentic';

// 1. Create providers with flat, typed options
const agent = createMultiProviderAgent({
  id: 'multi-ai',
  defaultProviderId: 'openai',
  systemPrompt: 'You are a helpful assistant.',
  providers: [
    openAI({
      apiKey: process.env.OPENAI_API_KEY!,
      models: ['gpt-4o', 'gpt-4o-mini'],
    }),
    anthropic({
      apiKey: process.env.ANTHROPIC_API_KEY!,
      models: ['claude-sonnet-4-20250514'],
    }),
    gemini({
      apiKey: process.env.GOOGLE_AI_API_KEY!,
      models: ['gemini-2.0-flash'],
    }),
  ],
});

// 2. Register and start
const server = new McpAgenticServer({ defaultAgentId: 'multi-ai' })
  .register(agent);

await server.start();

MCP clients can then select a provider per session and override parameters per prompt:

// Create a session with Anthropic
{ "tool": "sessions_create", "arguments": { "agentId": "multi-ai", "metadata": { "provider": "anthropic", "runtimeParams": { "model": "claude-sonnet-4-20250514" } } } }

// Send a prompt with runtime parameter overrides
{ "tool": "sessions_prompt", "arguments": { "sessionId": "...", "prompt": "Explain MCP", "runtimeParams": { "temperature": 0.3, "maxTokens": 200 } } }

// One-shot delegation with a specific provider
{ "tool": "tasks_delegate", "arguments": { "prompt": "Summarize this", "metadata": { "provider": "google-gemini" }, "runtimeParams": { "temperature": 0 } } }

Custom Providers with defineProvider

Use defineProvider() to create custom providers with Zod-validated options and discoverable metadata:

import { z } from 'zod';
import { defineProvider, createMultiProviderAgent, openAI } from '@stdiobus/mcp-agentic';

const myLLM = defineProvider({
  id: 'my-llm',
  kind: 'llm',
  displayName: 'My Custom LLM',
  description: 'Internal LLM service',
  capabilities: { streaming: false, tools: false, vision: false, jsonMode: true },
  schema: z.object({
    endpoint: z.string().url(),
    apiKey: z.string().min(1),
    models: z.array(z.string()).nonempty(),
  }),
  create: (options) => ({
    id: 'my-llm',
    models: options.models,
    async complete(messages, params) {
      const res = await fetch(options.endpoint, {
        method: 'POST',
        headers: { Authorization: `Bearer ${options.apiKey}`, 'Content-Type': 'application/json' },
        body: JSON.stringify({ messages, ...params }),
      });
      const data = await res.json();
      return { text: data.text, stopReason: 'end_turn' as const };
    },
  }),
});

// Use alongside built-in factories
const agent = createMultiProviderAgent({
  id: 'hybrid',
  defaultProviderId: 'openai',
  providers: [
    openAI({ apiKey: process.env.OPENAI_API_KEY!, models: ['gpt-4o'] }),
    myLLM({ endpoint: 'https://my-llm.internal/v1/chat', apiKey: 'sk-...', models: ['my-model'] }),
  ],
});

The factory function returned by defineProvider exposes static metadata for introspection:

myLLM.id;           // 'my-llm'
myLLM.kind;         // 'llm'
myLLM.displayName;  // 'My Custom LLM'
myLLM.description;  // 'Internal LLM service'
myLLM.capabilities; // { streaming: false, tools: false, vision: false, jsonMode: true }
myLLM.schema;       // Zod schema — use for JSON Schema generation

When registered, agents_discover automatically includes displayName, description, kind, and capabilities for custom providers.

Advanced: Low-Level Class-Based API (deprecated)

Deprecation notice: The class-based API (new OpenAIProvider(), new AnthropicProvider(), new GoogleGeminiProvider()) is deprecated. Use the factory functions openAI(), anthropic(), gemini() instead. Manual ProviderRegistry + MultiProviderCompanionAgent wiring is replaced by createMultiProviderAgent().

import { McpAgenticServer, ProviderRegistry, OpenAIProvider, AnthropicProvider, GoogleGeminiProvider, MultiProviderCompanionAgent } from '@stdiobus/mcp-agentic';

// 1. Create providers with credentials from environment variables
const registry = new ProviderRegistry();

registry.register(new OpenAIProvider({
  credentials: { apiKey: process.env.OPENAI_API_KEY! },
  models: ['gpt-4o', 'gpt-4o-mini'],
}));

registry.register(new AnthropicProvider({
  credentials: { apiKey: process.env.ANTHROPIC_API_KEY! },
  models: ['claude-sonnet-4-20250514'],
}));

registry.register(new GoogleGeminiProvider({
  credentials: { apiKey: process.env.GOOGLE_AI_API_KEY! },
  models: ['gemini-2.0-flash'],
}));

// 2. Create a multi-provider agent
const agent = new MultiProviderCompanionAgent({
  id: 'multi-ai',
  defaultProviderId: 'openai',
  registry,
  systemPrompt: 'You are a helpful assistant.',
});

// 3. Register and start
const server = new McpAgenticServer({ defaultAgentId: 'multi-ai' })
  .register(agent);

await server.start();

CLI Reference Server

The published binary (npx @stdiobus/mcp-agentic) starts a server with no agents registered. It is useful for:

  • Verifying MCP connectivity (bridge_health)
  • Inspecting the tool schema (agents_discover returns an empty list)
  • Confirming the transport layer works end-to-end

It cannot delegate worktasks_delegate, sessions_create, and sessions_prompt will fail because there are no agents to handle requests. For production use, create a custom entry point with server.register() calls as shown in Quick Start above.

The mcp.json shipped with this package references the CLI binary and is provided as a template. Copy and adapt it to point at your own server script.

Architecture

%%{init: {'theme':'dark', 'themeVariables':{'edgeLabelBackground':'#1a1a2e','lineColor':'#4a90e2','textColor':'#ddd'}}}%%
graph LR
    C[MCP Client] -->|MCP tools| S[McpAgenticServer] --> IPE[InProcessExecutor]
    IPE -->|AgentHandler| MCA[MultiProviderCompanionAgent]

    subgraph FAC ["Factory API (recommended)"]
        DP[defineProvider] --> OF[openAI]
        DP --> AF[anthropic]
        DP --> GF[gemini]
        DP -->|custom| CP["yourProvider()"]
        CMPA[createMultiProviderAgent] -->|creates| PR
        CMPA -->|creates| MCA
    end

    MCA --> PR[ProviderRegistry]
    PR --> OP[OpenAIProvider] --> OSDK[openai]
    PR --> AP[AnthropicProvider] --> ASDK["@anthropic-ai/sdk"]
    PR --> GP[GoogleGeminiProvider] --> GSDK["@google/generative-ai"]
    PR --> CPI["Custom AIProvider"] --> CSDK["Any LLM endpoint"]
    OF -->|new| OP
    AF -->|new| AP
    GF -->|new| GP
    CP -->|new| CPI

    %% ── Styles ──
    classDef client fill:#1a1a2e,stroke:#f39c12,stroke-width:2px,color:#fff
    classDef kernel fill:#1a1a2e,stroke:#4a90e2,stroke-width:3px,color:#fff,font-weight:bold
    classDef worker fill:#16213e,stroke:#50c878,stroke-width:2px,color:#fff
    classDef agent fill:#0f3460,stroke:#9b59b6,stroke-width:1px,color:#ddd
    classDef proxy fill:#16213e,stroke:#e67e22,stroke-width:2px,color:#fff
    classDef external fill:#1a1a2e,stroke:#95a5a6,stroke-width:1px,color:#bbb,font-style:italic
    classDef factory fill:#1a1a2e,stroke:#2ecc71,stroke-width:2px,color:#fff
    classDef custom fill:#16213e,stroke:#1abc9c,stroke-width:2px,color:#fff,stroke-dasharray:5 5

    class C client
    class S,IPE kernel
    class MCA agent
    class PR proxy
    class OP,AP,GP worker
    class OSDK,ASDK,GSDK external
    class DP,OF,AF,GF,CMPA factory
    class CP,CPI custom
    class CSDK external

    style FAC fill:#1a1a2e,stroke:#2ecc71,stroke-width:2px,color:#ddd
Loading
Session lifecycle — create → prompt → close (in-process agent)
%%{init: {'theme':'dark', 'themeVariables':{'actorBkg':'#1a1a2e','actorBorder':'#4a90e2','actorTextColor':'#fff','signalColor':'#50c878','signalTextColor':'#ddd','noteBkgColor':'#16213e','noteTextColor':'#fff','noteBorderColor':'#e67e22','activationBkgColor':'#0f3460','activationBorderColor':'#9b59b6','sequenceNumberColor':'#f39c12'}}}%%
sequenceDiagram
    participant C as MCP Client
    participant S as McpAgenticServer
    participant E as InProcessExecutor
    participant A as AgentHandler

    C->>S: sessions_create({ agentId })
    S->>S: validateMetadataSize()
    S->>S: resolveExecutor(agentId)
    S->>E: createSession(agentId, metadata)
    E->>A: onSessionCreate(sessionId)
    E-->>S: SessionEntry { sessionId, agentId, status }
    S-->>C: { sessionId, agentId, status: "active" }

    C->>S: sessions_prompt({ sessionId, prompt })
    S->>S: validatePromptSize()
    S->>S: resolveExecutorForSession(sessionId)
    S->>E: prompt(sessionId, input)
    E->>A: prompt(sessionId, input, opts)
    A-->>E: AgentResult { text, stopReason }
    E-->>S: AgentResult
    S-->>C: { text, stopReason }

    C->>S: sessions_close({ sessionId })
    S->>S: resolveExecutorForSession(sessionId)
    S->>E: closeSession(sessionId)
    E->>A: onSessionClose(sessionId)
    E-->>S: void
    S-->>C: { closed: true }
Loading
sessions_prompt with runtimeParams — parameter merge and provider delegation
%%{init: {'theme':'dark', 'themeVariables':{'actorBkg':'#1a1a2e','actorBorder':'#4a90e2','actorTextColor':'#fff','signalColor':'#50c878','signalTextColor':'#ddd','noteBkgColor':'#16213e','noteTextColor':'#fff','noteBorderColor':'#e67e22','activationBkgColor':'#0f3460','activationBorderColor':'#9b59b6','sequenceNumberColor':'#f39c12'}}}%%
sequenceDiagram
    participant Client as MCP Client
    participant Server as McpAgenticServer
    participant Executor as InProcessExecutor
    participant Agent as MultiProviderCompanionAgent
    participant Registry as ProviderRegistry
    participant Provider as AIProvider

    Client->>Server: sessions_prompt({ sessionId, prompt, runtimeParams })
    Server->>Server: validatePromptSize + withBackpressure
    Server->>Server: resolveExecutorForSession(sessionId)
    Note over Server: If runtimeParams present, pass to<br/>agent.setPromptRuntimeParams()
    Server->>Executor: prompt(sessionId, input, opts)
    Executor->>Agent: prompt(sessionId, input, opts)
    Agent->>Agent: merge(configDefaults, sessionParams, promptParams)
    Agent->>Registry: get(resolvedProviderId)
    Registry-->>Agent: provider instance
    Agent->>Provider: complete(messages, mergedParams, signal)
    Provider-->>Agent: AIProviderResult
    Agent->>Agent: append to conversation history
    Agent-->>Executor: AgentResult
    Executor-->>Server: AgentResult
    Server-->>Client: MCP response
Loading
sessions_create with provider selection — binding a session to a specific AI provider
%%{init: {'theme':'dark', 'themeVariables':{'actorBkg':'#1a1a2e','actorBorder':'#4a90e2','actorTextColor':'#fff','signalColor':'#50c878','signalTextColor':'#ddd','noteBkgColor':'#16213e','noteTextColor':'#fff','noteBorderColor':'#e67e22','activationBkgColor':'#0f3460','activationBorderColor':'#9b59b6','sequenceNumberColor':'#f39c12'}}}%%
sequenceDiagram
    participant Client as MCP Client
    participant Server as McpAgenticServer
    participant Executor as InProcessExecutor
    participant Agent as MultiProviderCompanionAgent

    Client->>Server: sessions_create({ agentId, metadata: {<br/>provider: "anthropic",<br/>runtimeParams: { model: "claude-sonnet-4-20250514" } } })
    Server->>Executor: createSession(agentId, metadata)
    Executor->>Agent: onSessionCreate(sessionId, metadata)
    Agent->>Agent: extract provider + runtimeParams from metadata
    Agent->>Agent: validate provider exists in registry
    Agent->>Agent: store SessionState with providerId + sessionParams
    Agent-->>Executor: void
    Executor-->>Server: SessionEntry
    Server-->>Client: { sessionId, agentId, status }
Loading
One-shot delegation — tasks_delegate flow
%%{init: {'theme':'dark', 'themeVariables':{'actorBkg':'#1a1a2e','actorBorder':'#4a90e2','actorTextColor':'#fff','signalColor':'#50c878','signalTextColor':'#ddd','noteBkgColor':'#16213e','noteTextColor':'#fff','noteBorderColor':'#e67e22','activationBkgColor':'#0f3460','activationBorderColor':'#9b59b6','sequenceNumberColor':'#f39c12'}}}%%
sequenceDiagram
    participant C as MCP Client
    participant S as McpAgenticServer
    participant E as AgentExecutor
    participant A as Agent

    C->>S: tasks_delegate({ agentId, prompt })
    S->>S: validatePromptSize()
    S->>S: validateMetadataSize()
    S->>S: resolveExecutor(agentId)
    S->>E: createSession(agentId)
    E-->>S: SessionEntry { sessionId }
    S->>E: prompt(sessionId, input)
    E->>A: prompt(sessionId, input)
    A-->>E: AgentResult { text, stopReason }
    E-->>S: AgentResult
    S->>E: closeSession(sessionId, "task-complete")
    E-->>S: void
    S-->>C: { success: true, text, stopReason }
Loading
Worker path — external ACP process via StdioBus
%%{init: {'theme':'dark', 'themeVariables':{'actorBkg':'#1a1a2e','actorBorder':'#4a90e2','actorTextColor':'#fff','signalColor':'#50c878','signalTextColor':'#ddd','noteBkgColor':'#16213e','noteTextColor':'#fff','noteBorderColor':'#e67e22','activationBkgColor':'#0f3460','activationBorderColor':'#9b59b6','sequenceNumberColor':'#f39c12'}}}%%
sequenceDiagram
    participant C as MCP Client
    participant S as McpAgenticServer
    participant W as WorkerExecutor
    participant B as StdioBus
    participant P as ACP Worker Process

    C->>S: sessions_prompt({ sessionId, prompt })
    S->>S: resolveExecutorForSession(sessionId)
    S->>W: prompt(sessionId, input)
    W->>B: bus.request("session/prompt", { sessionId, input })
    B->>P: JSON-RPC via stdin
    P-->>B: JSON-RPC response via stdout
    B-->>W: { text, stopReason }
    W->>W: validate response
    W-->>S: AgentResult
    S-->>C: { text, stopReason }
Loading
Executor resolution — in-process priority and caching
%%{init: {'theme':'dark', 'themeVariables':{'actorBkg':'#1a1a2e','actorBorder':'#4a90e2','actorTextColor':'#fff','signalColor':'#50c878','signalTextColor':'#ddd','noteBkgColor':'#16213e','noteTextColor':'#fff','noteBorderColor':'#e67e22','activationBkgColor':'#0f3460','activationBorderColor':'#9b59b6','sequenceNumberColor':'#f39c12'}}}%%
sequenceDiagram
    participant S as McpAgenticServer
    participant Cache as agentExecutorCache
    participant IP as InProcessExecutor
    participant WE as WorkerExecutor

    S->>Cache: get(agentId)
    alt cache hit
        Cache-->>S: executor
    else cache miss
        S->>IP: discover()
        IP-->>S: AgentInfo[]
        alt agent found in-process
            S->>Cache: set(agentId, InProcessExecutor)
            S-->>S: return InProcessExecutor
        else not in-process
            S->>WE: discover()
            WE-->>S: AgentInfo[]
            alt agent found in workers
                S->>Cache: set(agentId, WorkerExecutor)
                S-->>S: return WorkerExecutor
            else not found anywhere
                S-->>S: return InProcessExecutor (will throw "Agent not found")
            end
        end
    end
Loading

MCP Tools

Tool Description Notes
bridge_health Check bridge readiness
agents_discover List available agents, optionally filter by capability Response includes enriched providers field with id, models, kind, capabilities, displayName, and description for each provider
sessions_create Create a new agent session Pass metadata.provider to select a provider; pass metadata.runtimeParams for session-level defaults
sessions_prompt Send a prompt to an existing session Accepts optional runtimeParams for per-prompt overrides (model, temperature, systemPrompt, etc.)
sessions_status Check session status
sessions_close Close a session
sessions_cancel Cancel an in-flight prompt
tasks_delegate One-shot delegation (create + prompt + close) Accepts optional runtimeParams for parameter overrides; pass metadata.provider to select a provider
Enriched agents_discover response example
{
  "agents": [{
    "id": "multi-ai",
    "capabilities": [],
    "status": "ready",
    "providers": [
      {
        "id": "openai",
        "models": ["gpt-4o"],
        "kind": "llm",
        "capabilities": { "streaming": true, "tools": true, "vision": true, "jsonMode": true },
        "displayName": "OpenAI",
        "description": "OpenAI GPT models via official openai npm SDK"
      },
      {
        "id": "anthropic",
        "models": ["claude-sonnet-4-20250514"],
        "kind": "llm",
        "capabilities": { "streaming": true, "tools": true, "vision": true, "jsonMode": false },
        "displayName": "Anthropic"
      }
    ]
  }]
}

Providers without kind default to "llm". Providers without capabilities omit the field entirely.

Configuration

McpAgenticServer accepts a McpAgenticServerConfig:

interface McpAgenticServerConfig {
  agents?: AgentHandler[];
  defaultAgentId?: string;
  maxConcurrentRequests?: number;  // default: 50
  maxPromptBytes?: number;         // default: 1048576 (1 MiB)
  maxMetadataBytes?: number;       // default: 65536 (64 KiB)
}

Worker registration

server.registerWorker({
  id: 'py-agent',
  command: 'python',
  args: ['agent.py'],
  env: { API_KEY: process.env.API_KEY },
  capabilities: ['data-analysis'],
});

Provider configuration

Factory options (recommended)

Each factory accepts flat, typed options validated by Zod at creation time:

Factory Option Type Required Description
openAI apiKey string yes OpenAI API key
models string[] yes Model identifiers (e.g. ['gpt-4o'])
defaults RuntimeParams no Default generation parameters
anthropic apiKey string yes Anthropic API key
models string[] yes Model identifiers (e.g. ['claude-sonnet-4-20250514'])
defaults RuntimeParams no Default generation parameters
gemini apiKey string yes Google AI API key
models string[] yes Model identifiers (e.g. ['gemini-2.0-flash'])
defaults RuntimeParams no Default generation parameters

Invalid options (empty apiKey, empty models array) throw a BridgeError with category CONFIG at creation time. The Zod schema is accessible via factory.schema for introspection and JSON Schema generation.

Low-level API (class-based)

Deprecated. Use the factory functions above instead.

Each provider class is constructed with a ProviderConfig:

interface ProviderConfig {
  /** Credential key-value pairs sourced from environment variables. */
  credentials: Record<string, string>;
  /** Model identifiers available for this provider. */
  models: string[];
  /** Default RuntimeParams applied when no override is specified. */
  defaults?: RuntimeParams;
}

Example:

import { OpenAIProvider, AnthropicProvider } from '@stdiobus/mcp-agentic';

// @deprecated — use openAI() and anthropic() factories instead
const openai = new OpenAIProvider({
  credentials: { apiKey: process.env.OPENAI_API_KEY! },
  models: ['gpt-4o', 'gpt-4o-mini'],
  defaults: { temperature: 0.7, maxTokens: 4096 },
});

const anthropic = new AnthropicProvider({
  credentials: { apiKey: process.env.ANTHROPIC_API_KEY! },
  models: ['claude-sonnet-4-20250514'],
  defaults: { temperature: 0.5 },
});

RuntimeParams

RuntimeParams controls AI generation behavior and can be specified at three levels with ascending priority:

ProviderConfig.defaults  <  session metadata.runtimeParams  <  prompt-level runtimeParams

Only defined fields override lower-priority values. undefined fields are ignored during merge. providerSpecific is shallow-merged across all layers.

interface RuntimeParams {
  model?: string;              // Model identifier
  temperature?: number;        // Sampling temperature (0–2)
  maxTokens?: number;          // Maximum tokens to generate
  topP?: number;               // Nucleus sampling (0–1)
  topK?: number;               // Top-K sampling
  stopSequences?: string[];    // Stop sequences
  systemPrompt?: string;       // System prompt override
  providerSpecific?: Record<string, unknown>;  // Provider-native parameters
}

Public API

Exported from @stdiobus/mcp-agentic:

Core types:

  • McpAgenticServer — main server class
  • McpAgenticServerConfig — server configuration type
  • AgentHandler / Agent — agent interface
  • AgentResult, AgentEvent, AgentChunk, AgentFinal, AgentError — result types
  • PromptOpts, StreamOpts — option types
  • WorkerConfig — worker configuration type

Provider Factory API:

  • defineProvider — factory contract function for creating providers with Zod validation and metadata
  • DefinedProvider, DefineProviderConfig — types for defineProvider
  • ProviderKind — provider type literal ('llm' | 'embedding' | 'reranker')
  • ProviderCapabilities — provider capabilities type (streaming, tools, vision, jsonMode)
  • openAI, OpenAIOptions — OpenAI factory + options type
  • anthropic, AnthropicOptions — Anthropic factory + options type
  • gemini, GeminiOptions — Gemini factory + options type
  • createMultiProviderAgent, CreateMultiProviderAgentConfig — multi-provider agent helper + config type

Provider Layer:

  • AIProvider — unified provider interface (extended with optional kind and capabilities)
  • AIProviderResult — normalized provider response type
  • RuntimeParams — generation parameter type
  • ProviderConfig — provider configuration type
  • ChatMessage — standard message format type
  • ProviderRegistry — provider registry class
  • ProviderInfo — provider info type (id, models, kind, capabilities, displayName, description)
  • mergeRuntimeParams — three-level parameter merge utility
  • OpenAIProvider — OpenAI provider via native SDK (deprecated — use openAI() factory)
  • AnthropicProvider — Anthropic provider via native SDK (deprecated — use anthropic() factory)
  • GoogleGeminiProvider — Google Gemini provider via native SDK (deprecated — use gemini() factory)

Multi-Provider Agent:

  • MultiProviderCompanionAgent — agent supporting multiple AI providers
  • MultiProviderCompanionConfig — multi-provider agent configuration type

Development

npm install
npm run build        # esbuild + tsc declarations
npm run typecheck    # type checking only
npm run test:unit    # unit tests (Jest)
npm run test:e2e     # end-to-end tests
npm run test:all     # unit + e2e
npm run test:e2e:providers  # live provider e2e tests (requires API keys)

Peer dependencies for provider development

The provider SDKs are peer/optional dependencies. Install only the ones you need:

npm install openai                  # OpenAI provider
npm install @anthropic-ai/sdk       # Anthropic provider
npm install @google/generative-ai   # Google Gemini provider

Live provider e2e tests

The test:e2e:providers script runs end-to-end tests against real AI provider APIs. Tests are skipped automatically when the corresponding API key is not set:

Environment Variable Provider
OPENAI_API_KEY OpenAI
ANTHROPIC_API_KEY Anthropic
GOOGLE_AI_API_KEY Google Gemini

Steering Guides

What's Next

MCP Agentic is built to grow. The architecture has no hard limits on the number of tools, agents, or execution backends. Current v1.0 ships with 8 MCP tools and two backends (in-process + worker). Next up: agent registry management, session persistence, operator-level permission controls, and more.

Follow the repo for updates. The project uses semantic versioning.

License

Apache-2.0

About

Agent orchestration server that connects MCP clients to ACP-compatible agents through stdio Bus.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Contributors

Languages