System Overview — Agent → MCP → ERP Flow
One universal MCP server with pluggable adapter backends. Agents never know which ERP they talk to.
Scroll to zoom • Drag to pan
flowchart LR
subgraph U[" Users "]
direction TB
U1["Employee / Accountant / CEO"]
end
subgraph O[" AI Orchestrator "]
direction TB
ORC["LLM Router\nHaiku • Sonnet • Opus"]
end
subgraph A[" Agent Layer "]
direction TB
A1["Finance"]
A2["HR"]
A3["Supply"]
A4["Sales"]
A5["Compliance"]
A6["Governance Hub"]
end
subgraph M[" Universal MCP Server \n Streamable HTTP + OAuth 2.1 "]
direction TB
REG["Tool Registry\n~25-30 curated tools"]
WELL["/.well-known/mcp.json"]
end
subgraph AD[" Adapter Factory "]
direction TB
AD1["Twendee"]
AD2["MISA"]
AD3["SAP"]
AD4["Odoo"]
AD5["Google"]
AD6["Microsoft"]
end
subgraph E[" ERP / Digital Office Core "]
direction TB
E1[("PostgreSQL")]
E2[("MISA Amis")]
E3[("SAP S/4")]
E4[("Odoo")]
E5[("Workspace")]
E6[("MS 365")]
end
U1 --> ORC
ORC --> A
A6 -.->|monitor| A1 & A2 & A3 & A4 & A5
A -->|MCP Protocol| M
REG --> AD
AD1 --> E1
AD2 --> E2
AD3 --> E3
AD4 --> E4
AD5 --> E5
AD6 --> E6
style U fill:#1e1b4b,stroke:#6366f1,color:#c7d2fe
style O fill:#1c1917,stroke:#a16207,color:#fde68a
style A fill:#052e16,stroke:#16a34a,color:#bbf7d0
style M fill:#2e1065,stroke:#9333ea,color:#e9d5ff
style AD fill:#0c1a3d,stroke:#2563eb,color:#bfdbfe
style E fill:#1a1a1a,stroke:#525252,color:#d4d4d4
Domain Adapter Interfaces — Class Hierarchy
Optional domains via ? — not every ERP supports every domain. MCP only advertises implemented tools.
Scroll to zoom • Drag to pan
classDiagram
class IERPAdapter {
<<interface>>
+hr? IHRAdapter
+crm? ICRMAdapter
+finance? IFinanceAdapter
+supplyChain? ISupplyChainAdapter
+productivity? IProductivityAdapter
+authenticate() void
+healthCheck() HealthStatus
+getSupportedDomains() string[]
}
class IHRAdapter {
<<interface>>
+getEmployee(id)
+searchEmployees(query)
+createLeaveRequest(data)
+getAttendance(empId, range)
+getContracts(empId)
+getPayrollSummary(empId, month)
}
class ICRMAdapter {
<<interface>>
+getDeal(id)
+searchDeals(query)
+createDeal(data)
+updateDealStage(id, stage)
+getLeads(filter)
}
class IFinanceAdapter {
<<interface>>
+getVoucher(id)
+createVoucher(data)
+getFinancialReport(type, range)
}
class IProductivityAdapter {
<<interface>>
+getEmails(filter)
+sendEmail(data)
+getCalendarEvents(range)
+getDocuments(filter)
}
class BaseAdapter {
<<abstract>>
#httpClient
#rateLimiter
#cache
+authenticate()
#refreshToken()
#withRetry(fn)
#withCache(key, fn, ttl)
}
class TwendeeAdapter { +hr +crm +finance }
class MISAAdapter { +finance +hr }
class SAPAdapter { +hr +crm +finance +supplyChain }
class GoogleAdapter { +productivity }
IERPAdapter <|.. BaseAdapter
BaseAdapter <|-- TwendeeAdapter
BaseAdapter <|-- MISAAdapter
BaseAdapter <|-- SAPAdapter
BaseAdapter <|-- GoogleAdapter
IERPAdapter --> IHRAdapter
IERPAdapter --> ICRMAdapter
IERPAdapter --> IFinanceAdapter
IERPAdapter --> IProductivityAdapter
New ERP Onboarding — Developer Experience
Scaffold → Fill methods → Test → Deploy → Agents auto-discover. Zero agent code changes.
Scroll to zoom • Drag to pan
sequenceDiagram
actor Dev as Developer
participant CLI as Scaffold CLI
participant FS as File System
participant Tests as Contract Tests
participant MCP as MCP Server
participant Agent as AI Agent
Dev->>CLI: npx erp-mcp scaffold --erp misa --domains hr,finance
CLI->>FS: Generate adapter stubs
Note over FS: adapters/misa/
misa-adapter.ts
misa-hr-adapter.ts
misa-finance-adapter.ts
misa-auth.ts • misa-client.ts
__tests__/
Dev->>FS: Fill in API mapping (~8-10 methods/domain)
Dev->>Tests: Run contract tests
Tests-->>Dev: Canonical output shapes verified
Dev->>MCP: Deploy (restart instance)
MCP->>MCP: AdapterFactory.getAdapter("misa")
MCP->>MCP: registerTools(supportedDomains)
MCP-->>MCP: Emit tools/list_changed
Agent->>MCP: tools/list
MCP-->>Agent: hr.getEmployee, finance.getVoucher...
Note over Agent: Zero changes to
agent prompts!
Agent->>MCP: hr.getEmployee({ id: "123" })
MCP-->>Agent: { id, name, email, dept, ... }
Implementation Timeline (18-21 days)
Sequential phases 01-04, then MISA + Productivity adapters in parallel.
Scroll to zoom • Drag to pan
gantt
dateFormat YYYY-MM-DD
axisFormat %b %d
section Foundation
P01 Canonical Types and Interfaces :p1, 2026-04-14, 3d
P02 TwendeeERPAdapter Reference :p2, after p1, 4d
section MCP Enhancement
P03 MCP Server Streamable HTTP :p3, after p2, 3d
P04 Scaffold CLI :p4, after p3, 2d
section External Adapters
P05 MISA Adapter Validation :p5, after p4, 4d
P06 Google and Microsoft Adapters :p6, after p4, 4d
Capability Discovery — Dynamic Tool Registration
MCP server only advertises tools for domains the active adapter implements.
Scroll to zoom • Drag to pan
flowchart LR
subgraph C["Instance Config"]
CFG["erpType: misa\ndomains: hr, finance"]
end
subgraph F["AdapterFactory"]
AF["getAdapter(config)"]
end
subgraph AD["MISAAdapter"]
direction TB
HR["hr: MISAHRAdapter"]
FIN["finance: MISAFinanceAdapter"]
CRM["crm: null"]
SUP["supplyChain: null"]
end
subgraph R["MCP Tool Registry"]
direction TB
R_HR["hr.getEmployee\nhr.searchEmployees\nhr.createLeave\nhr.getAttendance"]
R_FIN["finance.getVoucher\nfinance.createVoucher\nfinance.getReport"]
R_SKIP["crm SKIPPED\nsupply SKIPPED"]
end
CFG --> AF
AF --> HR
AF --> FIN
AF --> CRM
HR --> R_HR
FIN --> R_FIN
CRM -.->|not implemented| R_SKIP
style HR fill:#052e16,stroke:#16a34a,color:#bbf7d0
style FIN fill:#052e16,stroke:#16a34a,color:#bbf7d0
style CRM fill:#1c1917,stroke:#525252,color:#a8a29e
style SUP fill:#1c1917,stroke:#525252,color:#a8a29e
style R_HR fill:#052e16,stroke:#16a34a,color:#bbf7d0
style R_FIN fill:#052e16,stroke:#16a34a,color:#bbf7d0
style R_SKIP fill:#2a1215,stroke:#991b1b,color:#fca5a5
Research Targets — MCP Focus
Prioritized research with assignees, deadlines, and status tracking for each implementation phase.
Canonical Model Extraction
- Assignee
- Backend Lead
- Deadline
- 2026-04-13 (before Phase 01)
- Blocker
- Blocks all phases
- Output
- ~30 canonical types + field mapping table
- Which of 121 Prisma models are business entities vs join tables?
- Minimal canonical type set agents need (~30 types)
- Field mapping: Twendee → SAP → MISA → Odoo
- Zod schema: auto-derive from Prisma or hand-write?
MCP SDK + Streamable HTTP
- Assignee
- Platform Engineer
- Deadline
- 2026-04-20 (before Phase 03)
- Blocker
- Blocks MCP server enhancement
- Output
- NestJS + MCP SDK integration guide
- @modelcontextprotocol/sdk with NestJS integration
- OAuth 2.1 PKCE flow for production MCP auth
- /.well-known/mcp.json endpoint implementation
- tools/list_changed notification pattern
MCP Client-Side Patterns
- Assignee
- AI/Agent Engineer
- Deadline
- 2026-04-20 (before Phase 03)
- Blocker
- Blocks agent ↔ MCP integration
- Output
- Client integration pattern doc
- How LLM orchestrator discovers + calls MCP tools
- Tool filtering per agent role
- Error handling: MCP error → LLM response
- Token overhead of 25-30 tool definitions
MISA API Capabilities
- Assignee
- Integration Engineer
- Deadline
- 2026-04-28 (before Phase 05)
- Blocker
- Blocks MISA adapter
- Output
- API capability matrix + auth flow
- REST endpoints MISA Amis exposes
- Auth method: API key, OAuth, session?
- Rate limits, pagination patterns
- Vietnamese fields (CMND/CCCD, MST) mapping
Google & Microsoft Graph APIs
- Assignee
- Integration Engineer
- Deadline
- 2026-04-28 (before Phase 06)
- Blocker
- Blocks productivity adapters
- Output
- API mapping + interface split recommendation
- IProductivityAdapter: separate or sub-domains?
- OAuth scopes for email, calendar, docs
- Existing MCP servers to reuse?
- Batch requests + delta queries
SAP OData Curation
- Assignee
- TBD
- Deadline
- V2 (after MISA validation)
- Blocker
- No — deferred
- Output
- SAP endpoint curation guide
- 5000+ endpoints → ~25-30 curated tools
- BAPI vs OData: when to use which
- SAP BTP OAuth 2.0 specifics
- Existing SAP MCP integrations