Documentation · Oracle
Creating an Oracle user with minimal privileges
This page is an outline. What is here is accurate, but it is
not yet the whole story — each section ends with a note on what is still to be
written. For anything it does not answer, DEPLOYMENT.md and
USING-MCP.md in the repository are the complete references.
Every caller shares one Oracle account. The generated server authenticates to the database,
not its callers — Oracle sees one service account no matter which agent called. Per-caller
attribution lives in the proxy’s access records, not in V$SESSION.
That makes this account’s grants the real boundary. Curation decides what tools exist; the grant decides what those tools can do if anything ever goes wrong with the first answer. Use both.
The shape of it
CREATE USER mcp_agent IDENTIFIED BY "..."
DEFAULT TABLESPACE users
QUOTA UNLIMITED ON users; -- only if it writes
GRANT CREATE SESSION TO mcp_agent;
-- One line per object you actually exposed. Not a role, not ANY privilege.
GRANT SELECT ON payroll.employee TO mcp_agent;
GRANT EXECUTE ON payroll.js_admin TO mcp_agent;
GRANT SELECT ON payroll.job_id_seq TO mcp_agent;
Rules worth keeping
- Grant per object, and only the operations the tools need. If a table is exposed read-only in
the config, do not grant
INSERTon it — then the two answers agree. - No
ANYprivileges, noDBA, noSELECT ANY TABLE. They defeat the point. RESOURCEno longer impliesUNLIMITED TABLESPACEon 12c and later. If the account writes, grant quota explicitly, or the first insert fails withORA-01950.- The generator needs dictionary access at design time, which is not the same account’s job at run time. You can use a different, better-privileged account to introspect and a narrow one to run.
To write. A complete copy-paste script; the exact dictionary grants introspection needs (
ALL_ARGUMENTS,ALL_PLSQL_*,ALL_TAB_COLUMNSand friends); notes on proxy authentication; what to do when the objects live in a second schema; a read-only-agent recipe.