fathom-mcp 2.0.1 → 2.2.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/index.js +67 -4
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Connects to any Fathom instance (self-hosted or cloud). Discovers
|
|
6
6
|
* available tools from GET /v1/tools, filtered by the token's scopes.
|
|
7
|
+
* Exposes the identity crystal as an MCP resource.
|
|
7
8
|
*
|
|
8
9
|
* Environment:
|
|
9
10
|
* FATHOM_API_URL — base URL (default: http://localhost:8201)
|
|
@@ -16,7 +17,12 @@
|
|
|
16
17
|
|
|
17
18
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
18
19
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
19
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
CallToolRequestSchema,
|
|
22
|
+
ListToolsRequestSchema,
|
|
23
|
+
ListResourcesRequestSchema,
|
|
24
|
+
ReadResourceRequestSchema,
|
|
25
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
20
26
|
|
|
21
27
|
const API_URL = (process.env.FATHOM_API_URL || "http://localhost:8201").replace(/\/$/, "");
|
|
22
28
|
const API_KEY = process.env.FATHOM_API_KEY || "";
|
|
@@ -113,15 +119,31 @@ async function main() {
|
|
|
113
119
|
process.exit(1);
|
|
114
120
|
}
|
|
115
121
|
|
|
116
|
-
// Build lookup
|
|
117
122
|
const toolMap = {};
|
|
118
123
|
for (const t of tools) toolMap[t.name] = t;
|
|
119
124
|
|
|
120
125
|
const server = new Server(
|
|
121
|
-
{ name: "Fathom", version: "
|
|
122
|
-
{
|
|
126
|
+
{ name: "Fathom", version: "2.1.0" },
|
|
127
|
+
{
|
|
128
|
+
capabilities: { tools: {}, resources: {} },
|
|
129
|
+
instructions: [
|
|
130
|
+
"You have a memory lake. Fathom is how you remember.",
|
|
131
|
+
"",
|
|
132
|
+
"BEFORE answering any question, call search_lake with a descriptive query.",
|
|
133
|
+
"One search is rarely enough — if results mention something unfamiliar, search for that too.",
|
|
134
|
+
"Search like a researcher: direct query, then broader category, then follow threads.",
|
|
135
|
+
"",
|
|
136
|
+
"When you learn something new, make a decision, or notice a pattern, call write_delta to save it.",
|
|
137
|
+
"One idea per delta. Tag consistently. Future you will search for this.",
|
|
138
|
+
"",
|
|
139
|
+
"Read the fathom://crystal resource at the start of every conversation — it tells you who you are.",
|
|
140
|
+
"",
|
|
141
|
+
"These are YOUR memories. Say 'I remember' not 'the search results show.'",
|
|
142
|
+
].join("\n"),
|
|
143
|
+
},
|
|
123
144
|
);
|
|
124
145
|
|
|
146
|
+
// Tools — dynamic from /v1/tools
|
|
125
147
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
126
148
|
tools: tools.map(t => ({
|
|
127
149
|
name: t.name,
|
|
@@ -144,6 +166,47 @@ async function main() {
|
|
|
144
166
|
}
|
|
145
167
|
});
|
|
146
168
|
|
|
169
|
+
// Resources — identity crystal
|
|
170
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
171
|
+
resources: [
|
|
172
|
+
{
|
|
173
|
+
uri: "fathom://crystal",
|
|
174
|
+
name: "Identity Crystal",
|
|
175
|
+
description: "Fathom's identity — a first-person synthesis of who this mind is. Read this at the start of every conversation for persistent context.",
|
|
176
|
+
mimeType: "text/plain",
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
}));
|
|
180
|
+
|
|
181
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
182
|
+
const { uri } = request.params;
|
|
183
|
+
if (uri === "fathom://crystal") {
|
|
184
|
+
try {
|
|
185
|
+
const r = await fetch(`${API_URL}/v1/crystal`, { headers: authHeaders(false) });
|
|
186
|
+
if (r.ok) {
|
|
187
|
+
const data = await r.json();
|
|
188
|
+
const text = data.text || "No crystal generated yet.";
|
|
189
|
+
const created = data.created_at || "unknown";
|
|
190
|
+
return {
|
|
191
|
+
contents: [{
|
|
192
|
+
uri,
|
|
193
|
+
mimeType: "text/plain",
|
|
194
|
+
text: `Identity crystal (crystallized ${created}):\n\n${text}`,
|
|
195
|
+
}],
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
} catch {}
|
|
199
|
+
return {
|
|
200
|
+
contents: [{
|
|
201
|
+
uri,
|
|
202
|
+
mimeType: "text/plain",
|
|
203
|
+
text: "No identity crystal available. Generate one from the Fathom dashboard.",
|
|
204
|
+
}],
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
208
|
+
});
|
|
209
|
+
|
|
147
210
|
const transport = new StdioServerTransport();
|
|
148
211
|
await server.connect(transport);
|
|
149
212
|
}
|