@ebowwa/claudecodehistory 1.1.1 → 1.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/example/README.md +79 -0
- package/example/package.json +37 -0
- package/example/src/index.ts +233 -0
- package/example/tsconfig.json +16 -0
- package/package.json +2 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Claude Code History MCP Server - Example
|
|
2
|
+
|
|
3
|
+
This is an example MCP server that demonstrates how to use the `@ebowwa/claudecodehistory` library to create an MCP server for Claude Code conversation history.
|
|
4
|
+
|
|
5
|
+
## About This Example
|
|
6
|
+
|
|
7
|
+
This example shows how to:
|
|
8
|
+
- Use the `ClaudeCodeHistoryService` class from the library
|
|
9
|
+
- Wrap it in an MCP server using the Model Context Protocol SDK
|
|
10
|
+
- Expose the service's functionality as MCP tools
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
This MCP server provides **4 powerful tools** for exploring your Claude Code conversation history:
|
|
15
|
+
|
|
16
|
+
### 1. `list_projects`
|
|
17
|
+
Discover all projects with Claude Code conversation history.
|
|
18
|
+
|
|
19
|
+
### 2. `list_sessions`
|
|
20
|
+
List conversation sessions for exploration and filtering.
|
|
21
|
+
|
|
22
|
+
### 3. `get_conversation_history`
|
|
23
|
+
Retrieve paginated conversation history with smart filtering.
|
|
24
|
+
|
|
25
|
+
### 4. `search_conversations`
|
|
26
|
+
Search across all conversation content by keywords.
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# From the example directory
|
|
32
|
+
cd example
|
|
33
|
+
|
|
34
|
+
# Install dependencies (uses bun)
|
|
35
|
+
bun install
|
|
36
|
+
|
|
37
|
+
# Run directly
|
|
38
|
+
bun src/index.ts
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage with MCP Clients
|
|
42
|
+
|
|
43
|
+
Add the following configuration to your MCP client (e.g., Claude Desktop):
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"mcpServers": {
|
|
48
|
+
"claude-code-history": {
|
|
49
|
+
"command": "bun",
|
|
50
|
+
"args": ["/path/to/claude-code-history-mcp/example/src/index.ts"]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Development
|
|
57
|
+
|
|
58
|
+
- **Runtime:** `bun` (no build step required)
|
|
59
|
+
- **TypeScript:** Executed directly via bun
|
|
60
|
+
- **Hot reload:** `bun --hot src/index.ts`
|
|
61
|
+
|
|
62
|
+
## Library Dependency
|
|
63
|
+
|
|
64
|
+
This example imports from `@ebowwa/claudecodehistory` (the parent package):
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { ClaudeCodeHistoryService } from '@ebowwa/claudecodehistory';
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The service provides all the core functionality for accessing Claude Code history:
|
|
71
|
+
|
|
72
|
+
- `getConversationHistory()` - Get paginated conversation history
|
|
73
|
+
- `searchConversations()` - Search by content
|
|
74
|
+
- `listProjects()` - List all projects
|
|
75
|
+
- `listSessions()` - List sessions with filters
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
MIT
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "claude-code-history-mcp-example",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"claude-code-history-mcp": "src/index.ts"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "bun --hot src/index.ts",
|
|
12
|
+
"start": "bun src/index.ts",
|
|
13
|
+
"typecheck": "tsc --noEmit"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@ebowwa/claudecodehistory": "file:..",
|
|
17
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/node": "^24.0.4",
|
|
21
|
+
"typescript": "^5.8.3"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"claude-code",
|
|
25
|
+
"mcp",
|
|
26
|
+
"history",
|
|
27
|
+
"conversation",
|
|
28
|
+
"example",
|
|
29
|
+
"typescript",
|
|
30
|
+
"bun"
|
|
31
|
+
],
|
|
32
|
+
"author": "ebowwa",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18.0.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
5
|
+
import {
|
|
6
|
+
CallToolRequestSchema,
|
|
7
|
+
ListToolsRequestSchema,
|
|
8
|
+
Tool
|
|
9
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
10
|
+
import { ClaudeCodeHistoryService } from '@ebowwa/claudecodehistory';
|
|
11
|
+
|
|
12
|
+
const server = new Server(
|
|
13
|
+
{
|
|
14
|
+
name: 'claude-code-history-mcp',
|
|
15
|
+
version: '1.1.0',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
capabilities: {
|
|
19
|
+
tools: {},
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const historyService = new ClaudeCodeHistoryService();
|
|
25
|
+
|
|
26
|
+
// Helper function to create response
|
|
27
|
+
const createResponse = (data: any) => ({ // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
28
|
+
content: [{
|
|
29
|
+
type: 'text',
|
|
30
|
+
text: JSON.stringify(data),
|
|
31
|
+
}],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Define available tools (ordered by recommended workflow)
|
|
35
|
+
const tools: Tool[] = [
|
|
36
|
+
{
|
|
37
|
+
name: 'list_projects',
|
|
38
|
+
description: 'List all projects with Claude Code conversation history (start here to explore available data)',
|
|
39
|
+
inputSchema: {
|
|
40
|
+
type: 'object',
|
|
41
|
+
properties: {},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'list_sessions',
|
|
46
|
+
description: 'List conversation sessions for a project or date range (use after list_projects to find specific sessions)',
|
|
47
|
+
inputSchema: {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
projectPath: {
|
|
51
|
+
type: 'string',
|
|
52
|
+
description: 'Filter by specific project path (optional)',
|
|
53
|
+
},
|
|
54
|
+
startDate: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
description: 'Start date in ISO format (optional)',
|
|
57
|
+
},
|
|
58
|
+
endDate: {
|
|
59
|
+
type: 'string',
|
|
60
|
+
description: 'End date in ISO format (optional)',
|
|
61
|
+
},
|
|
62
|
+
timezone: {
|
|
63
|
+
type: 'string',
|
|
64
|
+
description: 'Timezone for date filtering (e.g., "Asia/Tokyo", "UTC"). Defaults to system timezone.',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'get_conversation_history',
|
|
71
|
+
description: 'Get paginated conversation history (use after exploring with list_projects/list_sessions for targeted data)',
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: {
|
|
75
|
+
sessionId: {
|
|
76
|
+
type: 'string',
|
|
77
|
+
description: 'Specific session ID to get history for (optional)',
|
|
78
|
+
},
|
|
79
|
+
startDate: {
|
|
80
|
+
type: 'string',
|
|
81
|
+
description: 'Start date in ISO format (optional)',
|
|
82
|
+
},
|
|
83
|
+
endDate: {
|
|
84
|
+
type: 'string',
|
|
85
|
+
description: 'End date in ISO format (optional)',
|
|
86
|
+
},
|
|
87
|
+
limit: {
|
|
88
|
+
type: 'number',
|
|
89
|
+
description: 'Maximum number of conversations to return (default: 20)',
|
|
90
|
+
default: 20,
|
|
91
|
+
},
|
|
92
|
+
offset: {
|
|
93
|
+
type: 'number',
|
|
94
|
+
description: 'Number of conversations to skip for pagination (default: 0)',
|
|
95
|
+
default: 0,
|
|
96
|
+
},
|
|
97
|
+
messageTypes: {
|
|
98
|
+
type: 'array',
|
|
99
|
+
items: {
|
|
100
|
+
type: 'string',
|
|
101
|
+
enum: ['user', 'assistant', 'system', 'result']
|
|
102
|
+
},
|
|
103
|
+
description: 'Filter by specific message types. Defaults to ["user"] to reduce data volume. Use ["user", "assistant"] to include Claude responses.',
|
|
104
|
+
default: ['user']
|
|
105
|
+
},
|
|
106
|
+
timezone: {
|
|
107
|
+
type: 'string',
|
|
108
|
+
description: 'Timezone for date filtering (e.g., "Asia/Tokyo", "UTC"). Defaults to system timezone.',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'search_conversations',
|
|
115
|
+
description: 'Search through conversation history by content (useful for finding specific topics across all conversations)',
|
|
116
|
+
inputSchema: {
|
|
117
|
+
type: 'object',
|
|
118
|
+
properties: {
|
|
119
|
+
query: {
|
|
120
|
+
type: 'string',
|
|
121
|
+
description: 'Search query to find in conversation content',
|
|
122
|
+
},
|
|
123
|
+
limit: {
|
|
124
|
+
type: 'number',
|
|
125
|
+
description: 'Maximum number of results to return (default: 30)',
|
|
126
|
+
default: 30,
|
|
127
|
+
},
|
|
128
|
+
projectPath: {
|
|
129
|
+
type: 'string',
|
|
130
|
+
description: 'Filter by specific project path (optional)',
|
|
131
|
+
},
|
|
132
|
+
startDate: {
|
|
133
|
+
type: 'string',
|
|
134
|
+
description: 'Start date in ISO format (optional)',
|
|
135
|
+
},
|
|
136
|
+
endDate: {
|
|
137
|
+
type: 'string',
|
|
138
|
+
description: 'End date in ISO format (optional)',
|
|
139
|
+
},
|
|
140
|
+
timezone: {
|
|
141
|
+
type: 'string',
|
|
142
|
+
description: 'Timezone for date filtering (e.g., "Asia/Tokyo", "UTC"). Defaults to system timezone.',
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
required: ['query'],
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
// Handle list tools request
|
|
151
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
152
|
+
return { tools };
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Handle tool calls
|
|
156
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
157
|
+
const { name, arguments: args } = request.params;
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
switch (name) {
|
|
161
|
+
case 'get_conversation_history': {
|
|
162
|
+
const history = await historyService.getConversationHistory({
|
|
163
|
+
sessionId: args?.sessionId as string,
|
|
164
|
+
startDate: args?.startDate as string,
|
|
165
|
+
endDate: args?.endDate as string,
|
|
166
|
+
limit: (args?.limit as number) || 20,
|
|
167
|
+
offset: (args?.offset as number) || 0,
|
|
168
|
+
messageTypes: args?.messageTypes as ('user' | 'assistant' | 'system' | 'result')[],
|
|
169
|
+
timezone: args?.timezone as string,
|
|
170
|
+
});
|
|
171
|
+
return createResponse(history);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
case 'search_conversations': {
|
|
175
|
+
const query = args?.query as string;
|
|
176
|
+
if (!query) {
|
|
177
|
+
throw new Error('Search query is required');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const results = await historyService.searchConversations(
|
|
181
|
+
query,
|
|
182
|
+
{
|
|
183
|
+
limit: (args?.limit as number) || 30,
|
|
184
|
+
projectPath: args?.projectPath as string,
|
|
185
|
+
startDate: args?.startDate as string,
|
|
186
|
+
endDate: args?.endDate as string,
|
|
187
|
+
timezone: args?.timezone as string,
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
return createResponse(results);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
case 'list_projects': {
|
|
194
|
+
const projects = await historyService.listProjects();
|
|
195
|
+
return createResponse(projects);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
case 'list_sessions': {
|
|
199
|
+
const sessions = await historyService.listSessions({
|
|
200
|
+
projectPath: args?.projectPath as string,
|
|
201
|
+
startDate: args?.startDate as string,
|
|
202
|
+
endDate: args?.endDate as string,
|
|
203
|
+
timezone: args?.timezone as string,
|
|
204
|
+
});
|
|
205
|
+
return createResponse(sessions);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
default:
|
|
209
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
210
|
+
}
|
|
211
|
+
} catch (error) {
|
|
212
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
213
|
+
return {
|
|
214
|
+
content: [{
|
|
215
|
+
type: 'text',
|
|
216
|
+
text: `Error: ${errorMessage}`,
|
|
217
|
+
}],
|
|
218
|
+
isError: true,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Start the server
|
|
224
|
+
async function main() {
|
|
225
|
+
const transport = new StdioServerTransport();
|
|
226
|
+
await server.connect(transport);
|
|
227
|
+
console.error('Claude Code History MCP Server started');
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
main().catch((error) => {
|
|
231
|
+
console.error('Failed to start server:', error);
|
|
232
|
+
process.exit(1);
|
|
233
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"noEmit": true
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*"],
|
|
15
|
+
"exclude": ["node_modules", "dist"]
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ebowwa/claudecodehistory",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "TypeScript library for accessing and analyzing Claude Code conversation history",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"dist/",
|
|
16
|
+
"example/",
|
|
16
17
|
"README.md",
|
|
17
18
|
"LICENSE"
|
|
18
19
|
],
|