Custom CRM & MCP

MCP Server Permissions Over Postgres for Business CRMs: Beyond Raw SQL

Dark architectural illustration of a structured MCP permission gateway shielding a cylindrical Postgres database vault, passing scoped reads while holding write proposals at a human approval lock

The fastest way to break trust in an AI-enabled CRM is to wire a language model to a generic Postgres MCP connector backed by raw SQL execution and one shared connection string. In a laptop demo, asking an assistant in plain language to look up a client, summarize quotes, and update a deal stage feels effortless. In live operations, where sales reps, account managers, dispatch coordinators, and finance staff share one multi-branch database, raw SQL over a shared credential collapses every permission boundary your application enforces.

Illustrative synthetic scenario: the architectural patterns and worked examples in this guide describe engineering choices for a custom AI CRM with MCP and do not depict customer records, a specific deployment, or a legal compliance guarantee.

Why Raw SQL MCP Connectors Fail Inside a Business CRM

Developer-focused Postgres MCP servers help engineers inspect schemas or explore local test data. Lifting that pattern into a multi-user operational CRM introduces three structural hazards that system prompts cannot prevent.

Raw SQL MCP Connector

Shared backend credentials and open queries. The model writes arbitrary SQL across tables, bypasses domain service invariants, and leaves a single technical user in Postgres logs.

Role-Scoped Domain MCP

Typed service tools, session identity, and RLS. Every invocation binds the signed-in employee inside a scoped transaction while sensitive mutations pause at an audited human gate.

  • Bypassing domain invariants: Moving an opportunity to delivery or pausing a branch agreement is never a single-column update. It checks prerequisites, creates onboarding tasks, and records timeline history. Raw SQL skips service rules and corrupts state silently.
  • Prompt injection from untrusted text: Every day, a CRM ingests external text: WhatsApp threads, forwarded emails, web forms, and vendor PDFs. With an unrestricted query tool, misleading instructions hidden inside a lead note can steer the model into joining unrelated tables or reading another client's data.
  • Erasing per-user accountability: When AI lookups share one backend credential, Postgres logs show only a technical service user rather than which employee initiated the action and under what role.

Structuring MCP Tool Boundaries: Read, Draft, and Propose-Write

A production MCP server acts as a typed gateway above your domain services rather than a pass-through to tables. Teams expose a compact catalog of schema-validated tools divided into three execution modes.

1

Context-Bounded Read Tools and Untrusted Content Wrapping

Read tools project only the fields needed for the task. An account-summary tool accepts a verified account ID and pagination limits, returning branch contacts, active agreements, and recent timeline events while omitting secrets, internal margins, or restricted billing notes. Every free-text field typed by an external visitor or customer, including messages, titles, and form answers, is wrapped as untrusted visitor content so the model treats it strictly as data rather than instructions.

2

Stateless Draft and Preparation Tools

Most daily leverage in an AI-native CRM needs zero immediate writes. Drafting tools assemble structured quotes from catalog rules, prepare handoff briefs, or compose source-cited replies as editable drafts without altering canonical rows.

3

Propose-Write Tools and Destructive Action Gates

Whenever a workflow changes commercial state, such as amending contract scope, requesting a credit, archiving a record, or sending an external message, the tool stages a proposal instead of mutating rows silently. Across multi-step workflow agents, state-changing tools write to an approval queue or carry destructive annotations requiring human confirmation before sending external messages, moving financial state, or deleting records.

Binding Identity From Session Auth, Never Model Arguments

A frequent mistake in internal MCP servers is placing user ID, role, or organization ID inside JSON arguments generated by the model. A language model is a text generator, never a security principal. Tool schemas must omit caller identity parameters altogether. Instead, the MCP server authenticates the signed-in user's session or personal key, resolves the verified actor ID, role, and tenant scope on the server, and passes that immutable principal into the CRM service.

Access keys follow the same rule: restricted project keys are blocked from broad lookups at the service boundary, while owner-issued full-access keys act strictly as their creator under identical role checks. User management, API key creation, and permission grants stay outside MCP completely so no agent credential can mint keys or escalate privileges.

Defense in Depth With Postgres Row-Level Security

Service-layer checks come first, and pairing them with Postgres Row-Level Security (RLS) ensures that even if a future query misses a filter, the database enforces tenant, branch, and role boundaries.

Server session auth Domain service check Transaction-local context Postgres RLS filtering

Transaction-Local Context Over Connection Pools

Because web backends share pooled Postgres connections, session-level variables risk leaking identity across requests. Each MCP tool runs inside a short transaction under a non-superuser role without RLS bypass rights and sets transaction-local values for the active actor ID and role. When the transaction finishes, Postgres clears that context automatically.

Combining Row Policies With Column Projections

RLS policies filter visible rows: account executives see assigned clients, while dispatch sees scheduled visits. Repository queries pair row policies with explicit column projections so a technician checking site entry notes never sees credit limits or collection history.

Synthetic Walkthrough: Handling a Multi-Branch Request Safely

Consider an illustrative workflow: an account manager opens the CRM assistant after receiving a forwarded email chain from a multi-branch distributor asking to expand weekly service in Haifa, close an unused site in Ashdod, and review a disputed visit charge. Hidden in the quoted footer is stray text mentioning an unrelated company and asking to inspect its account.

  1. Session-bound transaction setup: The MCP server verifies the account manager's session, opens a scoped Postgres transaction, and binds her user ID and assigned portfolio locally.
  2. Scoped reads and untrusted isolation: Read tools fetch only the active distributor while wrapping email bodies as untrusted content. Any attempt to inspect the unrelated company fails both service checks and Postgres RLS.
  3. Evidence-linked proposal staging: Rather than editing agreement or invoice tables directly, a proposal tool stages one review card linking the Haifa expansion, Ashdod closure checklist, and finance task to the exact email and visit IDs.
  4. Human sign-off and audit trail: The account manager verifies the cited sources and approves routing while every tool call and approval writes to an immutable audit table.
Architecture checkpoint: what happens when the assistant is asked to issue a credit or close an active branch mid-conversation?
Financially material updates and branch closures never execute silently inside the model loop.

The MCP tool never alters balances or deactivates a live site directly. It stages a cited proposal record and triggers an explicit confirmation gate so the authorized manager or finance lead approves the change under their own audited session.

Audit Logging and Engineering Checklist Before Production

When scoping custom AI agent engineering over operational databases, verify five controls before connecting MCP to production Postgres:

  • Dedicated non-superuser Postgres role: Force RLS on every business table under a least-privilege role without bypass rights.
  • Zero raw SQL tools in operations: Wrap validated domain services with explicit field projections and bounded row limits.
  • Server-bound principals and off-limits admin tools: Resolve identity strictly on the server and keep users, keys, and grants out of MCP.
  • Untrusted content wrappers everywhere: Isolate every visitor-authored or client-authored string, including notes, messages, and titles.
  • Append-only audit logs: Record the authenticated person, key scope, tool name, target entity IDs, and approval outcome.

MCP makes AI dependable inside a custom CRM because of the boundaries it enforces, not the shortcuts it allows.

Combining typed domain tools, session-bound identity, transaction-local Postgres RLS, and human confirmation gates turns your relational core into a safe, auditable foundation for daily operations.

What does a custom AI CRM with MCP look like?

See how conversations, quotes and operational tools unite around one customer record with human approval.

You can also start with a short description of the workflow or product you want to build.

Ideas, delivered to your inbox

Occasional practical guides and examples on AI and building products. No spam.

Unsubscribe anytime.

Ask DevShift