Content
<h1 align="center">MCP Agentic — Multi-Agent Orchestration Server</h1>
<p align="center">
Agent orchestration server that connects MCP clients to ACP-compatible agents through <a href="https://stdiobus.com">stdio Bus</a>.
</p>
<p align="center">
<a href="https://www.npmjs.com/package/@stdiobus/mcp-agentic"><img src="https://img.shields.io/npm/v/@stdiobus/mcp-agentic?style=for-the-badge&logo=npm" alt="npm"></a>
<a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/protocol-MCP-purple?style=for-the-badge&logo=jsonwebtokens" alt="MCP"></a>
<a href="https://agentclientprotocol.com"><img src="https://img.shields.io/badge/protocol-ACP-purple?style=for-the-badge&logo=jsonwebtokens" alt="ACP"></a>
<a href="https://github.com/stdiobus"><img src="https://img.shields.io/badge/ecosystem-stdio%20Bus-ff4500?style=for-the-badge" alt="stdioBus"></a>
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen?style=for-the-badge&logo=nodedotjs" alt="Node"></a>
<a href="https://esbuild.github.io"><img src="https://img.shields.io/badge/build-esbuild-yellow?style=for-the-badge&logo=esbuild" alt="Build"></a>
<a href="https://github.com/stdiobus/mcp-agentic"><img src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-lightgrey?style=for-the-badge&logo=nodedotjs" alt="Platform"></a>
<a href="https://github.com/stdiobus/mcp-agentic/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue?style=for-the-badge&logo=opensourceinitiative" alt="License"></a>
<a href="https://www.typescriptlang.org"><img src="https://img.shields.io/badge/typescript-strict-blue?style=for-the-badge&logo=typescript" alt="TypeScript"></a>
<a href="https://github.com/stdiobus/mcp-agentic"><img src="https://img.shields.io/badge/tests-780%20passing-brightgreen?style=for-the-badge&logo=jest" alt="Tests"></a>
<a href="https://github.com/stdiobus/mcp-agentic"><img src="https://img.shields.io/badge/e2e-86%20passing-brightgreen?style=for-the-badge&logo=playwright" alt="E2E"></a>
</p>
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 providers** — `defineProvider()` contract for third-party and private LLM integrations with discoverable metadata
- **Enriched discovery** — `agents_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 errors** — `BridgeError` categories with retryability info
## Basic Quick Start
Create a custom entry point that registers your agents before starting the server:
```bash
npm install @stdiobus/mcp-agentic
```
```typescript
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:
```bash
npm install @stdiobus/mcp-agentic
npm install openai @anthropic-ai/sdk @google/generative-ai
```
```typescript
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:
```jsonc
// 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:
```typescript
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:
```typescript
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.
<details>
<summary>Advanced: Low-Level Class-Based API (deprecated)</summary>
> **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()`.
```typescript
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();
```
</details>
## 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 work** — `tasks_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
```mermaid
%%{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
```
<details>
<summary>Session lifecycle — create → prompt → close (in-process agent)</summary>
```mermaid
%%{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 }
```
</details>
<details>
<summary>sessions_prompt with runtimeParams — parameter merge and provider delegation</summary>
```mermaid
%%{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
```
</details>
<details>
<summary>sessions_create with provider selection — binding a session to a specific AI provider</summary>
```mermaid
%%{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 }
```
</details>
<details>
<summary>One-shot delegation — tasks_delegate flow</summary>
```mermaid
%%{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 }
```
</details>
<details>
<summary>Worker path — external ACP process via StdioBus</summary>
```mermaid
%%{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 }
```
</details>
<details>
<summary>Executor resolution — in-process priority and caching</summary>
```mermaid
%%{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
```
</details>
## 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 |
<details>
<summary>Enriched agents_discover response example</summary>
```json
{
"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.
</details>
## Configuration
`McpAgenticServer` accepts a `McpAgenticServerConfig`:
```typescript
interface McpAgenticServerConfig {
agents?: AgentHandler[];
defaultAgentId?: string;
maxConcurrentRequests?: number; // default: 50
maxPromptBytes?: number; // default: 1048576 (1 MiB)
maxMetadataBytes?: number; // default: 65536 (64 KiB)
}
```
### Worker registration
```typescript
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`:
```typescript
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:
```typescript
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.
```typescript
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
```bash
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:
```bash
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
- [Activation and Scope](steering/activation-and-scope.md)
- [Discovery and Routing](steering/discovery-and-routing.md)
- [Delegation and Session Lifecycle](steering/delegation-and-session-lifecycle.md)
- [Failure Handling](steering/failure-handling.md)
- [Configuration](steering/configuration.md)
## 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
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
servers
Model Context Protocol Servers
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.