MCP Chat Integration Plan¶
Objective¶
Create an MCP-based integration so natural-language messages from Discord, email-to-text, or other chat channels can create and manage accounting records such as customers and sales invoices.
Primary Use Case¶
Example operator workflow:
User sends a plain-language message:
Create customer Jane Doe, email jane@example.com, phone 780-555-0123Create invoice for Jane Doe: 12 DTF shirts at 15 each, Alberta tax
The chat agent (Hermes/Open Claw/Nemo Claw) calls MCP tools.
MCP server validates and normalizes input.
MCP server calls Inkforje Accounting API endpoints.
MCP server returns structured success/failure output back to chat.
sequenceDiagram
participant User as DTF Operator
participant Chat as Discord/Email-to-Text
participant Agent as Hermes/Open Claw/Nemo Claw
participant MCP as MCP Gateway
participant API as Inkforje API
participant DB as PostgreSQL
User->>Chat: "Create invoice for Jane Doe..."
Chat->>Agent: Inbound message
Agent->>MCP: create_invoice(tool args)
MCP->>API: OAuth2 token + POST /api/invoices/
API->>DB: Persist customer/invoice rows
DB-->>API: Commit OK
API-->>MCP: JSON response
MCP-->>Agent: Typed tool result
Agent-->>Chat: Confirmation / error details
Reference API Endpoints¶
From current accounting/api_urls.py:
POST /api/customers/GET /api/customers/POST /api/invoices/GET /api/invoices/POST /api/invoices/<uuid:uuid>/approve/POST /api/invoices/<uuid:uuid>/pay/POST /oauth/token/
These are sufficient to start with customer + invoice creation flows.
Recommended MCP Tool Contract (v1)¶
Expose narrow MCP tools instead of one generic action:
create_customercreate_invoicelist_customers(optional, for disambiguation)approve_invoice(optional)record_invoice_payment(optional)
Each tool should enforce strict JSON schema and return typed responses:
ok: true|falsemessage: stringdata: object|nullerrors: [..]
Input Normalization Rules¶
Apply deterministic normalization before API calls:
Resolve customer references by UUID, then by exact name/email match.
Parse money/quantity as decimals; reject ambiguous values.
Parse jurisdiction strings to known tax preset identifiers.
Require explicit currency when not inferable from defaults.
Reject incomplete invoice lines (missing qty/rate/description).
Security And Access Model¶
Use a dedicated OAuth2 confidential client for MCP.
Request only required scopes (minimum privilege).
Restrict ingress by source channel identity and shared secret.
Log request ID, actor/channel, normalized payload, API response status.
Redact PII in long-term logs where feasible.
Important¶
The referenced .env.production currently contains live-looking credentials
and secrets (database, storage, API keys, webhook secret, broker auth, etc.).
Rotate all exposed values before production rollout and move secret handling to
secure secret storage.
Do not copy raw secret values into documentation, prompts, or MCP tool outputs.
High-Level System Design¶
Suggested deployment components:
mcp-gatewayservice: receives MCP calls from chat agents and enforces tool schema.nlp-parsermodule: converts natural language to strict tool arguments.inkforje-api-clientmodule: OAuth token handling + typed API requests to Django backend.audit-logstore: immutable event logs for traceability and support.retry/dead-letterqueue: handles transient failures and idempotent retries.
flowchart LR
A[Discord / Email-to-Text] --> B[Chat Agent]
B --> C[MCP Gateway]
C --> D[NLP Parser + Validation]
D --> E[Inkforje API Client]
E --> F[/oauth/token/]
E --> G[/api/customers/]
E --> H[/api/invoices/]
G --> I[(PostgreSQL)]
H --> I
C --> J[(Audit Log)]
C --> K[(Retry / Dead-letter Queue)]
Implementation Phases¶
Phase 1: Foundation¶
Provision OAuth client for MCP.
Implement
create_customerMCP tool.Add integration tests against
/api/customers/.Add audit logging and correlation IDs.
Phase 2: Invoice Creation¶
Implement
create_invoiceMCP tool.Add line-item parsing and tax preset mapping.
Validate invoice totals and API response consistency.
Add retry/idempotency behavior.
Phase 3: Channel Connectors¶
Add Discord command/message adapter.
Add email-to-text webhook adapter.
Add sender allowlist and abuse/rate controls.
Add operator-friendly error responses.
Phase 4: Hardening¶
Add structured metrics and alerts.
Add dead-letter review workflow.
Add backup manual review queue for uncertain parses.
Run UAT with DTF business scenarios.
Testing Strategy¶
Required automated tests:
Tool schema validation tests.
API contract tests for customer/invoice flows.
Negative tests (unknown customer, malformed quantity/rate, missing fields).
Permission/scope tests.
Idempotency tests for duplicate inbound messages.
Operational Guardrails¶
To reduce risk in chat-driven accounting updates:
Confirm before posting financial transactions above a configured threshold.
Require explicit customer confirmation when name matching is ambiguous.
Store original inbound message alongside normalized command payload.
Provide a dry-run mode that returns the would-be API payload.
Sphinx Build¶
Build HTML documentation:
uv run --with sphinx sphinx-build -b html docs docs/_build/html
Generated entry point:
docs/_build/html/index.html
GitHub Actions: Cloudflare Pages Deployment¶
The repository now includes a workflow to build Sphinx docs and deploy to Cloudflare Pages:
.github/workflows/publish-docs-cloudflare-pages.yml
Required GitHub repository secrets:
CLOUDFLARE_API_TOKENCLOUDFLARE_ACCOUNT_IDCLOUDFLARE_PAGES_PROJECT_NAME
Implementation Status (Current Repo)¶
Initial MCP server implementation is now added:
accounting/mcp/server.py: stdio MCP server withinitialize,tools/list, andtools/callsupport.accounting/mcp/client.py: OAuth2 client-credentials API client.accounting/mcp/schemas.py: strict input validation serializers.accounting/management/commands/run_mcp_server.py: command entrypoint.
Current tools:
create_customer->POST /api/customers/create_invoice->POST /api/invoices/
Run MCP Server (stdio)¶
Set environment variables:
export MCP_API_BASE_URL="https://accounting.inkforje.com"
export MCP_OAUTH_CLIENT_ID="<oauth-client-id>"
export MCP_OAUTH_CLIENT_SECRET="<oauth-client-secret>"
Run:
uv run python manage.py run_mcp_server