@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.
Files changed (41) hide show
  1. package/README.md +548 -0
  2. package/access/auth.js +289 -0
  3. package/access/oauth.js +1059 -0
  4. package/access/resource-metadata.js +167 -0
  5. package/access/tiers.js +422 -0
  6. package/analytics.js +634 -0
  7. package/api-bridge.js +499 -0
  8. package/governance/money.js +141 -0
  9. package/output-formatter.js +589 -0
  10. package/package.json +68 -0
  11. package/resources.js +246 -0
  12. package/security.js +690 -0
  13. package/server.js +2139 -0
  14. package/server.json +55 -0
  15. package/skills/backlog-triage/SKILL.md +115 -0
  16. package/skills/board-review/SKILL.md +96 -0
  17. package/skills/incident-to-card/SKILL.md +126 -0
  18. package/skills/log-outreach.md +62 -0
  19. package/skills/ship-the-card/SKILL.md +155 -0
  20. package/tool-annotations.js +269 -0
  21. package/tools/billing.js +149 -0
  22. package/tools/email-tools.js +652 -0
  23. package/tools/enterprise-tools.js +651 -0
  24. package/tools/free-search.js +160 -0
  25. package/tools/memory.js +440 -0
  26. package/tools/morning-brief.js +551 -0
  27. package/tools/paper-tools.js +563 -0
  28. package/tools/scheduling.js +322 -0
  29. package/tools/work-board-tools.js +758 -0
  30. package/toolsets/communications.js +276 -0
  31. package/toolsets/crm.js +495 -0
  32. package/toolsets/extensibility.js +1131 -0
  33. package/toolsets/infrastructure.js +757 -0
  34. package/toolsets/intelligence.js +232 -0
  35. package/toolsets/knowledge.js +154 -0
  36. package/toolsets/matrix.js +217 -0
  37. package/toolsets/outreach.js +432 -0
  38. package/toolsets/prospecting.js +314 -0
  39. package/toolsets/revenue/always-loaded.js +341 -0
  40. package/toolsets/revenue/sloan-tools.js +81 -0
  41. 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
+ }