The Deeto MCP Server provides a standardized JSON-RPC 2.0 interface for querying and managing customer references, companies, content assets, and prospect data — compatible with Claude Desktop, custom agents, or any MCP-compatible client.Documentation Index
Fetch the complete documentation index at: https://knowledge.deeto.com/llms.txt
Use this file to discover all available pages before exploring further.
vendorId is auto-injected from your API key. You never need to pass
vendorId in any tool call. The server reads it from your Authorization header and injects it automatically — any value you pass is silently overridden.Server Details
| Property | Value |
|---|---|
| Protocol | JSON-RPC 2.0 |
| MCP Version | 2024-11-05 |
| Server Name | deeto-mcp-server |
| Transport | HTTP Streamable |
| Base URL | https://api.deeto.ai/v2/mcp |
What You Can Do
Query Data
Search and filter people (references and prospects), companies, and content assets with powerful filtering, sorting, and pagination.
Create Records
Add new companies and reference contacts to your workspace programmatically.
Generate Content
Create case studies, win/loss reports, and other content drafts using your reference data.
Get Insights
Access aggregated workspace statistics, rewards data, and prospect pipeline views.
Available Tools
| Tool | Description | Min. Privilege |
|---|---|---|
get-stats | Workspace totals for people, companies, content, and rewards | contentViewer |
get-people | Query references and prospects with filtering, sorting, and pagination | contentViewer |
get-companies | Query companies with search, filtering, and sorting | contentViewer |
get-contents | Query content assets (quotes, reviews, case studies, etc.) | contentViewer |
get-prospects-dashboard | Prospect pipeline view with meeting data | rep |
get-content-instructions | Schema and instructions for creating a content type | rep |
create-company | Create a new company in your workspace | admin |
create-person | Create a new reference contact | admin |
save-draft-content | Save a content draft (case study, win/loss report) | admin |
- Getting Started
- Authentication
- Tools Reference
- Examples
- Error Handling
- Security
Getting Started
Generate an API Key
API keys are generated from the Deeto platform by workspace Admins or Deeto Admins. Each key has a privilege level that determines which tools it can access.When creating a key you specify:
- Name — a descriptive label
- Privilege — the access level for this key
dtk_live_ prefix:dtk_live_abc123def456...
The full API key is shown only once at creation time. Store it securely — it cannot be retrieved later. Only a truncated preview is shown in the management UI.
You cannot create a key with a higher privilege level than your own. An Admin cannot create a Deeto Admin key.
Initialize the Connection
Send an Response:
initialize request to establish the MCP session:POST https://api.deeto.ai/v2/mcp
Authorization: Bearer dtk_live_your_api_key_here
Content-Type: application/json
{
"jsonrpc": "2.0",
"method": "initialize",
"id": 1
}
{
"jsonrpc": "2.0",
"result": {
"protocolVersion": "2024-11-05",
"capabilities": { "tools": {} },
"serverInfo": {
"name": "deeto-mcp-server",
"version": "1.0.0"
},
"instructions": "..."
},
"id": 1
}
Your
vendorId is embedded in the instructions field of the initialize response. You can also find it in the Deeto platform settings.List Available Tools
Discover which tools your API key can access:The response includes each tool’s name, description, and input schema. Tools above your privilege level are not returned.
{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 2
}
Make Your First Call
Start with Response:
get-stats for a quick overview:{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-stats",
"arguments": {}
},
"id": 3
}
{
"jsonrpc": "2.0",
"result": {
"content": [{
"type": "text",
"text": "{\"data\":{\"tools\":{\"get-people\":{\"total\":619},\"get-companies\":{\"total\":526},\"get-contents\":{\"total\":3322}},\"rewards\":{\"totalRedemptions\":124,\"totalRedeemedAmount\":9300,\"totalRedeemableAmount\":4150}}}"
}]
},
"id": 3
}
Query Your Data
Now try querying references with filtering and pagination:Response:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-people",
"arguments": {
"userPrivileges": "reference",
"page": 1,
"pageSize": 10,
"fields": ["basic", "status"]
}
},
"id": 4
}
{
"jsonrpc": "2.0",
"result": {
"content": [{
"type": "text",
"text": "{"data":[{"id":"uuid","authenticatedUser":{"firstName":"Jane","lastName":"Doe","email":"jane@acme.com"},"account":{"companyName":"Acme Corp"},"userStatus":"referrer-confirmed"}],"pagination":{"totalCount":619,"returned":10,"hasNext":true,"isLastPage":false}}"
}]
},
"id": 4
}
Connecting with Claude Desktop
Add this to your Claude Desktop MCP configuration file:- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"deeto": {
"command": "npx",
"args": [
"mcp-remote",
"https://api.deeto.ai/v2/mcp",
"--header",
"Authorization:${AUTH_TOKEN}"
],
"env": {
"AUTH_TOKEN": "Bearer dtk_live_your_api_key_here"
}
}
}
}
- “How many references do we have?”
- “Show me all confirmed references at enterprise companies”
- “Find all quotes tagged with ‘ROI’”
- “Create a case study based on our Acme Corp references”
Authentication
All requests must include your API key in theAuthorization header:Authorization: Bearer dtk_live_your_api_key_here
Privilege Levels
Privileges are hierarchical — higher levels inherit all permissions from lower levels.| Rank | Privilege | API Value | Capabilities |
|---|---|---|---|
| 0 | Content Viewer | contentViewer | Read-only access to people, companies, content, and stats |
| 1 | Rep | rep | Content Viewer + prospect dashboard, content instructions |
| 2 | Manager | manager | Rep + start-agent tool for automated workflows |
| 3 | Admin | admin | Manager + create companies, create people, save drafts, manage API keys |
| 4 | Deeto Admin | deetoAdmin | Full platform access (Deeto internal use) |
Tool-to-Privilege Mapping
| Tool | Minimum Privilege Required |
|---|---|
get-stats | contentViewer |
get-people | contentViewer |
get-companies | contentViewer |
get-contents | contentViewer |
get-prospects-dashboard | rep |
get-content-instructions | rep |
create-company | admin |
create-person | admin |
save-draft-content | admin |
Key Management
| Capability | Supported | Notes |
|---|---|---|
| Immediate revocation | ✅ Yes | Revoked keys are rejected on the next request with no propagation delay |
| Key rotation | ✅ Yes | Generate a new key and revoke the old one at any time via the Deeto admin console |
| Automatic expiration (TTL) | 🔄 In development | On the roadmap. Keys can be manually revoked at any time in the interim |
| IP allowlist | ❌ No | Not currently supported |
Authentication Errors
| Scenario | Error Code | Message |
|---|---|---|
| No auth header | -32001 | Unauthorized: Bearer token required |
| Invalid or malformed key | -32001 | Unauthorized: Invalid API key |
| Revoked key | -32001 | Unauthorized: API key has been revoked |
| Insufficient privilege | -32001 | Forbidden: tool '<name>' requires '<required>' privilege but your API key/token has '<current>'. Ask a workspace admin to upgrade the privilege of this credential, or use a different credential with sufficient access. |
Best Practices
- Use minimum privilege — create keys with only the access level needed
- Rotate keys regularly — revoke old keys and generate new ones periodically
- One key per integration — use separate keys for different applications
- Never expose keys — do not commit keys to source control or expose them client-side
- Monitor usage — the system tracks when each key was last used so you can identify inactive ones
All tools are called via the
Use the
For “available for calls” queries use
Response:
Response:
Response:
Responses exceeding the size limit are automatically truncated with
tools/call JSON-RPC method:{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "tool-name",
"arguments": { }
},
"id": 1
}
vendorId is never required. It is automatically injected from your API key on every call.get-stats
Fast, lightweight tool returning unfiltered workspace totals plus rewards activity.Minimum Privilege:contentViewer | Parameters: None required.Response:{
"data": {
"tools": {
"get-people": { "total": 619 },
"get-companies": { "total": 526 },
"get-contents": { "total": 3322 }
},
"rewards": {
"totalRedemptions": 124,
"totalRedeemedAmount": 9300,
"totalRedeemableAmount": 4150
}
}
}
rewards section when the user asks about redemptions, total redeemed amounts, rewards given, or outstanding rewards.get-people
Query references and prospects with filtering, sorting, and pagination.Minimum Privilege:contentViewer| Parameter | Type | Required | Description |
|---|---|---|---|
mode | String | No | search (default) — use filters to find specific people. analyze — retrieve all data for LLM analysis |
search | String | No | Free-text search across name, email, content, and custom fields. 3+ words triggers AI semantic search; 1–2 words filters by name/email/content |
userPrivileges | String | No | reference or prospect — filter by person type. Omit to return all |
page | Number | No | Page number (default: 1) |
pageSize | Number | No | Items per page. Max 500 for external clients (default: 100) |
orderBy | String | No | createdAt, updatedAt, authenticatedUser.firstName, authenticatedUser.lastName, authenticatedUser.userStatus, account.companyName |
orderDirection | String | No | ASC or DESC (default: DESC) |
fields | Array | No | basic, status, tags, contributions, availability, full (default: ['basic']) |
context | Object | No | Advanced filtering or ID-based selection (see below) |
Fields
| Value | Returns |
|---|---|
basic | id, name, email, company, createdAt |
status | userStatus |
tags | tags and categories |
contributions | contribution types |
availability | scheduling availability |
full | all fields |
Context Filters
{
"context": {
"type": "filters",
"filters": {
"referenceStatus": ["referrer-confirmed", "confirmed", "pending"],
"accountContactIds": ["uuid"],
"callAvailabilities": ["100", "6", "3", "1"],
"additionalFields": [
{ "customizedFormFieldId": "uuid", "value": ["value"] }
]
}
}
}
callAvailabilities values:| Value | Meaning |
|---|---|
"100" | Available as needed |
"6" | Up to 6 calls/quarter |
"3" | Up to 3 calls/quarter |
"1" | Up to 1 call/quarter |
"0" | Not available |
"suspended" | Deactivated by admin |
["100", "6", "3", "1"]. For “unavailable” use ["0", "suspended"].additionalFields discovery: The response metadata contains availableAdditionalFields listing each customizedFormFieldId, fieldName, and allowed values for the workspace. Use those values exactly when filtering.Context Views (select by ID)
{
"context": {
"type": "views",
"views": {
"peopleIds": ["uuid1", "uuid2"]
}
}
}
get-companies
Query companies (accounts) with search, filtering, sorting, and pagination.Minimum Privilege:contentViewer| Parameter | Type | Required | Description |
|---|---|---|---|
mode | String | No | search (default) — find specific companies. analyze — get data for analysis. export — bulk export |
search | String | No | Search by company name |
page | Number | No | Page number (default: 1) |
pageSize | Number | No | Items per page (default: 100) |
orderBy | String | No | Field to sort by |
orderDirection | String | No | ASC or DESC (default: DESC) |
fields | Array | No | basic, extended, tags, full (default: ['basic']) |
context | Object | No | Filter by companyIds or companyNames, or select by views |
get-contents
Query content assets including quotes, reviews, video testimonials, case studies, and more.Minimum Privilege:contentViewerBy default,
get-contents returns both approved and internal only assets. Internal-only assets (e.g. Gong call transcripts) are safe for AI generation context but are not meant for external sharing. If you pass vendorPublishPolicies explicitly, only the statuses you specify are returned.| Parameter | Type | Required | Description |
|---|---|---|---|
mode | String | No | search (default) or analyze |
search | String | No | Full-text search across content |
includeFullContent | Boolean | No | Default false. When true, returns full un-truncated publishedContent. Page size is auto-reduced to fit token limits |
type | String | No | Single type filter (see values below) |
page | Number | No | Page number (default: 1) |
pageSize | Number | No | Items per page. Max 200 for contents (default: 100) |
orderBy | String | No | createdAt, vendorPublishPolicy, name, lastEditedAt (default: createdAt) |
orderDirection | String | No | ASC or DESC (default: DESC) |
context | Object | No | Filter by types (array), tags, companyIds, or select by contentsIds |
Content Types
| Type | Description |
|---|---|
Quote | Text quote from a reference |
Review | Customer review |
VideoTestimonial | Video testimonial asset |
url | URL-based content |
pdf | PDF document |
CaseStudy | Case study |
QuestionsAndAnswers | Q&A asset |
extractedText | Extracted text content |
Transcript | Call or meeting transcript |
To filter by multiple content types, use
context.filters.types (array) instead of the type parameter (single value only).Q&A content: Each
QuestionsAndAnswers asset returns a qa: field with full question/answer pairs formatted as qa: Q: <question> | A: <answer>; .... Answers are truncated to 300 chars each.Context Views (select by ID)
{
"context": {
"type": "views",
"views": {
"contentsIds": ["uuid1", "uuid2"]
}
}
}
get-prospects-dashboard
Retrieve the prospect pipeline/kanban view with optional meeting data.Minimum Privilege:rep| Parameter | Type | Required | Description |
|---|---|---|---|
mode | String | No | search (default) or analyze |
page | Number | No | Page number (default: 1) |
pageSize | Number | No | Items per page. Max 1000 external (default: 100) |
orderBy | String | No | Field to sort by |
orderDirection | String | No | ASC or DESC (default: DESC) |
fields | Array | No | basic, meetings, full (default: ['basic', 'meetings']) |
opportunityOwnerIds | Array | No | Filter by opportunity owner UUIDs |
prospectTemplateIds | Array | No | Filter by prospect template UUIDs |
liveCompanion | Boolean | No | Filter by live companion status |
context | Object | No | Additional filters or views |
get-content-instructions
Get the schema, validation rules, and examples for creating content of a specific type.Minimum Privilege:rep| Parameter | Type | Required | Description |
|---|---|---|---|
contentType | String | Yes | CaseStudy or WinLossReport |
Always call
get-content-instructions before using save-draft-content to understand the exact schema for the content type you’re creating.create-company
Create a new company (account) in your workspace.Minimum Privilege:admin| Parameter | Type | Required | Description |
|---|---|---|---|
companyName | String | Yes | Company name (must be unique in workspace) |
website | URL | No | Company website URL |
companySize | String | No | Company size category |
linkedInProfile | String | No | LinkedIn company page URL |
{
"success": true,
"data": {
"accountId": "uuid",
"companyName": "Acme Corp"
}
}
create-person
Create a new reference contact in your workspace.Minimum Privilege:admin| Parameter | Type | Required | Description |
|---|---|---|---|
email | String | Yes | Contact email (must be unique) |
firstName | String | Yes | First name |
lastName | String | Yes | Last name |
companyName | String | Yes | Associated company name |
title | String | No | Job title |
linkedInProfile | String | No | LinkedIn profile URL |
{
"success": true,
"data": {
"accountContactId": "uuid",
"email": "jane@acme.com",
"firstName": "Jane",
"lastName": "Doe",
"companyName": "Acme Corp"
}
}
save-draft-content
Save a content draft (case study or win/loss report) to the system.Minimum Privilege:adminThe
publishedContent array is required and must contain the actual content blocks. This tool does not generate content — you must build the content first, then pass it here.| Parameter | Type | Required | Description |
|---|---|---|---|
context | Object | Yes | { "conversationId": "uuid" } |
messageId | UUID | Yes | ID of the assistant message creating this draft |
type | String | Yes | CaseStudy or WinLossReport |
name | String | Yes | Draft name (min 3 chars, unique per type in conversation) |
title | String | No | Display title (defaults to name) |
publishedContent | Array | Yes | Array of content blocks (see below) |
tags | Array | No | Tags for categorization |
metadata | Object | No | Additional metadata (e.g. contentPurpose) |
Content Block Types
| Block Type | Description | Key Fields |
|---|---|---|
title | Content title heading | text |
paragraph | Text paragraph (supports inline HTML) | text |
container | Reference to source content | sourceContentObjectId, content |
quoteBlock | Quote from a reference | text |
author | Author attribution | text, participant info |
Text in
publishedContent blocks uses inline HTML for formatting (<strong>, <em>, <ul><li>, <br>), not Markdown.Pagination
All list tools support consistent pagination.Request:{ "page": 1, "pageSize": 50 }
{
"pagination": {
"totalCount": 1000,
"returned": 50,
"hasNext": true,
"isLastPage": false
}
}
| Limit | Value |
|---|---|
| Default page size | 100 |
Max page size — get-people | 500 (external clients) |
Max page size — get-companies | 1000 (external clients) |
Max page size — get-contents | 200 (contents are larger) |
| Max response size | 90 KB |
hasNext: true. Reduce pageSize or use specific fields to avoid truncation.Get Workspace Overview
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": { "name": "get-stats", "arguments": {} },
"id": 1
}
{
"data": {
"tools": {
"get-people": { "total": 1232 },
"get-companies": { "total": 526 },
"get-contents": { "total": 3322 }
},
"rewards": {
"totalRedemptions": 124,
"totalRedeemedAmount": 9300,
"totalRedeemableAmount": 4150
}
}
}
Query Confirmed References
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-people",
"arguments": {
"userPrivileges": "reference",
"page": 1,
"pageSize": 25,
"fields": ["basic", "status"],
"orderBy": "createdAt",
"orderDirection": "DESC",
"context": {
"type": "filters",
"filters": {
"referenceStatus": ["referrer-confirmed", "confirmed"]
}
}
}
},
"id": 2
}
Find References Available for Calls
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-people",
"arguments": {
"userPrivileges": "reference",
"context": {
"type": "filters",
"filters": {
"callAvailabilities": ["100", "6", "3", "1"]
}
}
}
},
"id": 3
}
For “who is available for calls?” always use
callAvailabilities — do not return total references for this query.Search People by Name
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-people",
"arguments": {
"search": "Jane Doe",
"fields": ["basic"]
}
},
"id": 4
}
Search for Prospects
Query all prospects in your workspace:{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-people",
"arguments": {
"userPrivileges": "prospect",
"page": 1,
"pageSize": 50,
"fields": ["basic", "status"]
}
},
"id": 5
}
Search Companies
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-companies",
"arguments": {
"search": "Acme",
"fields": ["basic", "extended"]
}
},
"id": 5
}
Get Content by Multiple Types
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-contents",
"arguments": {
"context": {
"type": "filters",
"filters": {
"types": ["Quote", "extractedText", "Transcript"]
}
}
}
},
"id": 6
}
When searching for quotes, include both
Quote and extractedText types for comprehensive results.Get Full Quote Text (Un-truncated)
By defaultget-contents returns a 100-character preview. When the user wants to read or paste the full quote (LinkedIn post, Slack message, slides), set includeFullContent: true:{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-contents",
"arguments": {
"includeFullContent": true,
"context": {
"type": "filters",
"filters": {
"types": ["Quote", "extractedText"]
}
}
}
},
"id": 7
}
Create a Company and Reference
Step 1: Create the Company{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create-company",
"arguments": {
"companyName": "Acme Corp",
"website": "https://acme.com"
}
},
"id": 8
}
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create-person",
"arguments": {
"email": "jane@acme.com",
"firstName": "Jane",
"lastName": "Doe",
"companyName": "Acme Corp",
"title": "VP of Customer Success",
"linkedInProfile": "https://linkedin.com/in/janedoe"
}
},
"id": 9
}
Content Creation Workflow
Get Content Instructions
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-content-instructions",
"arguments": { "contentType": "CaseStudy" }
},
"id": 10
}
Gather Source Data
Use
get-contents and get-people to collect the reference data and quotes you’ll use.Save the Draft
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "save-draft-content",
"arguments": {
"context": { "conversationId": "conv-uuid-here" },
"messageId": "msg-uuid-here",
"type": "CaseStudy",
"name": "Acme Success Story",
"title": "How Acme Increased Revenue by 40%",
"publishedContent": [
{ "type": "title", "text": "How Acme Increased Revenue by 40%" },
{ "type": "paragraph", "text": "By implementing our platform, Acme Corp achieved a <strong>40% increase</strong> in annual revenue within the first year." },
{ "type": "quoteBlock", "text": "The platform completely transformed our sales process." },
{ "type": "author", "text": "Jane Doe, VP of Customer Success at Acme Corp" }
]
}
},
"id": 11
}
Paginate Through All Results
// Page 1
{ "params": { "name": "get-people", "arguments": { "page": 1, "pageSize": 100 } } }
// Check response: pagination.hasNext === true → fetch next page
{ "params": { "name": "get-people", "arguments": { "page": 2, "pageSize": 100 } } }
// Continue until pagination.isLastPage === true
Using with curl
curl -X POST https://api.deeto.ai/v2/mcp \
-H "Authorization: Bearer dtk_live_your_key_here" \
-H "Content-Type: application/json" \
--compressed \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get-stats","arguments":{}},"id":1}'
Include
--compressed in your curl commands. The server uses gzip compression.Error Response Format
All errors follow the JSON-RPC 2.0 error format:{
"jsonrpc": "2.0",
"error": {
"code": -32001,
"message": "Unauthorized: Bearer token required"
},
"id": null
}
Protocol Errors
These occur at the JSON-RPC level before reaching any tool.| Code | Name | Description |
|---|---|---|
-32600 | Invalid Request | Malformed JSON-RPC request (missing jsonrpc, method, etc.) |
-32601 | Method Not Found | Unknown JSON-RPC method — only initialize, tools/list, tools/call are supported |
-32602 | Invalid Params | Missing required parameters (e.g. no name in tools/call) |
-32603 | Internal Error | Unexpected server-side error |
Authentication Errors
| Code | Message | Cause | Solution |
|---|---|---|---|
-32001 | Unauthorized: Bearer token required | No Authorization header | Add Authorization: Bearer dtk_live_... header |
-32001 | Unauthorized: Invalid API key | Key doesn’t exist or is malformed | Check the key value and dtk_live_ prefix |
-32001 | Unauthorized: API key has been revoked | Key was revoked by an admin | Generate a new API key |
-32001 | Forbidden: tool '<name>' requires '<required>' privilege but your API key/token has '<current>'. Ask a workspace admin to upgrade the privilege of this credential, or use a different credential with sufficient access. | Key privilege too low | Ask a workspace admin to upgrade the key’s privilege, or use a different key |
Tool Errors
Tool-level errors are returned within thecontent field of a successful JSON-RPC response:{
"jsonrpc": "2.0",
"result": {
"content": [{
"type": "text",
"text": "{\"success\": false, \"error\": \"invalid input parameters\", \"details\": \"...\"}"
}]
},
"id": 1
}
Common Tool Errors
| Error | Cause | Solution |
|---|---|---|
invalid input parameters | Input validation failed (Zod schema) | Check the details field for specific validation errors |
Invalid filter value | Enum filter value not recognized | Check response for availableValues to see valid options |
Invalid sourceContentObjectId | Referenced content doesn’t exist | Verify content IDs with get-contents before using in drafts |
Company name already exists | Duplicate company name in workspace | Use a unique name or search for the existing company first |
Email already exists | Duplicate email for a person | Search for the existing contact first |
Best Practices
1. Always checksuccess in tool responsesconst result = JSON.parse(response.result.content[0].text);
if (!result.success) {
console.error('Tool error:', result.error, result.details);
}
pagination.hasNext before requesting the next page.3. Validate filter values first — When filtering by custom fields, query without filters first to discover available values in the response metadata.4. Retry on transient errors — For -32603 (Internal Error), implement exponential backoff retries.5. Handle response size limits — Responses are limited to 90 KB. Use smaller page sizes and iterate through pages for large datasets.Troubleshooting
Getting 401 Unauthorized with a valid key
Getting 401 Unauthorized with a valid key
- Verify the
Authorizationheader format:Bearer dtk_live_... - Ensure there are no extra spaces or line breaks in the key
- Check if the key has been revoked in the Deeto admin console
Tool returns empty results
Tool returns empty results
- Check if filters are too restrictive — try without filters first
- Use
get-statsto verify data exists in the workspace - Confirm you’re using the correct
userPrivilegesvalue (referencevsprospect)
Response is truncated
Response is truncated
- Reduce
pageSizeto get smaller responses - Use specific
fieldsto limit returned data - Check
pagination.hasNextand request the next page
save-draft-content returns error
save-draft-content returns error
- Ensure
publishedContentis provided and non-empty - Call
get-content-instructionsfirst for the correct schema - Verify all
sourceContentObjectIdreferences exist viaget-contents - Check that
nameis at least 3 characters and unique per type in the conversation
Privilege error on a tool call
Privilege error on a tool call
The error message tells you exactly what’s needed:
Forbidden: tool '<name>' requires '<required>' privilege but your API key/token has '<current>'. Ask a workspace Admin to generate a new key with the required privilege level.Compliance & Certifications
Deeto maintains the following certifications. All apply to the MCP Server as part of the Deeto platform.| Certification | Scope |
|---|---|
| SOC 2 Type II | Security, Availability, and Confidentiality trust service criteria |
| ISO/IEC 27001 | Information security management system |
| CSA STAR | Cloud security assurance |
| GDPR | EU data protection and privacy |
| HIPAA | Health information privacy (where applicable) |
Architecture & Data Flow
The Deeto MCP Server runs entirely within Deeto’s infrastructure. There is no third-party intermediary between your AI client and Deeto.AI Client →(① HTTPS + API key)→ AWS API Gateway
↓ ② Authenticate + route
Deeto MCP Server
↓ ③ Query workspace data
Deeto Database
↓ ④ Results
Deeto MCP Server
↓ ⑤ JSON-RPC Response
AI Client ←────────────────────────────────────────
All data returned by the MCP Server is scoped to the workspace associated with the API key. Cross-workspace data access is not possible.
- In transit: TLS 1.2+ encryption
- At rest: AWS RDS encryption, covered under SOC 2 scope
- Keys: Stored as one-way SHA-256 hashes server-side
Access Model
Standard Access
Keys are per-user credentials bound to a specific user identity and workspace. Privilege level is set at creation. Every action is traceable to the key owner. Lifecycle managed by the customer.
Design Partner Program
Deeto provisions a single workspace-level key on behalf of the customer for early onboarding. The key is revoked automatically when the partnership ends. Lifecycle managed by Deeto.
Penetration Testing
Deeto conducts annual penetration tests against its full platform, including the MCP Server, performed by an independent third-party security firm.The latest attestation letter is available under NDA via trust.deeto.ai or by contacting your account manager.Data Retention & Deletion
Connector interaction data follows the same retention policy as the rest of the Deeto platform, covered under the SOC 2 scope. No query-level logs are stored beyond what is part of the conversation record.For specific retention periods or data deletion requests, contact privacy@deeto.ai.Security Contact
For security questionnaires, vulnerability disclosures, or custom assessments:- Email: support@deeto.ai
- Trust Center: trust.deeto.ai