MCP Integration
Connect AI assistants like Claude and Cursor to manage Odoo instances through oCore using the Model Context Protocol.
oCore implements a Model Context Protocol (MCP) server that lets AI assistants interact with your Odoo instances directly. MCP is an open standard that provides a structured way for AI tools to discover and call functions exposed by external systems. Through oCore's MCP server, assistants like Claude Desktop, Cursor, and other MCP-compatible clients can search records, inspect schemas, run SQL queries, manage modules, and more -- all scoped to the instances your API key has access to.
How It Works
When an AI assistant connects to oCore's MCP server, it authenticates with an API key and receives a list of tools namespaced by instance. For example, if your API key has access to an instance with slug prod-v17, the assistant sees tools like prod_v17_search_read, prod_v17_execute_sql, and prod_v17_list_models. The assistant can then call these tools as part of a conversation to read data, inspect schemas, or perform operations on that Odoo instance.
Each MCP session is isolated: the tools available depend on the API key's permissions, instance scoping, and your organization's security settings.
Setting Up MCP Access
There are two ways to connect an AI assistant to oCore:
- OAuth flow (recommended): The AI client connects directly using the MCP server URL. oCore handles authentication through an OAuth consent screen in your browser -- no API key copying required.
- Manual API key: Create an API key in the dashboard and paste it into the client's configuration file.
Instance and Category Filtering
You can filter which instances appear in a session by appending ?instances=slug1,slug2 to the SSE URL. You can also filter tool categories with ?categories=orm,sql,metadata.
Connecting Claude Desktop
Claude Desktop supports OAuth-based MCP connections. Add this to your claude_desktop_config.json (typically at ~/.config/claude/claude_desktop_config.json on Linux or ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"ocore": {
"type": "sse",
"url": "https://your-ocore-domain.com/api/mcp/sse"
}
}
}When Claude Desktop connects, it will discover oCore's OAuth endpoints automatically, open your browser for login and consent, and receive tokens without any manual key management.
{
"mcpServers": {
"ocore": {
"type": "sse",
"url": "https://your-ocore-domain.com/api/mcp/sse",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}Create an API key in Settings > API Keys and paste it into the config.
After saving the config, restart Claude Desktop. The MCP tools will appear in the tool picker.
Connecting ChatGPT
ChatGPT uses the same OAuth-based MCP connection flow. When you add oCore as an MCP server in ChatGPT:
Enter the oCore MCP server URL: https://your-ocore-domain.com/api/mcp/sse
ChatGPT discovers the OAuth authorization server via the .well-known endpoints.
Your browser opens to the oCore login page (if not already signed in), then the consent screen.
After approving, ChatGPT receives OAuth tokens and the MCP tools become available in your conversation.
The OAuth Consent Flow
When an AI client initiates an OAuth connection, you will see a consent screen in your browser. This is what happens:
Login: If you are not already signed into oCore, you will be redirected to the login page first.
Consent screen: The consent page shows the requesting client's name and logo, the permissions (scopes) it is requesting, and your available organizations.
Select an organization: Pick which organization the AI client should have access to.
Configure permissions: Choose a permission preset or customize categories, instance scoping, tool allowlists, and read-only mode.
API key handling: Choose to auto-create a new MCP API key or link an existing one from the picker.
Approve or deny: Click approve to grant access. oCore creates the API key (if auto-creating) and issues OAuth tokens to the client.
Existing Key Picker
If you already have active MCP API keys in the selected organization, the consent form shows them in a picker. Linking an existing key avoids creating a duplicate and lets you reuse your existing permission configuration.
Managing OAuth Authorizations
Navigate to Settings > OAuth Authorizations to view and manage your active OAuth connections:
- See which AI clients are connected and when they last authenticated
- View the organization and API key linked to each authorization
- Revoke individual authorizations (this soft-deletes the OAuth tokens and cleans up auto-created API keys)
- Revoke all authorizations for a specific client
Using with Cursor
Add the following to your project's .cursor/mcp.json file:
{
"mcpServers": {
"ocore": {
"type": "sse",
"url": "https://your-ocore-domain.com/api/mcp/sse",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}Cursor will discover the MCP server and make the tools available in chat and the agent panel.
Device Flow for CLI Tools
If you are using a CLI tool or working in an environment without browser redirects (SSH sessions, containers), the device authorization flow lets you authenticate:
The CLI tool displays a user code (e.g., BCKF-HMLT) and a verification URL.
Open the URL in any browser on any device. You can also scan the QR code displayed in the terminal.
Log into oCore, confirm the user code, select an organization, and approve.
The CLI tool automatically receives tokens and connects to the MCP server.
Device codes expire after 15 minutes. If the code expires before you approve, the CLI tool will need to request a new one.
MCP Invite Links
An administrator can share an MCP invite link that lets you connect to their organization without going through the full OAuth consent flow. When you receive an invite link:
Open the link in your browser (it looks like https://ocore.example.com/oauth/invite/<token>).
Log into oCore if you are not already signed in.
Review the permissions the invite grants and accept.
oCore creates an MCP API key for you in the admin's organization with the invite's scoped permissions.
If you are not already a member of the organization, oCore automatically adds you as a Viewer. The invite's permissions cannot exceed the admin's own permissions -- scope escalation is prevented.
Using with Other MCP Clients
oCore supports two MCP transports:
- SSE (Server-Sent Events) at
/api/mcp/sse-- for browser-based and long-lived connections - Streamable HTTP at
/api/mcp/stream-- for stateful HTTP-based clients
Any MCP-compatible client can connect by pointing to one of these endpoints. Clients that support OAuth will discover the authorization server automatically. For clients without OAuth support, include a valid API key in the Authorization: Bearer header.
Available Tools
oCore exposes 101 tools across 14 categories. Each instance-scoped tool is prefixed with the instance slug (e.g., myinstance_search_read). Platform tools use the ocore_ prefix.
Tool Categories Overview
| Category | Tools | Description |
|---|---|---|
orm | 12 | Core CRUD and batch operations on Odoo models |
search | 5 | Advanced search, aggregation, count, and fuzzy matching |
metadata | 10 | Model schemas, field definitions, views, translations, and instance info |
sql | 3 | Direct PostgreSQL queries and table inspection |
shell | 3 | Python code execution in the Odoo environment |
files | 9 | Read, write, and search files in Odoo addon directories |
modules | 10 | Install, upgrade, uninstall, and inspect Odoo modules |
system | 18 | User management, cron jobs, system parameters, logs, and backups |
context | 14 | Knowledge notes, saved filters, bookmarks, and context loading |
monitoring | 10 | PostHog analytics: users, errors, performance, sessions |
export | 2 | CSV import and export |
attachments | 4 | List, upload, download, and delete file attachments |
reports | 1 | Generate QWeb reports as PDF or HTML |
platform | 2 | List instances and servers (not instance-scoped) |
Common Parameters
Most tools accept these optional parameters:
| Parameter | Description |
|---|---|
timeout_seconds | Timeout in seconds (default: 15, max: 120) |
max_response_size | Max response size in KB (default: 50) |
context | Odoo context dict (lang, tz, company_id) |
confirm | Required for destructive operations. Set to true to proceed. |
dry_run | If true, returns what would be affected without executing |
ORM Operations
Core CRUD operations on Odoo models. Category: orm.
| Tool | Description | Type |
|---|---|---|
search_read | Search and read records with domain filters, pagination, field selection, and smart field defaults. Supports format: "text" for human-readable output. | Read |
read | Read specific records by their IDs. Returns full field values for the requested records. | Read |
count | Count records matching a domain filter without fetching data. | Read |
create | Create a new record. Returns the full created record with smart-selected fields. | Write |
write | Update existing records by ID. Returns the full updated records. | Write |
unlink | Delete records by ID. Requires confirm: true. | Destructive |
copy | Duplicate a record with optional field overrides. Returns the full new record. | Write |
execute_method | Call any public model method not covered by other tools. Blocked methods (sudo, with_user, shell, etc.) and blocked models (ir.config_parameter) are rejected. Read-only methods like name_search, default_get, and onchange bypass the write check. | Write |
Smart Field Selection
search_read, read, create, and write automatically select the most useful fields when none are specified, omitting large binary/HTML fields and internal technical fields. You can always pass an explicit fields array to override.
Search and Aggregation
Advanced search tools for complex queries. Category: search.
| Tool | Description | Type |
|---|---|---|
advanced_search | Search with a mandatory domain filter. Like search_read but domain is required. Includes total count and pagination hints. | Read |
aggregation | Group and aggregate data using Odoo's read_group. Supports presets (count_by_state, count_by_date) and output formats (json, table, csv). | Read |
distinct_field_values | Get distinct values for one or more fields. Useful for understanding data distribution. | Read |
fuzzy_search | Fuzzy text search with similarity scoring using Python's difflib. Supports multi-field matching via search_fields. | Read |
Batch Operations
Bulk operations on multiple records. Category: orm (uses ORM permission category). Max batch size: 500.
| Tool | Description | Type |
|---|---|---|
batch_create | Create multiple records in one call. Each record is independent -- partial failures do not roll back successful creates. | Write |
batch_update | Update multiple records with different values each. Each update is independent. | Write |
batch_delete | Delete multiple records by ID. Requires confirm: true. | Destructive |
batch_copy | Duplicate multiple records with optional shared default overrides. | Write |
batch_execute | Execute a method on multiple records independently. | Write |
Schema and Metadata
Inspect Odoo model definitions and instance configuration. Category: metadata.
| Tool | Description | Type |
|---|---|---|
list_models | List all non-transient Odoo models with name, label, state, and source module. Results are cached for 5 minutes. Filterable by state and search. | Read |
get_field_metadata | Get field definitions for a model. Default summary mode shows 12 attributes per field. Set detail: true for full metadata. Set grouped: true (default) to organize by simple/relational/technical categories. | Read |
get_model_constraints | Get SQL and Python constraints defined on a model. | Read |
get_model_relations | Get all relational fields (Many2one, One2many, Many2many) with their target models, inverse names, and relation tables. | Read |
get_model_methods | List all methods on a model including API decorator type. Set include_private: false to hide private methods. | Read |
get_model_views | Get view definitions (XML arch + metadata) for form, tree, search, and kanban views. Optionally filter by view_type. | Read |
get_instance_info | Get oCore instance details: server, environment, project, Odoo version, edition, write status, ports, and timestamps. | Read |
get_addon_manifest | Read a module's manifest metadata from ir.module.module: name, summary, description, author, license, category, state, and installed version. | Read |
SQL Queries
Direct PostgreSQL access. Category: sql.
| Tool | Description | Type |
|---|---|---|
execute_sql | Run a SQL query against the instance database. SELECT queries auto-add LIMIT 1000 if no LIMIT is specified. DML (INSERT/UPDATE/DELETE) requires confirm: true and shows an EXPLAIN preview first. DDL is blocked. Dangerous functions (pg_read_file, dblink, lo_import) are blocked. Output formats: json, table, csv. Supports explain: true for query plans. | Write |
execute_sql_script | Run a multi-statement SQL script with transaction control (BEGIN/COMMIT/SAVEPOINT). Requires confirm: true for DML. DDL is blocked. | Destructive |
list_tables | List database tables with row counts, sizes, and Odoo model mapping. Set raw_pg: true for raw PostgreSQL table info without model resolution. | Read |
SQL Safety
DDL statements (CREATE TABLE, ALTER TABLE, DROP TABLE) are always blocked. Dangerous PostgreSQL functions for filesystem and external access are rejected. A statement_timeout is set automatically based on the timeout_seconds parameter.
Shell and Code Execution
Execute Python code in the Odoo environment. Category: shell. All shell tools require mcp_write_enabled.
| Tool | Description | Type |
|---|---|---|
execute_shell | Execute Python code in the Odoo shell with access to env, self, and all Odoo imports. Output is wrapped as {stdout, stderr, exit_code}. | Write |
execute_shell_multi | Execute multiple Python commands in a single session. Variables and imports persist across commands within the same call. | Write |
python_repl | Stateless Python REPL. Each call starts fresh -- include all imports and setup each time. | Write |
File Operations
Read and modify files in Odoo addon directories. All paths are relative to the instance's custom addons root and sandboxed to prevent directory traversal. Category: files.
| Tool | Description | Type |
|---|---|---|
file_browse | List files and directories in an addon directory. Omit path to list all custom addons. | Read |
file_read | Read file content. Supports line ranges (start_line, end_line) for large files and encoding: "base64" for binary files. Default max size: 100KB. | Read |
file_write | Edit an existing file. Three modes: full_content (replace entire file), patch (unified diff), or insert_at_line (insert at a specific line). | Write |
file_create | Create a new file or directory. Set is_directory: true for directories. Supports nested directory creation. | Write |
file_delete | Delete a file. Requires confirm: true. | Destructive |
file_info | Get file metadata: size, permissions, modification time, and git status (modified, staged, untracked, clean). | Read |
file_tree | Recursive directory listing. Default depth: 3 levels (max: 3). | Read |
file_move | Move or rename a file within the addon directory. | Write |
search_in_code | Search for text or regex patterns in addon source code. Scope to a specific addon or search all custom addons. Returns file paths, line numbers, and matching content with context. | Read |
Module Management
Install, upgrade, and inspect Odoo modules. Category: modules. Install/upgrade/uninstall operations enforce a minimum 90-second timeout.
| Tool | Description | Type |
|---|---|---|
list_modules | List all available modules with state, version, category, and author. Filterable by state, category, and search. | Read |
install_module | Install an Odoo module. | Write |
upgrade_module | Upgrade one or more modules to their on-disk version. | Write |
uninstall_module | Uninstall a module. Requires confirm: true. | Destructive |
module_drift | Detect version drift between installed modules in the database and their on-disk manifest versions. | Read |
module_dependencies | Get the dependency graph for a module. Shows both direct and reverse dependencies. | Read |
module_categories | List all module categories with module counts. | Read |
check_uninstall_deps | Check what depends on a module before uninstalling. Shows dependent modules, models, and views that would break. | Read |
module_history | View module install/upgrade history for the instance. | Read |
scaffold_module | Create a complete Odoo module skeleton with manifest, models, views, security, and directory structure. | Write |
User and System Administration
Manage Odoo users, system parameters, cron jobs, and server operations. Category: system.
| Tool | Description | Type |
|---|---|---|
list_users | List Odoo users with search and active filter. Returns id, login, name, active, last_login, share, and company_id. | Read |
user_groups | View security group memberships for a user. Returns group id, full name, and category. | Read |
set_user_active | Activate or deactivate a user. System users (IDs 1-3) are protected. | Write |
set_user_password | Reset a user's password (superuser reset, no current password needed). Min 8 characters. System users protected. | Write |
set_user_groups | Replace all security group assignments for a user. Use user_groups first to see current groups. | Write |
impersonate_user | Create a one-time login URL to impersonate an Odoo user with full audit trail. System users protected. | Write |
user_access_rights | View effective access rights for a user on a model. Shows can_read, can_write, can_create, can_unlink and granting groups. Set detail: true for raw ACL and ir.rule data. | Read |
get_system_parameter | Read Odoo system parameters (ir.config_parameter). Without a key, returns all parameters. Sensitive values (passwords, secrets, tokens) are automatically masked. | Read |
set_system_parameter | Set or create an Odoo system parameter. | Write |
list_scheduled_actions | List all scheduled actions (ir.cron) including disabled ones. Shows interval, next/last call times, and priority. | Read |
toggle_scheduled_action | Enable or disable a scheduled action. | Write |
run_scheduled_action | Trigger a scheduled action immediately. Enforces a 60-second cooldown between identical triggers. Requires confirm: true. | Write |
clear_system_cache | Clear Odoo caches (asset bundles, .pyc files, session files). Requires confirm: true. | Destructive |
server_info | Get Odoo server version, installed module count, database name, and configuration. | Read |
odoo_logs | Tail Odoo container logs. Default 100 lines (max 1000). Supports grep-style filtering with filter parameter. | Read |
Database Backup and Restore
Create, list, and restore database backups. Category: system.
| Tool | Description | Type |
|---|---|---|
backup_database | Create a pg_dump backup. Pre-checks database size against a configurable limit (default 2GB). Formats: custom (binary, default) or plain (SQL text). | Write |
list_backups | List available backup files with timestamps and sizes. Filterable by max_age_days. | Read |
restore_database | Restore a database from a backup file. Automatically creates a pre-restore snapshot before proceeding. Stops and restarts the Odoo container. Requires confirm: true. | Destructive |
Restore Safety
Database restore is a destructive operation. A pre-restore backup is always created automatically. If the pre-restore backup fails, the restore is aborted. The Odoo container is always restarted after restore, even if the restore fails mid-way.
Knowledge and Context
Persistent knowledge storage and reusable filters for AI sessions. Category: context.
Notes
| Tool | Description | Type |
|---|---|---|
add_note | Add a knowledge note about an instance, model, record, field, or module. Notes are shared across all API keys in the organization. Max 100 notes per scope. | Write |
list_notes | List notes filtered by target type, tags, or search text. | Read |
update_note | Update an existing note. Only provided fields are modified. | Write |
delete_note | Soft-delete a note. Requires confirm: true. | Destructive |
set_model_summary | Set or update the summary note for a specific model. Upserts a note tagged ["summary"]. | Write |
set_instance_summary | Set or update the summary note for the instance. Upserts a note tagged ["summary"]. | Write |
Saved Filters
| Tool | Description | Type |
|---|---|---|
save_filter | Save a reusable search filter for a model. Stores domain, fields, order, and limit. | Write |
list_filters | List saved filters for the instance, sorted by most-used first. | Read |
run_filter | Execute a saved filter by name or ID and return matching records. | Read |
delete_filter | Soft-delete a saved filter. Requires confirm: true. | Destructive |
Bookmarks and Context
| Tool | Description | Type |
|---|---|---|
bookmark_call | Bookmark an MCP tool call for future reference. Stores an inline snapshot of the tool name, parameters, and result summary. If no audit_log_id is provided, bookmarks the most recent call in the session. | Write |
list_bookmarks | List bookmarked tool calls. Filterable by instance, tags, or search text. Returns up to 50 bookmarks, most recent first. | Read |
delete_bookmark | Soft-delete a bookmark. Requires confirm: true. | Destructive |
get_context | Load aggregated knowledge context: instance summary, model summaries, notes, saved filters, and recent bookmarks. Useful at session start to give the AI assistant full context. | Read |
Analytics and Monitoring
PostHog-powered analytics for Odoo instances. Category: monitoring. Requires PostHog to be configured. All tools accept a period parameter (1d, 7d, 14d, 30d, 90d).
| Tool | Description | Type |
|---|---|---|
posthog_dashboard | Full analytics dashboard: DAU, WAU, MAU, sessions, error rate, top modules, and web vitals. | Read |
posthog_active_users | Active user counts (DAU/WAU/MAU) and top users list. | Read |
posthog_online_users | Currently online users (real-time, last 5 minutes). | Read |
posthog_module_usage | Module usage analytics: which modules are most used and adoption rates. | Read |
posthog_web_vitals | Core Web Vitals (LCP, INP, CLS) and performance metrics. | Read |
posthog_errors | Error summary: top error types, counts, and trends. | Read |
posthog_slow_rpcs | Slowest RPC calls: endpoint, average duration, and call count. | Read |
posthog_sessions | Session statistics: count, average duration, bounce rate, and trends. | Read |
posthog_feature_flags | List PostHog feature flags: key, active status, and rollout percentage. | Read |
posthog_surveys | List PostHog surveys: name, type, status, and response count. | Read |
CSV Import and Export
Bulk data import/export via CSV. Category: orm (uses ORM permission category).
| Tool | Description | Type |
|---|---|---|
import_csv | Import records from CSV content. Validates headers against model fields, supports field_mapping to remap column names, and creates records in batches of 100. Max 1000 rows. Includes CSV formula injection protection. Note: batches commit independently with no rollback between batches. | Write |
export_csv | Export records as CSV. Uses smart field defaults (stored fields only) when no fields are specified. Max 5000 rows (default 500). Column headers use field labels. | Read |
Translations
Read and update Odoo translations. Handles both Odoo 17 (ir.translation model) and Odoo 18+ (field translation API) automatically. Category: metadata.
| Tool | Description | Type |
|---|---|---|
list_translations | List translations for a model, optionally filtered by field and language. | Read |
update_translation | Update a translation value. For Odoo 18+, the source parameter (old value to replace) is required. | Write |
Attachments
Manage Odoo file attachments (ir.attachment). Category: attachments. Max file size: 10 MB.
| Tool | Description | Type |
|---|---|---|
list_attachments | List attachments for a specific model record. Filterable by MIME type. | Read |
upload_attachment | Upload a base64-encoded file attachment to a model record. Requires mcp_write_enabled. | Write |
download_attachment | Download attachment content by ID as base64. Runs as admin and bypasses ir.attachment record rules. | Read |
Reports
Generate Odoo QWeb reports. Category: reports.
| Tool | Description | Type |
|---|---|---|
generate_report | Generate a QWeb report as PDF or HTML. Pre-checks wkhtmltopdf status for PDF format. Max records: 10 for PDF, 50 for HTML. Output size limit: 10 MB (base64). Minimum timeout: 60 seconds. | Read |
Platform Tools
These tools are not instance-scoped and use the ocore_ prefix instead of an instance slug. Category: platform.
| Tool | Description |
|---|---|
ocore_list_instances | List all instances accessible to the current API key. Returns id, name, slug, Odoo version, status, environment type, and mcp_write_enabled. |
ocore_list_servers | List all servers in the organization. Returns id, name, host, and status. |
Knowledge Layer
The Knowledge Layer is a persistent storage system that lets AI assistants accumulate and reuse knowledge about your Odoo instances across sessions. It consists of three data types -- notes, saved filters, and bookmarks -- all scoped to your organization and optionally to specific instances.
Notes
Notes store human or AI-authored knowledge about your Odoo environment. Each note is attached to a specific target:
| Target Type | Description | Example |
|---|---|---|
instance | About the instance as a whole | "This is our EU production instance running custom e-commerce flows" |
model | About a specific Odoo model | "sale.order: Custom fields x_approved_by and x_delivery_notes track approval workflow" |
record | About a specific record | "res.partner#42: Key customer, do not modify without sales team approval" |
field | About a specific field | "sale.order.x_delivery_notes: Free-text field used by warehouse team" |
module | About a custom module | "custom_invoicing: Handles VAT split for cross-border EU sales" |
Notes properties:
- Title -- Up to 200 characters
- Body -- Up to 2,000 characters of content
- Tags -- Optional array of tags for filtering (e.g.,
["summary", "workflow"]) - Shared -- Notes are shared across all API keys in the organization
- Limit -- Up to 100 notes per scope to prevent unbounded growth
- Soft delete -- Deleted notes are soft-deleted and excluded from queries
Summary Notes
Notes tagged with "summary" have special significance. The set_model_summary and set_instance_summary tools upsert a single summary note per target, making it easy to maintain one authoritative description. Summary notes are used by auto-context (see below) to inject knowledge into tool descriptions at session start.
Saved Filters
Saved filters store reusable Odoo domain searches that can be executed by name:
| Field | Description |
|---|---|
| Name | Unique name per instance (e.g., "large_orders", "overdue_invoices") |
| Model | The Odoo model to search (e.g., sale.order) |
| Domain | Odoo domain filter expression as JSON (e.g., [["amount_total", ">", 10000]]) |
| Fields | Optional list of fields to return |
| Order By | Sort order (e.g., amount_total desc) |
| Result Limit | Maximum results to return (default 80) |
| Is Default | At most one filter per model per instance can be the default |
| Use Count | Automatically incremented each time the filter is executed, enabling "most-used first" sorting |
Saved filters let an AI assistant quickly recall complex queries without re-specifying the domain each time. Use list_filters to see available filters (sorted by most-used first) and run_filter to execute one.
Bookmarks
Bookmarks save references to important MCP tool calls for future reference:
| Field | Description |
|---|---|
| Label | Human-readable description (up to 200 characters) |
| Note | Optional extended notes (up to 1,000 characters) |
| Tags | Optional tags for filtering |
| Tool Name | The MCP tool that was called |
| Tool Params | Snapshot of the tool's input parameters |
| Result Summary | Truncated result (up to 500 characters) |
| Audit Log ID | Optional link to the MCP audit log entry |
Bookmarks store an inline snapshot of the tool call so they remain useful even if audit log entries are later purged. If no audit_log_id is provided when bookmarking, the system bookmarks the most recent call in the current session.
Auto-Context
When an API key has mcp_auto_context enabled, oCore automatically injects Knowledge Layer data into tool descriptions at session start. This gives the AI assistant immediate context without requiring an explicit get_context call.
At session registration time, oCore runs a parallel query (with a 5-second deadline) for each instance:
- Instance summary -- Loads the note tagged
"summary"withtarget_type=instance - Model summaries -- Loads up to 20 notes tagged
"summary"withtarget_type=model, showing the model name and a 150-character excerpt - Saved filter count -- Counts available saved filters and mentions them if any exist
The results are prepended to each instance's tool descriptions as an [Auto-context] prefix. For example:
[Auto-context] Instance context: EU production instance with custom VAT workflow.
Model summaries: sale.order: Custom approval fields x_approved_by, x_delivery_notes;
account.move: Modified to support split VAT for EU cross-border. 3 saved filters
available -- call get_context for details.Enabling Auto-Context
Auto-context is controlled per API key. Enable it in the API key settings or during OAuth consent. The feature adds a small overhead at session start (5-second max) but provides immediate context for every conversation.
Loading Full Context
The get_context tool loads the complete Knowledge Layer for an instance in a single call:
- Instance summary note
- All model summary notes
- All notes (non-summary, up to limit)
- All saved filters with name, model, and description
- Recent bookmarks (up to 50)
This is useful at the beginning of a session when auto-context is not enabled, or when the assistant needs the full detail beyond what auto-context provides.
Security
oCore's MCP server enforces multiple layers of security on every tool call:
Authentication
Every MCP session requires a valid API key. Keys are periodically revalidated against the database (every 30 seconds) to detect revocation, expiration, or user deactivation mid-session.
Instance Scoping
API keys can be scoped to specific instances. A key scoped to prod-v17 will only see tools for that instance -- no other instances are visible or callable.
RBAC Categories
API keys can be restricted to specific tool categories (e.g., orm, sql, metadata). If a key only has orm and metadata permissions, shell and SQL tools are blocked. An empty permission list grants full access.
Read-Only Mode
Keys can be marked as read-only, which blocks all write and destructive operations while still allowing search, read, and metadata inspection tools.
Production Guard
Each instance has a mcp_write_enabled flag. When disabled (the default for production instances), all write operations are blocked regardless of the API key's permissions. This prevents accidental data modification in production.
Destructive Operation Confirmation
High-risk tools require a confirm: true parameter. Without it, the tool returns a warning message describing what would happen instead of executing. The following tools are marked destructive:
unlink,batch_delete-- record deletionexecute_sql_script-- multi-statement SQLfile_delete-- file deletionuninstall_module-- module removalclear_system_cache-- cache clearingrestore_database-- database restoredelete_note,delete_filter,delete_bookmark-- knowledge deletion
IP Allowlist
API keys can include an IP allowlist. Connections from IPs not on the list are rejected.
Kill Switch
Organization administrators can disable MCP access entirely via the organization settings toggle. This immediately blocks all MCP tool calls for every key in the organization.
Rate Limiting
Per-key rate limiting prevents abuse:
| Transport | Default Limit |
|---|---|
| SSE | 100 calls/minute |
| Stdio | 30 calls/minute |
Tool Allow/Deny Lists
API keys support per-tool filtering with allow or deny lists, giving fine-grained control over which specific tools a key can invoke.
Model Allowlist
API keys can restrict which Odoo models are accessible. When a model allowlist is set, list_models only returns models in the allowlist, and ORM operations on other models are rejected.
Input Validation
All tool inputs are validated before execution:
- Model names, field names, and method names are checked against a strict identifier pattern (
[a-zA-Z_][a-zA-Z0-9_.]*). - SQL queries are stripped of comments and strings, then scanned for DDL, dangerous functions, and blocked statements.
- File paths are sandboxed to the instance's addon directory with traversal prevention.
- User IDs 1-3 (admin, public,
__system__) cannot be modified by user management tools.
Audit Logging
Every MCP tool call is recorded in a dedicated mcp_audit_log table with:
- Tool name and category
- Input parameters (sensitive values like passwords are automatically redacted)
- Result summary (truncated to 500 characters)
- Whether the call succeeded or errored
- Latency in milliseconds
- Session ID, API key ID, user ID, and IP address
High-level session events (session started, session ended) are also logged to the main audit log.
Sensitive Data Redaction
Parameters containing keys like password, secret, token, or credential are automatically replaced with [REDACTED] before being written to the audit log.
Prompt Templates
oCore includes built-in MCP prompt templates that AI assistants can use for guided analysis:
| Prompt | Description |
|---|---|
analyze_error | Analyze an Odoo traceback and suggest fixes |
explain_model | Explain an Odoo model's purpose, fields, and relationships |
debug_performance | Diagnose Odoo performance issues based on symptoms |
Example Usage Patterns
Exploring an instance
1. ocore_list_instances -- discover available instances
2. myinstance_get_instance_info -- get version, environment, status
3. myinstance_server_info -- Odoo server details
4. myinstance_list_models search="sale" -- find sale-related models
5. myinstance_get_field_metadata model="sale.order" -- understand the schemaSearching and reading data
1. myinstance_search_read model="res.partner" domain=[["is_company","=",true]] fields=["name","email"] limit=10
2. myinstance_aggregation model="sale.order" fields=["amount_total:sum"] groupby=["state"] format="table"
3. myinstance_count model="sale.order" domain=[["state","=","sale"]]
4. myinstance_fuzzy_search model="res.partner" query="Acme Corp" min_score=0.6Modifying data safely
1. myinstance_create model="res.partner" values={"name":"New Partner","email":"new@example.com"}
2. myinstance_write model="res.partner" ids=[42] values={"phone":"+1234567890"}
3. myinstance_unlink model="res.partner" ids=[99] confirm=trueWorking with modules
1. myinstance_list_modules state="installed"
2. myinstance_module_dependencies addon="sale"
3. myinstance_check_uninstall_deps module="sale_stock"
4. myinstance_install_module module="sale_management"Debugging with SQL and logs
1. myinstance_execute_sql query="SELECT id, name FROM res_partner WHERE active = false LIMIT 10"
2. myinstance_odoo_logs lines=200 filter="ERROR"
3. myinstance_execute_sql query="SELECT state, count(*) FROM sale_order GROUP BY state"Using knowledge context
1. myinstance_get_context -- load all saved knowledge at session start
2. myinstance_set_model_summary model="sale.order" summary="Main sales model. Custom fields: x_approved_by, x_delivery_notes."
3. myinstance_save_filter name="large_orders" model="sale.order" domain=[["amount_total",">",10000]] fields=["name","partner_id","amount_total"]
4. myinstance_run_filter name="large_orders"Troubleshooting
Tools not appearing in the AI assistant
- Verify the API key is valid and not expired or revoked
- Check that the organization has MCP enabled (kill switch is off)
- Confirm at least one instance is in
runningstatus - Check your AI client's MCP configuration for syntax errors
Tool calls returning "unauthorized"
- The API key may have been revoked or expired since the session started
- The owning user account may have been deactivated
- The organization may have toggled MCP off via the kill switch
Tool calls returning "permission denied"
- The API key's MCP permissions do not include the tool's category
- Check the key's category list and add the required category (e.g.,
sql,shell) - Keys with no explicit permissions have full access to all categories
Write operations blocked
- The instance has
mcp_write_enabledset tofalse(production guard) - The API key is in read-only mode
- For destructive operations, include
confirm: truein the tool arguments
Rate limit exceeded
- Reduce the frequency of tool calls
- Contact your administrator to adjust rate limits if the default is too low for your use case
Shell/SQL tools timing out
- Increase the
timeout_secondsparameter (max 120 seconds) - For module operations, the minimum timeout is automatically raised to 90 seconds
- For report generation, the minimum timeout is automatically raised to 60 seconds
- Long-running SQL queries have a
statement_timeoutset automatically