@adrata/adrata-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +548 -0
- package/access/auth.js +289 -0
- package/access/oauth.js +1059 -0
- package/access/resource-metadata.js +167 -0
- package/access/tiers.js +422 -0
- package/analytics.js +634 -0
- package/api-bridge.js +499 -0
- package/governance/money.js +141 -0
- package/output-formatter.js +589 -0
- package/package.json +68 -0
- package/resources.js +246 -0
- package/security.js +690 -0
- package/server.js +2139 -0
- package/server.json +55 -0
- package/skills/backlog-triage/SKILL.md +115 -0
- package/skills/board-review/SKILL.md +96 -0
- package/skills/incident-to-card/SKILL.md +126 -0
- package/skills/log-outreach.md +62 -0
- package/skills/ship-the-card/SKILL.md +155 -0
- package/tool-annotations.js +269 -0
- package/tools/billing.js +149 -0
- package/tools/email-tools.js +652 -0
- package/tools/enterprise-tools.js +651 -0
- package/tools/free-search.js +160 -0
- package/tools/memory.js +440 -0
- package/tools/morning-brief.js +551 -0
- package/tools/paper-tools.js +563 -0
- package/tools/scheduling.js +322 -0
- package/tools/work-board-tools.js +758 -0
- package/toolsets/communications.js +276 -0
- package/toolsets/crm.js +495 -0
- package/toolsets/extensibility.js +1131 -0
- package/toolsets/infrastructure.js +757 -0
- package/toolsets/intelligence.js +232 -0
- package/toolsets/knowledge.js +154 -0
- package/toolsets/matrix.js +217 -0
- package/toolsets/outreach.js +432 -0
- package/toolsets/prospecting.js +314 -0
- package/toolsets/revenue/always-loaded.js +341 -0
- package/toolsets/revenue/sloan-tools.js +81 -0
- package/transport-http.js +505 -0
package/resources.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Additional MCP resources for Adrata MCP Server.
|
|
3
|
+
*
|
|
4
|
+
* Resources (passive context injection — Claude reads these automatically):
|
|
5
|
+
* - adrata://recent-research — last 10 companies/people researched
|
|
6
|
+
* - adrata://guide/sales-playbook — contextual sales methodology tips
|
|
7
|
+
* - adrata://workspace — workspace summary (enterprise only)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
11
|
+
import { homedir } from 'node:os';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Local memory helpers (mirrors memory.js for free tier)
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
const ADRATA_DIR = join(homedir(), '.adrata');
|
|
19
|
+
const MEMORIES_FILE = join(ADRATA_DIR, 'memories.json');
|
|
20
|
+
|
|
21
|
+
function readLocalMemories() {
|
|
22
|
+
if (!existsSync(MEMORIES_FILE)) return [];
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(readFileSync(MEMORIES_FILE, 'utf-8'));
|
|
25
|
+
} catch {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Resource: adrata://recent-research
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
function buildRecentResearchHandler(apiFn, auth) {
|
|
35
|
+
return async () => {
|
|
36
|
+
let text;
|
|
37
|
+
|
|
38
|
+
if (auth.authenticated) {
|
|
39
|
+
try {
|
|
40
|
+
const data = await apiFn('GET', '/api/v1/mcp/memories', {
|
|
41
|
+
params: { limit: 10, memory_type: 'deal_context' },
|
|
42
|
+
});
|
|
43
|
+
const items = data?.data || data || [];
|
|
44
|
+
if (items.length === 0) {
|
|
45
|
+
text = 'No recent research activity found. Use search_companies or search_people to start researching.';
|
|
46
|
+
} else {
|
|
47
|
+
const lines = items.map((item, i) => {
|
|
48
|
+
const tags = (item.tags || []).join(', ');
|
|
49
|
+
const date = item.created_at ? new Date(item.created_at).toLocaleDateString() : 'unknown';
|
|
50
|
+
return `${i + 1}. [${date}] ${item.content}${tags ? ` (tags: ${tags})` : ''}`;
|
|
51
|
+
});
|
|
52
|
+
text = `Recent Research Activity (last ${items.length} items):\n\n${lines.join('\n')}`;
|
|
53
|
+
}
|
|
54
|
+
} catch {
|
|
55
|
+
text = 'Recent research data unavailable (API error). User is authenticated but the memory API could not be reached.';
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
// Free tier: pull from local memories
|
|
59
|
+
const memories = readLocalMemories();
|
|
60
|
+
const recent = memories
|
|
61
|
+
.filter(m => m.is_latest && !m.forgotten_at)
|
|
62
|
+
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at))
|
|
63
|
+
.slice(0, 10);
|
|
64
|
+
|
|
65
|
+
if (recent.length === 0) {
|
|
66
|
+
text = 'No recent research activity found. Use search_companies or search_people to start researching.';
|
|
67
|
+
} else {
|
|
68
|
+
const lines = recent.map((item, i) => {
|
|
69
|
+
const tags = (item.tags || []).join(', ');
|
|
70
|
+
const date = item.created_at ? new Date(item.created_at).toLocaleDateString() : 'unknown';
|
|
71
|
+
return `${i + 1}. [${date}] ${item.content}${tags ? ` (tags: ${tags})` : ''}`;
|
|
72
|
+
});
|
|
73
|
+
text = `Recent Research Activity (last ${recent.length} items, local storage):\n\n${lines.join('\n')}\n\nNote: Upgrade to Pro for server-side memory with full research history and vector search.`;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
contents: [{
|
|
79
|
+
uri: 'adrata://recent-research',
|
|
80
|
+
mimeType: 'text/plain',
|
|
81
|
+
text,
|
|
82
|
+
}],
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Resource: adrata://guide/sales-playbook
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
const SALES_PLAYBOOK_TEXT = `Adrata Sales Playbook — Contextual Methodology Tips
|
|
92
|
+
|
|
93
|
+
1. DISCOVERY FRAMEWORK
|
|
94
|
+
- Lead with business pain, not product features
|
|
95
|
+
- Ask "What happens if you do nothing?" to quantify urgency
|
|
96
|
+
- Map the buying committee early: Champion, Decision Maker, Budget Holder, Influencer
|
|
97
|
+
- Identify the compelling event driving timeline
|
|
98
|
+
|
|
99
|
+
2. QUALIFICATION (MEDDPIC)
|
|
100
|
+
- Metrics: What measurable outcomes does the buyer need?
|
|
101
|
+
- Economic Buyer: Who signs the check? Have you confirmed?
|
|
102
|
+
- Decision Criteria: What are they evaluating against?
|
|
103
|
+
- Decision Process: Steps, timeline, approvals required?
|
|
104
|
+
- Identify Pain: What specific pain does this solve?
|
|
105
|
+
- Champion: Who inside the org is selling for you?
|
|
106
|
+
|
|
107
|
+
3. MULTI-THREADING STRATEGY
|
|
108
|
+
- Never rely on a single contact (single-threaded = high risk)
|
|
109
|
+
- Map 3-5 stakeholders per deal minimum
|
|
110
|
+
- Use buyer group tracking to monitor engagement across contacts
|
|
111
|
+
- Each stakeholder needs a personalized value message
|
|
112
|
+
|
|
113
|
+
4. PIPELINE HYGIENE
|
|
114
|
+
- Update opportunity stage after every meaningful interaction
|
|
115
|
+
- Log Next Moves with specific dates and owners
|
|
116
|
+
- Stale deals (>30 days no activity) need re-engagement or disqualification
|
|
117
|
+
- Use close dates that reflect reality, not optimism
|
|
118
|
+
|
|
119
|
+
5. CLOSING TACTICS
|
|
120
|
+
- Confirm decision criteria are met before asking for the close
|
|
121
|
+
- Address procurement/legal/security early, not at the end
|
|
122
|
+
- Create mutual action plans with shared timelines
|
|
123
|
+
- Follow up on proposals within 48 hours
|
|
124
|
+
|
|
125
|
+
6. POST-SALE EXPANSION
|
|
126
|
+
- Schedule a 30/60/90 day check-in cadence
|
|
127
|
+
- Document success metrics achieved for future case studies
|
|
128
|
+
- Ask for introductions to other departments or teams
|
|
129
|
+
- Monitor usage signals for upsell timing
|
|
130
|
+
|
|
131
|
+
Tips for using Adrata effectively:
|
|
132
|
+
- Use search_companies before outreach to check existing intelligence
|
|
133
|
+
- Save key deal insights with save_memory for cross-session context
|
|
134
|
+
- Track buyer group composition to ensure multi-threading
|
|
135
|
+
- Set actions with due dates to maintain pipeline velocity`;
|
|
136
|
+
|
|
137
|
+
function buildSalesPlaybookHandler() {
|
|
138
|
+
return async () => ({
|
|
139
|
+
contents: [{
|
|
140
|
+
uri: 'adrata://guide/sales-playbook',
|
|
141
|
+
mimeType: 'text/plain',
|
|
142
|
+
text: SALES_PLAYBOOK_TEXT,
|
|
143
|
+
}],
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
// Resource: adrata://workspace
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
|
|
151
|
+
function buildWorkspaceHandler(apiFn, auth) {
|
|
152
|
+
return async () => {
|
|
153
|
+
let text;
|
|
154
|
+
|
|
155
|
+
if (auth.tier === 'enterprise' && auth.authenticated) {
|
|
156
|
+
try {
|
|
157
|
+
const data = await apiFn('GET', '/api/v1/capabilities/workspace');
|
|
158
|
+
const ws = data?.data || data;
|
|
159
|
+
|
|
160
|
+
const lines = [
|
|
161
|
+
'Workspace Summary',
|
|
162
|
+
'=================',
|
|
163
|
+
'',
|
|
164
|
+
`Name: ${ws.name || 'Unknown'}`,
|
|
165
|
+
`Plan: ${ws.plan || 'enterprise'}`,
|
|
166
|
+
`Members: ${ws.member_count ?? 'unknown'}`,
|
|
167
|
+
`Created: ${ws.created_at ? new Date(ws.created_at).toLocaleDateString() : 'unknown'}`,
|
|
168
|
+
'',
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
if (ws.stats) {
|
|
172
|
+
lines.push('Workspace Statistics:');
|
|
173
|
+
if (ws.stats.companies != null) lines.push(`- Companies: ${ws.stats.companies}`);
|
|
174
|
+
if (ws.stats.people != null) lines.push(`- People: ${ws.stats.people}`);
|
|
175
|
+
if (ws.stats.opportunities != null) lines.push(`- Opportunities: ${ws.stats.opportunities}`);
|
|
176
|
+
if (ws.stats.actions != null) lines.push(`- Actions: ${ws.stats.actions}`);
|
|
177
|
+
if (ws.stats.active_users != null) lines.push(`- Active users: ${ws.stats.active_users}`);
|
|
178
|
+
lines.push('');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (ws.capabilities) {
|
|
182
|
+
lines.push('Enabled Capabilities:');
|
|
183
|
+
for (const [cap, enabled] of Object.entries(ws.capabilities)) {
|
|
184
|
+
lines.push(`- ${cap}: ${enabled ? 'enabled' : 'disabled'}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
text = lines.join('\n');
|
|
189
|
+
} catch {
|
|
190
|
+
text = 'Workspace data unavailable (API error). Your enterprise connection is active but the workspace API could not be reached.';
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
text = `Workspace Summary — Enterprise Feature
|
|
194
|
+
|
|
195
|
+
The workspace resource provides a summary of your organization's Adrata workspace including team size, data volume, and enabled capabilities.
|
|
196
|
+
|
|
197
|
+
This resource requires an enterprise connection. To access it:
|
|
198
|
+
1. Run the connect_workspace tool to link your Adrata workspace via OAuth 2.0
|
|
199
|
+
2. Ensure your workspace has an enterprise plan
|
|
200
|
+
|
|
201
|
+
Current tier: ${auth.tier}
|
|
202
|
+
Status: ${auth.authenticated ? 'Authenticated but not enterprise tier' : 'Not connected'}
|
|
203
|
+
|
|
204
|
+
Use connect_workspace to get started.`;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
contents: [{
|
|
209
|
+
uri: 'adrata://workspace',
|
|
210
|
+
mimeType: 'text/plain',
|
|
211
|
+
text,
|
|
212
|
+
}],
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
// Registration
|
|
219
|
+
// ---------------------------------------------------------------------------
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Register all additional MCP resources on the server.
|
|
223
|
+
*
|
|
224
|
+
* @param {object} server - McpServer instance
|
|
225
|
+
* @param {Function} apiFn - The api() helper for server calls
|
|
226
|
+
* @param {object} auth - AUTH context { tier, token, apiKey, authenticated }
|
|
227
|
+
*/
|
|
228
|
+
export function registerResources(server, apiFn, auth) {
|
|
229
|
+
server.resource(
|
|
230
|
+
'recent-research',
|
|
231
|
+
'adrata://recent-research',
|
|
232
|
+
buildRecentResearchHandler(apiFn, auth)
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
server.resource(
|
|
236
|
+
'sales-playbook',
|
|
237
|
+
'adrata://guide/sales-playbook',
|
|
238
|
+
buildSalesPlaybookHandler()
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
server.resource(
|
|
242
|
+
'workspace-summary',
|
|
243
|
+
'adrata://workspace',
|
|
244
|
+
buildWorkspaceHandler(apiFn, auth)
|
|
245
|
+
);
|
|
246
|
+
}
|