@smara/mcp-server 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 ADDED
@@ -0,0 +1,61 @@
1
+ # @smara/mcp-server
2
+
3
+ MCP server for the [Smara Memory API](https://smara.io) — give any AI app persistent, decay-aware memory.
4
+
5
+ ## Quick Start
6
+
7
+ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
8
+
9
+ ```json
10
+ {
11
+ "mcpServers": {
12
+ "smara": {
13
+ "command": "npx",
14
+ "args": ["-y", "@smara/mcp-server"],
15
+ "env": {
16
+ "SMARA_API_KEY": "your-api-key-here"
17
+ }
18
+ }
19
+ }
20
+ }
21
+ ```
22
+
23
+ Get a free API key at [smara.io](https://smara.io) (10,000 memories, no credit card).
24
+
25
+ ## Tools
26
+
27
+ | Tool | Description |
28
+ |------|-------------|
29
+ | `store_memory` | Store a fact about a user with importance scoring |
30
+ | `search_memories` | Semantic search with Ebbinghaus decay-aware ranking |
31
+ | `get_user_context` | Pre-formatted context string for LLM system prompts |
32
+ | `delete_memory` | Delete a specific memory |
33
+ | `get_usage` | Check plan limits and memory count |
34
+
35
+ ## How It Works
36
+
37
+ Smara combines vector similarity search (Voyage AI embeddings) with Ebbinghaus forgetting curves. Memories decay over time — recent, frequently-accessed memories rank higher, just like human recall.
38
+
39
+ ```
40
+ score = similarity × 0.7 + decay_score × 0.3
41
+ ```
42
+
43
+ ## Works With
44
+
45
+ - Claude Desktop
46
+ - Claude Code
47
+ - Cursor
48
+ - Windsurf
49
+ - VS Code (GitHub Copilot)
50
+ - Any MCP-compatible client
51
+
52
+ ## Environment Variables
53
+
54
+ | Variable | Required | Default |
55
+ |----------|----------|---------|
56
+ | `SMARA_API_KEY` | Yes | — |
57
+ | `SMARA_API_URL` | No | `https://api.smara.io` |
58
+
59
+ ## License
60
+
61
+ MIT
@@ -0,0 +1 @@
1
+ export declare function smaraFetch(path: string, options?: RequestInit): Promise<unknown>;
@@ -0,0 +1,19 @@
1
+ const BASE_URL = process.env.SMARA_API_URL || "https://api.smara.io";
2
+ const API_KEY = process.env.SMARA_API_KEY;
3
+ export async function smaraFetch(path, options = {}) {
4
+ if (!API_KEY)
5
+ throw new Error("SMARA_API_KEY environment variable is required. Get a free key at https://smara.io");
6
+ const res = await fetch(`${BASE_URL}${path}`, {
7
+ ...options,
8
+ headers: {
9
+ Authorization: `Bearer ${API_KEY}`,
10
+ "Content-Type": "application/json",
11
+ ...options.headers,
12
+ },
13
+ });
14
+ if (!res.ok) {
15
+ const text = await res.text();
16
+ throw new Error(`Smara API ${res.status}: ${text}`);
17
+ }
18
+ return res.json();
19
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/build/index.js ADDED
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ import { smaraFetch } from "./api-client.js";
6
+ const server = new McpServer({
7
+ name: "smara",
8
+ version: "1.0.0",
9
+ });
10
+ // ── Store a memory ──────────────────────────────────
11
+ server.registerTool("store_memory", {
12
+ title: "Store Memory",
13
+ description: "Store a fact or preference about a user. Smara handles deduplication and contradiction detection automatically. Use importance 0.1-0.3 for trivia, 0.5 for general facts, 0.7-1.0 for critical preferences.",
14
+ inputSchema: {
15
+ user_id: z.string().describe("Unique identifier for the user"),
16
+ fact: z.string().describe("The fact or preference to remember"),
17
+ importance: z
18
+ .number()
19
+ .min(0)
20
+ .max(1)
21
+ .optional()
22
+ .default(0.5)
23
+ .describe("Importance score (0-1). Higher = slower decay."),
24
+ },
25
+ }, async ({ user_id, fact, importance }) => {
26
+ const data = await smaraFetch("/v1/memories", {
27
+ method: "POST",
28
+ body: JSON.stringify({ user_id, fact, importance }),
29
+ });
30
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
31
+ });
32
+ // ── Search memories ─────────────────────────────────
33
+ server.registerTool("search_memories", {
34
+ title: "Search Memories",
35
+ description: "Semantic search across stored memories for a user. Returns results ranked by a blend of vector similarity (70%) and Ebbinghaus decay score (30%). Recent, frequently-accessed memories rank higher.",
36
+ inputSchema: {
37
+ user_id: z.string().describe("User to search memories for"),
38
+ q: z.string().describe("Natural language search query"),
39
+ limit: z
40
+ .number()
41
+ .min(1)
42
+ .max(50)
43
+ .optional()
44
+ .default(5)
45
+ .describe("Max results to return"),
46
+ },
47
+ }, async ({ user_id, q, limit }) => {
48
+ const params = new URLSearchParams({ user_id, q, limit: String(limit) });
49
+ const data = await smaraFetch(`/v1/memories/search?${params}`);
50
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
51
+ });
52
+ // ── Get user context ────────────────────────────────
53
+ server.registerTool("get_user_context", {
54
+ title: "Get User Context",
55
+ description: "Retrieve a pre-formatted context string for a user, ready to inject into an LLM system prompt. Returns the most relevant memories ranked by decay-aware scoring.",
56
+ inputSchema: {
57
+ user_id: z.string().describe("User to get context for"),
58
+ q: z
59
+ .string()
60
+ .optional()
61
+ .describe("Optional query to focus the context on a topic"),
62
+ top_n: z
63
+ .number()
64
+ .min(1)
65
+ .max(20)
66
+ .optional()
67
+ .default(5)
68
+ .describe("Number of top memories to include"),
69
+ },
70
+ }, async ({ user_id, q, top_n }) => {
71
+ const params = new URLSearchParams({ top_n: String(top_n) });
72
+ if (q)
73
+ params.set("q", q);
74
+ const data = await smaraFetch(`/v1/users/${encodeURIComponent(user_id)}/context?${params}`);
75
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
76
+ });
77
+ // ── Delete a memory ─────────────────────────────────
78
+ server.registerTool("delete_memory", {
79
+ title: "Delete Memory",
80
+ description: "Delete a specific memory by ID. Use when a user asks to forget something.",
81
+ inputSchema: {
82
+ id: z.string().describe("The memory ID to delete"),
83
+ },
84
+ }, async ({ id }) => {
85
+ await smaraFetch(`/v1/memories/${encodeURIComponent(id)}`, { method: "DELETE" });
86
+ return { content: [{ type: "text", text: JSON.stringify({ deleted: id }) }] };
87
+ });
88
+ // ── Get usage stats ─────────────────────────────────
89
+ server.registerTool("get_usage", {
90
+ title: "Get Usage",
91
+ description: "Check current memory usage — plan, limits, and how many memories are stored. Useful for monitoring quota.",
92
+ inputSchema: {},
93
+ }, async () => {
94
+ const data = await smaraFetch("/v1/usage");
95
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
96
+ });
97
+ // ── Start ────────────────────────────────────────────
98
+ async function main() {
99
+ const transport = new StdioServerTransport();
100
+ await server.connect(transport);
101
+ console.error("Smara MCP Server running on stdio");
102
+ }
103
+ main().catch((error) => {
104
+ console.error("Fatal error:", error);
105
+ process.exit(1);
106
+ });
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@smara/mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for Smara Memory API — persistent memory for AI agents",
5
+ "type": "module",
6
+ "bin": {
7
+ "smara-mcp": "./build/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc && chmod 755 build/index.js",
11
+ "dev": "tsx src/index.ts"
12
+ },
13
+ "files": [
14
+ "build"
15
+ ],
16
+ "keywords": [
17
+ "mcp",
18
+ "smara",
19
+ "memory",
20
+ "ai-agents",
21
+ "model-context-protocol"
22
+ ],
23
+ "author": "parallelromb",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/smara-io/mcp-server"
28
+ },
29
+ "homepage": "https://smara.io",
30
+ "dependencies": {
31
+ "@modelcontextprotocol/sdk": "^1.29.0",
32
+ "zod": "^3.25.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^22.0.0",
36
+ "tsx": "^4.19.0",
37
+ "typescript": "^5.8.0"
38
+ }
39
+ }