# Architecture Overview
A comprehensive look at the Dataverse MCP Toolbox architecture, component relationships, and design principles.
## System Architecture
```mermaid
graph TB
subgraph "User Space"
User[👤 Developer]
VSCode[VS Code Application]
end
subgraph "Extension Layer"
UI[Extension UI
Commands, TreeViews, Panels]
ServerMgr[Server Manager
Binary Lifecycle]
RpcClient[RPC Client
Named Pipe]
Storage[Storage Services
State & Secrets]
McpProvider[MCP Provider
Copilot Integration]
end
subgraph "Sidecar Layer"
direction LR
subgraph Core["Core Server (.NET)"]
direction TB
CoreRpc[RPC Service
Request Handler]
ConnService[Connection Services]
AuthService[Auth Services]
ToolService[Tool Execution]
PluginService[Plugin Manager]
CoreState[State Manager]
end
subgraph Bridge["MCP Bridge (.NET)"]
direction TB
StdioHandler[STDIO Handler
MCP Protocol]
PipeClient[Named Pipe Client]
Forwarder[Request Forwarder]
end
end
subgraph "External Services"
Copilot[GitHub Copilot]
Dataverse[(Microsoft Dataverse)]
NuGet[NuGet.org]
AAD[Azure AD]
end
User --> VSCode
VSCode --> UI
UI --> ServerMgr
UI --> RpcClient
UI --> Storage
UI --> McpProvider
ServerMgr -->|Spawns| Core
ServerMgr -->|Downloads| NuGet
RpcClient -->|Named Pipe| CoreRpc
McpProvider -->|Registers| Bridge
Copilot -->|STDIO/MCP| StdioHandler
StdioHandler --> Forwarder
Forwarder --> PipeClient
PipeClient -->|Named Pipe| CoreRpc
CoreRpc --> ConnService
CoreRpc --> ToolService
CoreRpc --> PluginService
ConnService --> AuthService
ToolService --> PluginService
ConnService -->|SDK| Dataverse
AuthService -->|MSAL| AAD
PluginService -->|Downloads| NuGet
style "Extension Layer" fill:#e1f5ff
style Core fill:#fff4e1
style Bridge fill:#ffe1f5
style "External Services" fill:#e1ffe1
```
## Design Principles
### 1. Separation of Concerns
Each component has a single, well-defined responsibility:
| Component | Responsibility | Does NOT Handle |
|-----------|----------------|-----------------|
| **Extension** | UI, lifecycle, storage | Dataverse operations, auth |
| **Core Server** | Business logic, Dataverse SDK | UI, MCP protocol |
| **MCP Bridge** | Protocol translation | Business logic, state |
### 2. Transport Agnostic Services
```mermaid
graph TB
subgraph "Service Layer - Transport Agnostic"
ConnService[Connection Service]
AuthService[Auth Service]
ToolService[Tool Service]
end
subgraph "Communication Layer - Pluggable"
NamedPipe[Named Pipe Transport]
TCP[TCP Transport
Future]
HTTP[HTTP Transport
Future]
end
RpcService[RPC Service Layer] --> ConnService
RpcService --> AuthService
RpcService --> ToolService
NamedPipe --> RpcService
TCP -.->|Future| RpcService
HTTP -.->|Future| RpcService
style "Service Layer - Transport Agnostic" fill:#e1ffe1
style "Communication Layer - Pluggable" fill:#ffe1e1
```
**Benefits:**
- Services can be tested without transport
- Transport can be swapped without changing business logic
- Services reusable in different contexts
### 3. Instance Isolation
```mermaid
graph TB
subgraph OS[Operating System]
subgraph Instance1[VS Code Window 1]
Ext1[Extension
Instance 1]
Core1[Core Server
PID 1234
Pipe: dvmcp-abc]
Bridge1[Bridge
PID 1235]
end
subgraph Instance2[VS Code Window 2]
Ext2[Extension
Instance 2]
Core2[Core Server
PID 5678
Pipe: dvmcp-xyz]
Bridge2[Bridge
PID 5679]
end
subgraph Instance3[VS Code Window 3]
Ext3[Extension
Instance 3]
Core3[Core Server
PID 9012
Pipe: dvmcp-qwe]
Bridge3[Bridge
PID 9013]
end
end
Dataverse[(Dataverse)]
Core1 --> Dataverse
Core2 --> Dataverse
Core3 --> Dataverse
style Instance1 fill:#e1f5ff
style Instance2 fill:#ffe1f5
style Instance3 fill:#fff4e1
```
**Isolation Mechanisms:**
- Unique named pipe per instance
- Separate process space
- Independent in-memory state
- No shared file locks
### 4. Defense in Depth
```mermaid
graph LR
Input[User Input] --> Validation1[Extension Validation]
Validation1 --> Validation2[Core Validation]
Validation2 --> Validation3[Plugin Validation]
Validation3 --> Sanitization[Input Sanitization]
Sanitization --> Execution[Safe Execution]
style Validation1 fill:#ffe1e1
style Validation2 fill:#ffe1e1
style Validation3 fill:#ffe1e1
```
**Security Layers:**
- Input validation at every boundary
- Token encryption in VS Code SecretStorage
- Plugin isolation via AppDomain
- Least privilege principle
## Component Communication Flow
### Extension → Core Server (Direct Operations)
```mermaid
sequenceDiagram
participant UI as Extension UI
participant RpcClient as RPC Client
participant Pipe as Named Pipe
participant Core as Core Server
participant Service as Service Layer
UI->>RpcClient: CreateConnection(url)
RpcClient->>RpcClient: Serialize to JSON-RPC
RpcClient->>Pipe: Write Request
Pipe->>Core: Named Pipe IPC
Core->>Core: Deserialize & Route
Core->>Service: CreateConnectionAsync()
Service->>Service: Authenticate & Test
Service->>Core: ConnectionResult
Core->>Core: Serialize Response
Core->>Pipe: Write Response
Pipe->>RpcClient: Read Response
RpcClient->>RpcClient: Deserialize
RpcClient->>UI: Result
```
### Copilot → Bridge → Core (Tool Execution)
```mermaid
sequenceDiagram
participant Copilot as GitHub Copilot
participant Bridge as MCP Bridge
participant Core as Core Server
participant Plugin as Plugin Tool
participant DV as Dataverse
Note over Copilot,Bridge: MCP Protocol (STDIO)
Copilot->>Bridge: tools/call (stdin)
Bridge->>Bridge: Parse MCP Request
Bridge->>Bridge: Translate to Core RPC
Note over Bridge,Core: Core RPC (Named Pipe)
Bridge->>Core: ExecuteTool(name, args)
Core->>Core: Validate & Route
Core->>Core: Get Active Connection
Core->>Plugin: ExecuteAsync(context)
Plugin->>DV: SDK Operation
DV->>Plugin: Result
Plugin->>Core: Tool Result
Core->>Bridge: RPC Response
Bridge->>Bridge: Translate to MCP
Bridge->>Copilot: MCP Result (stdout)
```
## Data Flow
### Authentication Flow
```mermaid
sequenceDiagram
participant User
participant Ext as Extension
participant Core as Core Server
participant Browser
participant AAD as Azure AD
participant Storage as Secret Storage
participant DV as Dataverse
User->>Ext: Create Connection
Ext->>Core: CreateConnection(url)
Core->>Browser: Open OAuth Flow
Browser->>AAD: Authenticate
User->>Browser: Enter Credentials
AAD->>Browser: Authorization Code
Browser->>Core: Redirect with Code
Core->>AAD: Exchange Code for Token
AAD->>Core: Access Token
Core->>Ext: Token (encrypted in transit)
Ext->>Storage: Store Token (encrypted)
Core->>DV: WhoAmI (test connection)
DV->>Core: User Info
Core->>Ext: Connection Success + User Info
Ext->>User: Connection Ready
```
### Plugin Installation Flow
```mermaid
sequenceDiagram
participant User
participant UI as Extension UI
participant Mgr as Plugin Manager (Ext)
participant NuGet as NuGet.org
participant FS as Filesystem
participant Core as Core Server
User->>UI: Install Plugin (packageId)
UI->>Mgr: InstallPlugin(packageId, version)
Mgr->>NuGet: Download Package
NuGet->>Mgr: .nupkg File
Mgr->>FS: Extract to Plugin Directory
FS->>Mgr: Extraction Complete
Mgr->>Core: ReloadPlugins()
Core->>FS: Scan Plugin Directory
Core->>Core: Load Assemblies
Core->>Core: Discover Tools
Core->>Core: Register in Tool Registry
Core->>Mgr: Plugin Loaded
Mgr->>UI: Installation Success
UI->>User: Plugin Available
```
## State Management Architecture
### State Distribution
```mermaid
graph TB
subgraph "Core Server - In-Memory (Volatile)"
ConnectionPool[Active ServiceClient Pool
Dictionary<string, IOrganizationService>]
ToolRegistry[Tool Registry
Dictionary<string, IMcpTool>]
ActiveConn[Active Connection ID
string?]
PluginCache[Loaded Plugin Assemblies
List<Assembly>]
end
subgraph "Extension - Persistent"
ConnMetadata[Connection Metadata
WorkspaceState
id, name, url]
Tokens[OAuth Tokens
SecretStorage
Encrypted]
Settings[User Settings
update channel, version]
end
subgraph "Filesystem - Persistent"
Binaries[Runtime Binaries
globalStorageUri/server/]
Plugins[Plugin Assemblies
globalStorageUri/plugins/]
end
Restart[Server Restart] -.->|Clears| ConnectionPool
Restart -.->|Clears| ToolRegistry
Restart -.->|Clears| ActiveConn
Restart -.->|Reloads from| Plugins
style "Core Server - In-Memory (Volatile)" fill:#ffe1e1
style "Extension - Persistent" fill:#e1f5ff
style "Filesystem - Persistent" fill:#fff4e1
```
### State Lifecycle
```mermaid
stateDiagram-v2
[*] --> ExtensionStart: VS Code Opens
ExtensionStart --> BinaryCheck: Extension Activates
BinaryCheck --> Download: Binaries Missing
BinaryCheck --> CoreStart: Binaries Present
Download --> CoreStart: Download Complete
CoreStart --> ServerRunning: Core Process Spawned
ServerRunning --> LoadPlugins: Initial Load
LoadPlugins --> Ready: Server Ready
Ready --> ProcessingRequest: Request Received
ProcessingRequest --> Ready: Request Complete
Ready --> ExtensionClose: VS Code Closes
ExtensionClose --> CleanupState: Shutdown Signal
CleanupState --> [*]: Process Terminated
note right of ServerRunning
In-Memory State:
- Empty connection pool
- Empty tool registry
- No active connection
end note
note right of Ready
State Populated:
- Connections created
- Plugins loaded
- Tools registered
end note
note right of CleanupState
State Destroyed:
- Connections disposed
- Assemblies unloaded
- Memory freed
end note
```
## Error Handling Strategy
### Error Propagation
```mermaid
graph TB
Error[Error Occurs] --> Layer{Which Layer?}
Layer -->|Dataverse SDK| DvError[DataverseException]
Layer -->|Plugin Code| PluginError[PluginException]
Layer -->|Validation| ValidationError[ValidationException]
Layer -->|Auth| AuthError[AuthenticationException]
DvError --> Wrap[Wrap in ToolCallResult]
PluginError --> Wrap
ValidationError --> Wrap
AuthError --> Wrap
Wrap --> RpcResponse[RPC Error Response]
RpcResponse --> Client{Client Type?}
Client -->|Extension| UIError[VS Code Error Message]
Client -->|Bridge/Copilot| McpError[MCP Error Response]
UIError --> User[User Sees Friendly Message]
McpError --> AI[AI Receives Structured Error]
style DvError fill:#ffe1e1
style PluginError fill:#ffe1e1
style ValidationError fill:#ffe1e1
style AuthError fill:#ffe1e1
```
### Error Response Structure
```mermaid
classDiagram
class ToolCallResult {
+bool Success
+object? Content
+ToolCallError? Error
+List~string~? IsError
}
class ToolCallError {
+string Code
+string Message
+string? Details
+Dictionary~string,object~? Data
}
class ErrorCodes {
<>
VALIDATION_ERROR
DATAVERSE_ERROR
PLUGIN_ERROR
NOT_FOUND
UNAUTHORIZED
TIMEOUT
}
ToolCallResult --> ToolCallError
ToolCallError --> ErrorCodes
```
## Platform-Specific Adaptations
### Named Pipe Implementation
```mermaid
graph TB
Decision{Operating
System?}
Decision -->|Windows| WinPipe[Named Pipe
\\.\pipe\dvmcp-{id}]
Decision -->|macOS/Linux| UnixSocket[Unix Domain Socket
/tmp/dvmcp-sockets/CoreFxPipe_dvmcp-{id}]
WinPipe --> WinAPI[Windows Named Pipe API
CreateNamedPipe]
UnixSocket --> PosixAPI[POSIX Socket API
Unix Domain Socket]
WinAPI --> Communicate[JSON-RPC Communication]
PosixAPI --> Communicate
Communicate --> LengthLimit{Path Length}
LengthLimit -->|Windows| NoLimit[No practical limit]
LengthLimit -->|Unix| Limit104[104 chars maximum]
Limit104 --> Shorten[Use short IDs + temp dirs]
style WinPipe fill:#e1f5ff
style UnixSocket fill:#ffe1f5
```
### Binary Selection
```mermaid
graph TB
Start[Extension Starts] --> Detect[Detect Platform & Arch]
Detect --> Platform{Platform?}
Platform -->|process.platform=darwin| Mac[macOS]
Platform -->|process.platform=win32| Windows[Windows]
Platform -->|process.platform=linux| Linux[Linux]
Mac --> MacArch{process.arch?}
MacArch -->|arm64| ARM[osx-arm64
Apple Silicon]
MacArch -->|x64| IntelMac[osx-x64
Intel Mac]
Windows --> Win64[win-x64
Windows 64-bit]
Linux --> Linux64[linux-x64
Linux 64-bit]
ARM --> ExtractBinary[Extract Binary from NuGet]
IntelMac --> ExtractBinary
Win64 --> ExtractBinary
Linux64 --> ExtractBinary
ExtractBinary --> Unix{Unix-like?}
Unix -->|Yes| Chmod[chmod +x
Make Executable]
Unix -->|No| Spawn[Spawn Process]
Chmod --> Spawn
style ARM fill:#e1ffe1
style IntelMac fill:#e1ffe1
style Win64 fill:#ffe1e1
style Linux64 fill:#fff4e1
```
## Scalability Considerations
### Multi-Instance Behavior
```mermaid
graph TB
subgraph Machine[Developer Machine]
subgraph Window1[VS Code Window 1]
E1[Extension 1]
C1[Core 1]
E1 -->|Pipe A| C1
end
subgraph Window2[VS Code Window 2]
E2[Extension 2]
C2[Core 2]
E2 -->|Pipe B| C2
end
subgraph Window3[VS Code Window 3]
E3[Extension 3]
C3[Core 3]
E3 -->|Pipe C| C3
end
end
AAD[Azure AD
Token Endpoint]
DV[(Dataverse)]
C1 -->|Independent Auth| AAD
C2 -->|Independent Auth| AAD
C3 -->|Independent Auth| AAD
C1 -->|Connection A| DV
C2 -->|Connection B| DV
C3 -->|Connection C| DV
style Window1 fill:#e1f5ff
style Window2 fill:#ffe1f5
style Window3 fill:#fff4e1
```
**No Central Coordination:**
- Each instance operates independently
- No shared memory or state
- No inter-instance communication
- No resource contention
## Next Steps
- **[Core Server](05-Core-Server.md)**: Detailed Core Server architecture
- **[MCP Bridge](06-MCP-Bridge.md)**: MCP Bridge implementation
- **[VS Code Extension](07-VS-Code-Extension.md)**: Extension architecture
- **[Communication Protocol](08-Communication.md)**: RPC protocol details