Skip to content

MCP — Database Server

Enforce Scopebound policies on agents using a Database MCP server (PostgreSQL, MySQL, or compatible).

Install

pip install scopebound

Role template

from scopebound import ScopeboundSDK
from scopebound.adapters.mcp_database import DatabaseMCPAdapter

sb = ScopeboundSDK(base_url="https://your-partner.api.scopebound.ai", api_key="sb-...")

role = DatabaseMCPAdapter.role_template(
    name="db-read-agent",
    allowed_tables=["invoices", "vendors", "transactions"],
    read_only=True,          # blocks execute and any DML entirely
    max_rows=1000,           # enforces DATA_LIMIT_EXCEEDED above this threshold
    approval_required=[]     # add "execute" here to require HITL on DDL/DML
)
sb.create_role(**role)

Read-only vs read-write

Set read_only=True for analytics agents and reporting pipelines. Only set read_only=False for agents that must write — and always pair with approval_required=["execute"].

Integration

from scopebound.adapters.mcp_database import DatabaseMCPAdapter

adapter = DatabaseMCPAdapter(sb, role_id="db-read-agent")

@server.pre_call
def enforce(tool_name: str, arguments: dict) -> None:
    adapter.enforce(tool_name, arguments)

Enforced tools

Tool Default policy Notes
list_tables Allow Returns only allowed_tables
query Allow Table must be in allowed_tables; rows capped at max_rows
execute Blocked Blocked entirely when read_only=True; requires approval when read_only=False

Deny codes

Code Trigger
SCOPE_VIOLATION Tool not in role's allowed_tools (e.g. execute on a read-only role)
PARAMETER_VIOLATION Table not in allowed_tables
DATA_LIMIT_EXCEEDED Query limit argument exceeds max_rows
MCP_SERVER_UNAUTHORIZED Agent's JWT does not include database in allowed_mcp_servers
MCP_TOOL_NOT_FOUND Tool name not in Database MCP server's declared manifest
MCP_ARGUMENT_SCHEMA_VIOLATION Required argument (table or query) missing from call

Example: enforce row limit

from scopebound import ScopeboundDenyError

try:
    adapter.enforce("query", {"table": "invoices", "limit": 50000})
except ScopeboundDenyError as e:
    print(e.deny_code)   # DATA_LIMIT_EXCEEDED
    print(e.reason)      # "limit 50000 exceeds max_rows 1000"

Example: read-write agent with HITL on execute

role = DatabaseMCPAdapter.role_template(
    name="db-write-agent",
    allowed_tables=["invoices"],
    read_only=False,
    approval_required=["execute"]
)
sb.create_role(**role)

adapter = DatabaseMCPAdapter(sb, role_id="db-write-agent")

from scopebound import ScopeboundPendingError

try:
    adapter.enforce("execute", {"query": "UPDATE invoices SET status='paid' WHERE id=42"})
except ScopeboundPendingError as e:
    status = sb.get_approval(e.approval_id)
    # Poll until approved or expired

Direct endpoint

curl -X POST https://your-partner.api.scopebound.ai/v1/mcp/enforce \
  -H "X-Scopebound-API-Key: sb-your-key" \
  -H "Content-Type: application/json" \
  -d '{
    "jwt": "your-session-jwt",
    "tool_name": "query",
    "arguments": {"table": "invoices", "limit": 100},
    "mcp_server": "database",
    "mcp_tool_schema": {"required": ["table"]}
  }'