timem-mcp 0.1.0__tar.gz
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.
- timem_mcp-0.1.0/.github/workflows/publish.yml +50 -0
- timem_mcp-0.1.0/.gitignore +77 -0
- timem_mcp-0.1.0/CLAUDE.md +79 -0
- timem_mcp-0.1.0/LICENSE +21 -0
- timem_mcp-0.1.0/PKG-INFO +145 -0
- timem_mcp-0.1.0/README.md +117 -0
- timem_mcp-0.1.0/pyproject.toml +48 -0
- timem_mcp-0.1.0/timem_mcp/__init__.py +10 -0
- timem_mcp-0.1.0/timem_mcp/__main__.py +26 -0
- timem_mcp-0.1.0/timem_mcp/client.py +51 -0
- timem_mcp-0.1.0/timem_mcp/config.py +79 -0
- timem_mcp-0.1.0/timem_mcp/server.py +119 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*" # Auto-trigger when pushing a tag starting with v
|
|
7
|
+
release:
|
|
8
|
+
types: [published]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
id-token: write # For PyPI trusted publishing
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout repository
|
|
20
|
+
uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Python
|
|
23
|
+
uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.11"
|
|
26
|
+
|
|
27
|
+
- name: Install build dependencies
|
|
28
|
+
run: |
|
|
29
|
+
python -m pip install --upgrade pip
|
|
30
|
+
pip install build
|
|
31
|
+
|
|
32
|
+
- name: Clean dist directory before build
|
|
33
|
+
run: |
|
|
34
|
+
# Clean dist directory to ensure only current build files are included
|
|
35
|
+
rm -rf dist/*
|
|
36
|
+
echo "Cleaned dist directory"
|
|
37
|
+
|
|
38
|
+
- name: Build package
|
|
39
|
+
run: |
|
|
40
|
+
python -m build
|
|
41
|
+
|
|
42
|
+
- name: List built packages
|
|
43
|
+
run: |
|
|
44
|
+
echo "Built packages:"
|
|
45
|
+
ls -la dist/
|
|
46
|
+
|
|
47
|
+
- name: Publish to PyPI
|
|
48
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
49
|
+
with:
|
|
50
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
pip-wheel-metadata/
|
|
24
|
+
share/python-wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
MANIFEST
|
|
29
|
+
|
|
30
|
+
# PyInstaller
|
|
31
|
+
*.manifest
|
|
32
|
+
*.spec
|
|
33
|
+
|
|
34
|
+
# Installer logs
|
|
35
|
+
pip-log.txt
|
|
36
|
+
pip-delete-this-directory.txt
|
|
37
|
+
|
|
38
|
+
# Unit test / coverage reports
|
|
39
|
+
htmlcov/
|
|
40
|
+
.tox/
|
|
41
|
+
.nox/
|
|
42
|
+
.coverage
|
|
43
|
+
.coverage.*
|
|
44
|
+
.cache
|
|
45
|
+
nosetests.xml
|
|
46
|
+
coverage.xml
|
|
47
|
+
*.cover
|
|
48
|
+
*.py,cover
|
|
49
|
+
.hypothesis/
|
|
50
|
+
.pytest_cache/
|
|
51
|
+
|
|
52
|
+
# Translations
|
|
53
|
+
*.mo
|
|
54
|
+
*.pot
|
|
55
|
+
|
|
56
|
+
# Environments
|
|
57
|
+
.env
|
|
58
|
+
.venv
|
|
59
|
+
env/
|
|
60
|
+
venv/
|
|
61
|
+
ENV/
|
|
62
|
+
env.bak/
|
|
63
|
+
venv.bak/
|
|
64
|
+
|
|
65
|
+
# IDEs
|
|
66
|
+
.vscode/
|
|
67
|
+
.idea/
|
|
68
|
+
*.swp
|
|
69
|
+
*.swo
|
|
70
|
+
*~
|
|
71
|
+
|
|
72
|
+
# OS
|
|
73
|
+
.DS_Store
|
|
74
|
+
Thumbs.db
|
|
75
|
+
|
|
76
|
+
# MCP Inspector
|
|
77
|
+
.mcp-inspector/
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
TiMEM MCP Server is a Model Context Protocol (MCP) server that provides memory management tools for TiMEM Engine. The project is built using FastMCP framework and communicates with MCP clients like Claude Desktop via stdio transport.
|
|
8
|
+
|
|
9
|
+
## Common Commands
|
|
10
|
+
|
|
11
|
+
### Development
|
|
12
|
+
```bash
|
|
13
|
+
# Install in development mode
|
|
14
|
+
pip install -e .
|
|
15
|
+
|
|
16
|
+
# Run directly (using Python module)
|
|
17
|
+
python -m timem_mcp
|
|
18
|
+
|
|
19
|
+
# Run using uvx (recommended)
|
|
20
|
+
uvx timem-mcp
|
|
21
|
+
|
|
22
|
+
# Debug with MCP Inspector
|
|
23
|
+
npx @modelcontextprotocol/inspector uvx --from <your-local-path> timem-mcp -e TiMEM_API_HOST=http://localhost:8000 -e TiMEM_API_KEY=<your-api-key> -e TiMEM_USER_ID=<your-user-id>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Build and Publish
|
|
27
|
+
```bash
|
|
28
|
+
# Build package
|
|
29
|
+
python -m build
|
|
30
|
+
|
|
31
|
+
# Check package
|
|
32
|
+
twine check dist/*
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Configuration Requirements
|
|
36
|
+
The following environment variables are required to run the service:
|
|
37
|
+
- `TiMEM_API_KEY`: TiMEM Engine API Key
|
|
38
|
+
- `TiMEM_USER_ID`: User ID
|
|
39
|
+
|
|
40
|
+
Optional configuration:
|
|
41
|
+
- `TiMEM_API_HOST`: API endpoint (defaults to `https://api.timem.cloud`)
|
|
42
|
+
|
|
43
|
+
## Code Architecture
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
timem_mcp/
|
|
47
|
+
├── __init__.py # Exports main entry point and version
|
|
48
|
+
├── __main__.py # Entry: validate config → start MCP server (stdio)
|
|
49
|
+
├── server.py # MCP core: FastMCP instance + 3 tool definitions
|
|
50
|
+
├── client.py # HTTP client: async calls to TiMEM Engine API
|
|
51
|
+
└── config.py # Config management: env var reading (supports TiMEM_*/TIMEM_* prefixes)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Execution Flow
|
|
55
|
+
1. `__main__.py:main()` → validate env vars → call `mcp.run(transport="stdio")`
|
|
56
|
+
2. `server.py` uses FastMCP decorators to register tool functions
|
|
57
|
+
3. Tool functions call TiMEM Engine API via `client.py:call_api()`
|
|
58
|
+
4. API paths retrieved from `config.py:Config` constants: `MEMORY_CREATE_PATH` / `MEMORY_QUERY_PATH`
|
|
59
|
+
5. Configuration retrieved from `config.py` getters: `get_api_key()` / `get_user_id()` / `get_base_url()`
|
|
60
|
+
|
|
61
|
+
### MCP Tools
|
|
62
|
+
| Tool | Purpose | API Endpoint |
|
|
63
|
+
|------|---------|--------------|
|
|
64
|
+
| `create_memory` | Create memories from conversation history | POST `/api/v1/memory/` |
|
|
65
|
+
| `search_memories` | Search stored memories | GET `/api/v1/memory/query` |
|
|
66
|
+
| `ready` | Health check | - |
|
|
67
|
+
|
|
68
|
+
## Key Design Points
|
|
69
|
+
|
|
70
|
+
- **Environment variable prefix priority**: `TiMEM_*` > `TIMEM_*` (implemented in `config.py:Config._get_env`)
|
|
71
|
+
- **API authentication**: Via `X-API-Key` request header (`client.py:call_api`)
|
|
72
|
+
- **Response format handling**: `create_memory` wraps list responses as `{"status": "success", "memories": [...], "count": n}` (`server.py:70-72`)
|
|
73
|
+
- **Transport mode**: MCP standard requires `stdio` transport, not HTTP
|
|
74
|
+
|
|
75
|
+
## Notes
|
|
76
|
+
|
|
77
|
+
- Project uses `pyproject.toml` for dependency management, not `requirements.txt`
|
|
78
|
+
- `timem_mcp_service.py` in root directory is a legacy file; use code in `timem_mcp/` package
|
|
79
|
+
- PyPI package name is `timem-mcp`, but Python import name is `timem_mcp` (follows Python convention)
|
timem_mcp-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 TiMEM Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
timem_mcp-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: timem-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: TiMEM MCP Server - Model Context Protocol server for TiMEM Engine
|
|
5
|
+
Project-URL: Homepage, https://github.com/timem-cloud/timem-mcp
|
|
6
|
+
Project-URL: Documentation, https://docs.timem.cloud
|
|
7
|
+
Project-URL: Repository, https://github.com/timem-cloud/timem-mcp
|
|
8
|
+
Author-email: TiMEM Team <contact@timem.cloud>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai,mcp,memory,model-context-protocol,timem
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Requires-Dist: fastmcp>=0.1.0
|
|
23
|
+
Requires-Dist: httpx>=0.24.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# TiMEM MCP Server
|
|
30
|
+
|
|
31
|
+
[Model Context Protocol](https://modelcontextprotocol.io) server for [TiMEM Engine](https://timem.cloud), providing memory management tools for AI applications.
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install timem-mcp
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
### With Claude Desktop
|
|
42
|
+
|
|
43
|
+
Add to your Claude Desktop configuration (`claude_desktop_config.json`):
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"mcpServers": {
|
|
48
|
+
"TiMEM-MCP": {
|
|
49
|
+
"command": "uvx",
|
|
50
|
+
"args": ["timem-mcp"],
|
|
51
|
+
"env": {
|
|
52
|
+
"TiMEM_API_KEY": "<your-api-key>",
|
|
53
|
+
"TiMEM_API_HOST": "https://api.timem.cloud", // optional
|
|
54
|
+
"TiMEM_USER_ID": "<your-user-id>"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Direct Execution
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Using uvx (recommended)
|
|
65
|
+
uvx timem-mcp
|
|
66
|
+
|
|
67
|
+
# Or using Python module
|
|
68
|
+
python -m timem_mcp
|
|
69
|
+
|
|
70
|
+
# Or directly if installed
|
|
71
|
+
timem-mcp
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Configuration
|
|
75
|
+
|
|
76
|
+
The server reads configuration from environment variables:
|
|
77
|
+
|
|
78
|
+
| Variable | Required | Default | Description |
|
|
79
|
+
|----------|----------|---------|-------------|
|
|
80
|
+
| `TiMEM_API_KEY` | Yes | - | Your TiMEM Engine API key |
|
|
81
|
+
| `TiMEM_USER_ID` | Yes | - | User identifier for memory operations |
|
|
82
|
+
| `TiMEM_API_HOST` | No | `https://api.timem.cloud` | TiMEM Engine API endpoint |
|
|
83
|
+
|
|
84
|
+
**Note:** Both `TiMEM_*` and `TIMEM_*` prefixes are supported. `TiMEM_*` takes priority.
|
|
85
|
+
|
|
86
|
+
## Available Tools
|
|
87
|
+
|
|
88
|
+
### `create_memory`
|
|
89
|
+
|
|
90
|
+
Create memories from conversation history.
|
|
91
|
+
|
|
92
|
+
**Parameters:**
|
|
93
|
+
- `messages` (required): List of message objects with `role` and `content`
|
|
94
|
+
- `session_id` (required): Session identifier
|
|
95
|
+
- `expert_id` (optional): Expert ID, default "default"
|
|
96
|
+
- `domain` (optional): Business domain, default "general"
|
|
97
|
+
|
|
98
|
+
**Example:**
|
|
99
|
+
```python
|
|
100
|
+
await create_memory(
|
|
101
|
+
messages=[
|
|
102
|
+
{"role": "user", "content": "My name is John"},
|
|
103
|
+
{"role": "assistant", "content": "Hello John!"}
|
|
104
|
+
],
|
|
105
|
+
session_id="sess_123",
|
|
106
|
+
expert_id="default",
|
|
107
|
+
domain="general"
|
|
108
|
+
)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### `search_memories`
|
|
112
|
+
|
|
113
|
+
Search and retrieve stored memories.
|
|
114
|
+
|
|
115
|
+
**Parameters:**
|
|
116
|
+
- `query` (optional): Search keywords
|
|
117
|
+
- `layer` (optional): Memory layer (L1-L5)
|
|
118
|
+
- `domain` (optional): Business domain
|
|
119
|
+
- `limit` (optional): Result count, default 10
|
|
120
|
+
|
|
121
|
+
**Example:**
|
|
122
|
+
```python
|
|
123
|
+
await search_memories(query="John", layer="L1", limit=5)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `ready`
|
|
127
|
+
|
|
128
|
+
Health check endpoint to verify the server is running.
|
|
129
|
+
|
|
130
|
+
## Development
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Install in development mode
|
|
134
|
+
pip install -e .
|
|
135
|
+
|
|
136
|
+
# Run tests
|
|
137
|
+
pytest
|
|
138
|
+
|
|
139
|
+
# Run with MCP Inspector
|
|
140
|
+
npx @modelcontextprotocol/inspector uvx --from <your-local-path> timem-mcp -e TiMEM_API_HOST=http://localhost:8000 -e TiMEM_API_KEY=<your-api-key> -e TiMEM_USER_ID=<your-user-id>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
MIT License - see LICENSE file for details.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# TiMEM MCP Server
|
|
2
|
+
|
|
3
|
+
[Model Context Protocol](https://modelcontextprotocol.io) server for [TiMEM Engine](https://timem.cloud), providing memory management tools for AI applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install timem-mcp
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### With Claude Desktop
|
|
14
|
+
|
|
15
|
+
Add to your Claude Desktop configuration (`claude_desktop_config.json`):
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"mcpServers": {
|
|
20
|
+
"TiMEM-MCP": {
|
|
21
|
+
"command": "uvx",
|
|
22
|
+
"args": ["timem-mcp"],
|
|
23
|
+
"env": {
|
|
24
|
+
"TiMEM_API_KEY": "<your-api-key>",
|
|
25
|
+
"TiMEM_API_HOST": "https://api.timem.cloud", // optional
|
|
26
|
+
"TiMEM_USER_ID": "<your-user-id>"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Direct Execution
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Using uvx (recommended)
|
|
37
|
+
uvx timem-mcp
|
|
38
|
+
|
|
39
|
+
# Or using Python module
|
|
40
|
+
python -m timem_mcp
|
|
41
|
+
|
|
42
|
+
# Or directly if installed
|
|
43
|
+
timem-mcp
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Configuration
|
|
47
|
+
|
|
48
|
+
The server reads configuration from environment variables:
|
|
49
|
+
|
|
50
|
+
| Variable | Required | Default | Description |
|
|
51
|
+
|----------|----------|---------|-------------|
|
|
52
|
+
| `TiMEM_API_KEY` | Yes | - | Your TiMEM Engine API key |
|
|
53
|
+
| `TiMEM_USER_ID` | Yes | - | User identifier for memory operations |
|
|
54
|
+
| `TiMEM_API_HOST` | No | `https://api.timem.cloud` | TiMEM Engine API endpoint |
|
|
55
|
+
|
|
56
|
+
**Note:** Both `TiMEM_*` and `TIMEM_*` prefixes are supported. `TiMEM_*` takes priority.
|
|
57
|
+
|
|
58
|
+
## Available Tools
|
|
59
|
+
|
|
60
|
+
### `create_memory`
|
|
61
|
+
|
|
62
|
+
Create memories from conversation history.
|
|
63
|
+
|
|
64
|
+
**Parameters:**
|
|
65
|
+
- `messages` (required): List of message objects with `role` and `content`
|
|
66
|
+
- `session_id` (required): Session identifier
|
|
67
|
+
- `expert_id` (optional): Expert ID, default "default"
|
|
68
|
+
- `domain` (optional): Business domain, default "general"
|
|
69
|
+
|
|
70
|
+
**Example:**
|
|
71
|
+
```python
|
|
72
|
+
await create_memory(
|
|
73
|
+
messages=[
|
|
74
|
+
{"role": "user", "content": "My name is John"},
|
|
75
|
+
{"role": "assistant", "content": "Hello John!"}
|
|
76
|
+
],
|
|
77
|
+
session_id="sess_123",
|
|
78
|
+
expert_id="default",
|
|
79
|
+
domain="general"
|
|
80
|
+
)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### `search_memories`
|
|
84
|
+
|
|
85
|
+
Search and retrieve stored memories.
|
|
86
|
+
|
|
87
|
+
**Parameters:**
|
|
88
|
+
- `query` (optional): Search keywords
|
|
89
|
+
- `layer` (optional): Memory layer (L1-L5)
|
|
90
|
+
- `domain` (optional): Business domain
|
|
91
|
+
- `limit` (optional): Result count, default 10
|
|
92
|
+
|
|
93
|
+
**Example:**
|
|
94
|
+
```python
|
|
95
|
+
await search_memories(query="John", layer="L1", limit=5)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### `ready`
|
|
99
|
+
|
|
100
|
+
Health check endpoint to verify the server is running.
|
|
101
|
+
|
|
102
|
+
## Development
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Install in development mode
|
|
106
|
+
pip install -e .
|
|
107
|
+
|
|
108
|
+
# Run tests
|
|
109
|
+
pytest
|
|
110
|
+
|
|
111
|
+
# Run with MCP Inspector
|
|
112
|
+
npx @modelcontextprotocol/inspector uvx --from <your-local-path> timem-mcp -e TiMEM_API_HOST=http://localhost:8000 -e TiMEM_API_KEY=<your-api-key> -e TiMEM_USER_ID=<your-user-id>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT License - see LICENSE file for details.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "timem-mcp"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "TiMEM MCP Server - Model Context Protocol server for TiMEM Engine"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.8"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "TiMEM Team", email = "contact@timem.cloud" }
|
|
10
|
+
]
|
|
11
|
+
keywords = ["mcp", "timem", "memory", "ai", "model-context-protocol"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 4 - Beta",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.8",
|
|
18
|
+
"Programming Language :: Python :: 3.9",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
dependencies = [
|
|
25
|
+
"fastmcp>=0.1.0",
|
|
26
|
+
"httpx>=0.24.0",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
dev = [
|
|
31
|
+
"pytest>=7.0.0",
|
|
32
|
+
"pytest-asyncio>=0.21.0",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.scripts]
|
|
36
|
+
timem-mcp = "timem_mcp:main"
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://github.com/timem-cloud/timem-mcp"
|
|
40
|
+
Documentation = "https://docs.timem.cloud"
|
|
41
|
+
Repository = "https://github.com/timem-cloud/timem-mcp"
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["hatchling"]
|
|
45
|
+
build-backend = "hatchling.build"
|
|
46
|
+
|
|
47
|
+
[tool.hatch.build.targets.wheel]
|
|
48
|
+
packages = ["timem_mcp"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""TiMEM MCP 服务入口点
|
|
2
|
+
|
|
3
|
+
支持通过 `uvx timem-mcp` 或 `python -m timem_mcp` 启动服务
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from .config import validate
|
|
9
|
+
from .server import mcp
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main() -> None:
|
|
13
|
+
"""主入口函数"""
|
|
14
|
+
try:
|
|
15
|
+
# 验证必需的环境变量
|
|
16
|
+
validate()
|
|
17
|
+
except ValueError as e:
|
|
18
|
+
print(f"配置错误: {e}", file=sys.stderr)
|
|
19
|
+
sys.exit(1)
|
|
20
|
+
|
|
21
|
+
# 使用 stdio 传输方式启动服务(MCP 标准要求)
|
|
22
|
+
mcp.run(transport="stdio")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
if __name__ == "__main__":
|
|
26
|
+
main()
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""TiMEM API 客户端模块
|
|
2
|
+
|
|
3
|
+
提供异步 HTTP 客户端用于调用 TiMEM Engine API
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Any, Dict, Optional
|
|
7
|
+
|
|
8
|
+
import httpx
|
|
9
|
+
|
|
10
|
+
from .config import get_base_url
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
async def call_api(
|
|
14
|
+
method: str,
|
|
15
|
+
path: str,
|
|
16
|
+
api_key: str,
|
|
17
|
+
json_data: Optional[Dict] = None,
|
|
18
|
+
params: Optional[Dict] = None,
|
|
19
|
+
timeout: float = 30.0,
|
|
20
|
+
) -> Dict[str, Any]:
|
|
21
|
+
"""通用 API 调用函数
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
method: HTTP 方法 (GET/POST)
|
|
25
|
+
path: API 路径
|
|
26
|
+
api_key: API Key
|
|
27
|
+
json_data: JSON 请求体 (POST 时使用)
|
|
28
|
+
params: URL 查询参数 (GET 时使用)
|
|
29
|
+
timeout: 超时时间
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
API 响应数据
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
httpx.HTTPStatusError: API 请求失败
|
|
36
|
+
"""
|
|
37
|
+
url = f"{get_base_url()}{path}"
|
|
38
|
+
headers = {"X-API-Key": api_key}
|
|
39
|
+
|
|
40
|
+
async with httpx.AsyncClient() as client:
|
|
41
|
+
if method.upper() == "POST":
|
|
42
|
+
response = await client.post(
|
|
43
|
+
url, json=json_data, headers=headers, timeout=timeout
|
|
44
|
+
)
|
|
45
|
+
else:
|
|
46
|
+
response = await client.get(
|
|
47
|
+
url, params=params, headers=headers, timeout=timeout
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
response.raise_for_status()
|
|
51
|
+
return response.json()
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""TiMEM MCP 配置模块
|
|
2
|
+
|
|
3
|
+
从环境变量读取配置,支持 TiMEM_* 和 TIMEM_* 两种前缀。
|
|
4
|
+
优先级: TiMEM_* > TIMEM_*
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Config:
|
|
12
|
+
"""配置管理类"""
|
|
13
|
+
|
|
14
|
+
# 环境变量前缀
|
|
15
|
+
PREFIXES = ["TiMEM_", "TIMEM_"]
|
|
16
|
+
|
|
17
|
+
# API paths
|
|
18
|
+
MEMORY_CREATE_PATH = "/api/v1/memory/"
|
|
19
|
+
MEMORY_QUERY_PATH = "/api/v1/memory/query"
|
|
20
|
+
|
|
21
|
+
# Default API base URL
|
|
22
|
+
DEFAULT_BASE_URL = "https://api.timem.cloud"
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def _get_env(cls, key: str) -> Optional[str]:
|
|
26
|
+
"""获取环境变量,支持多种前缀
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
key: 配置键名(不含前缀)
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
环境变量值,如果不存在则返回 None
|
|
33
|
+
"""
|
|
34
|
+
# 按优先级尝试不同前缀
|
|
35
|
+
for prefix in cls.PREFIXES:
|
|
36
|
+
value = os.getenv(f"{prefix}{key}")
|
|
37
|
+
if value:
|
|
38
|
+
return value
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
@classmethod
|
|
42
|
+
def get_api_key(cls) -> str:
|
|
43
|
+
"""获取 API Key(必需)"""
|
|
44
|
+
api_key = cls._get_env("API_KEY")
|
|
45
|
+
if not api_key:
|
|
46
|
+
raise ValueError(
|
|
47
|
+
"TiMEM_API_KEY 环境变量未设置。"
|
|
48
|
+
"请在环境变量中设置 TiMEM_API_KEY 或 TIMEM_API_KEY"
|
|
49
|
+
)
|
|
50
|
+
return api_key
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def get_user_id(cls) -> str:
|
|
54
|
+
"""获取用户 ID(必需)"""
|
|
55
|
+
user_id = cls._get_env("USER_ID")
|
|
56
|
+
if not user_id:
|
|
57
|
+
raise ValueError(
|
|
58
|
+
"TiMEM_USER_ID 环境变量未设置。"
|
|
59
|
+
"请在环境变量中设置 TiMEM_USER_ID 或 TIMEM_USER_ID"
|
|
60
|
+
)
|
|
61
|
+
return user_id
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
def get_base_url(cls) -> str:
|
|
65
|
+
"""获取 API 基础地址"""
|
|
66
|
+
return cls._get_env("API_HOST") or cls.DEFAULT_BASE_URL
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
def validate(cls) -> None:
|
|
70
|
+
"""验证必需的配置项"""
|
|
71
|
+
cls.get_api_key()
|
|
72
|
+
cls.get_user_id()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# 导出便捷访问函数
|
|
76
|
+
get_api_key = Config.get_api_key
|
|
77
|
+
get_user_id = Config.get_user_id
|
|
78
|
+
get_base_url = Config.get_base_url
|
|
79
|
+
validate = Config.validate
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""TiMEM MCP 服务模块
|
|
2
|
+
|
|
3
|
+
提供 create_memory 和 search_memories 两个核心工具
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Any, Dict, List, Optional
|
|
7
|
+
|
|
8
|
+
from fastmcp import FastMCP
|
|
9
|
+
|
|
10
|
+
from .client import call_api
|
|
11
|
+
from .config import get_api_key, get_user_id, Config
|
|
12
|
+
|
|
13
|
+
__version__ = "0.1.0"
|
|
14
|
+
|
|
15
|
+
# 创建 MCP 服务器实例
|
|
16
|
+
mcp = FastMCP("TiMEM")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@mcp.tool()
|
|
20
|
+
async def create_memory(
|
|
21
|
+
messages: List[Dict[str, str]],
|
|
22
|
+
session_id: str,
|
|
23
|
+
expert_id: str = "default",
|
|
24
|
+
domain: str = "general",
|
|
25
|
+
) -> Dict[str, Any]:
|
|
26
|
+
"""从对话历史创建记忆
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
messages: 对话消息列表,格式 [{"role": "user|assistant", "content": "..."}]
|
|
30
|
+
session_id: 会话ID
|
|
31
|
+
expert_id: 专家ID (默认 "default")
|
|
32
|
+
domain: 业务域 (默认 "general")
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
创建的结果,包含 status 和 memories/data 字段
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
result = await create_memory(
|
|
39
|
+
messages=[
|
|
40
|
+
{"role": "user", "content": "你好,我叫张三"},
|
|
41
|
+
{"role": "assistant", "content": "你好张三,很高兴认识你"}
|
|
42
|
+
],
|
|
43
|
+
session_id="sess_456",
|
|
44
|
+
expert_id="agent_001",
|
|
45
|
+
domain="customer_service"
|
|
46
|
+
)
|
|
47
|
+
"""
|
|
48
|
+
# 从环境变量读取 API Key 和用户 ID
|
|
49
|
+
api_key = get_api_key()
|
|
50
|
+
user_id = get_user_id()
|
|
51
|
+
|
|
52
|
+
request_body = {
|
|
53
|
+
"user_id": user_id,
|
|
54
|
+
"expert_id": expert_id,
|
|
55
|
+
"session_id": session_id,
|
|
56
|
+
"messages": [
|
|
57
|
+
{"role": msg.get("role"), "content": msg.get("content")} for msg in messages
|
|
58
|
+
],
|
|
59
|
+
"format": "compact",
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if domain:
|
|
63
|
+
request_body["domain"] = domain
|
|
64
|
+
|
|
65
|
+
response = await call_api(
|
|
66
|
+
"POST", Config.MEMORY_CREATE_PATH, api_key, json_data=request_body, timeout=60.0
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# 主服务返回的是列表格式,需要包装成字典
|
|
70
|
+
if isinstance(response, list):
|
|
71
|
+
return {"status": "success", "memories": response, "count": len(response)}
|
|
72
|
+
return response
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@mcp.tool()
|
|
76
|
+
async def search_memories(
|
|
77
|
+
query: Optional[str] = None,
|
|
78
|
+
layer: Optional[str] = None,
|
|
79
|
+
domain: Optional[str] = None,
|
|
80
|
+
limit: int = 10,
|
|
81
|
+
) -> Dict[str, Any]:
|
|
82
|
+
"""搜索/查询记忆
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
query: 搜索关键词
|
|
86
|
+
layer: 记忆层级 L1-L5
|
|
87
|
+
domain: 业务域
|
|
88
|
+
limit: 返回数量 (默认 10)
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
搜索结果列表
|
|
92
|
+
|
|
93
|
+
Example:
|
|
94
|
+
result = await search_memories(
|
|
95
|
+
query="张三",
|
|
96
|
+
layer="L1",
|
|
97
|
+
limit=5
|
|
98
|
+
)
|
|
99
|
+
"""
|
|
100
|
+
# 从环境变量读取 API Key 和用户 ID
|
|
101
|
+
api_key = get_api_key()
|
|
102
|
+
user_id = get_user_id()
|
|
103
|
+
|
|
104
|
+
params = {"user_id": user_id, "size": limit}
|
|
105
|
+
|
|
106
|
+
if query:
|
|
107
|
+
params["keywords"] = [query]
|
|
108
|
+
if layer:
|
|
109
|
+
params["layer"] = layer
|
|
110
|
+
if domain:
|
|
111
|
+
params["domain"] = domain
|
|
112
|
+
|
|
113
|
+
return await call_api("GET", Config.MEMORY_QUERY_PATH, api_key, params=params)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@mcp.tool()
|
|
117
|
+
def ready() -> str:
|
|
118
|
+
"""确认服务已就绪"""
|
|
119
|
+
return "ready"
|