ghostdrive1's picture
Upload folder using huggingface_hub
116524e verified
|
Raw
History Blame Contribute Delete
8.85 kB
# ACE MCP Server
ACE (Agentic Context Engine) provides an optional MCP server that exposes ACE as a tool provider over the [Model Context Protocol](https://modelcontextprotocol.io/). Orchestration frameworks, IDEs (Cursor, Windsurf, Claude Code), and other MCP clients can connect to the server and use ACE skills at runtime.
The integration is fully opt-in. Installing ACE without the `mcp` extra does not pull in the MCP SDK, and attempting to start `ace-mcp` without that extra will fail with an install hint instead of breaking normal ACE imports.
> Need client-specific setup steps? See the [MCP Client Setup](mcp-client-setup.md) guide.
## Installation
```bash
uv add "ace-framework[mcp]"
```
## Running the Server
Start the server using the provided CLI entrypoint:
```bash
ace-mcp
```
By default it communicates over `stdio`, making it ready for integration as a local tool provider in any MCP-compatible client.
Example with a specific model:
```bash
ACE_MCP_DEFAULT_MODEL=bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0 ace-mcp
```
## Configuration
All settings are read from environment variables with the `ACE_MCP_` prefix:
| Variable | Default | Description |
|----------|---------|-------------|
| `ACE_MCP_DEFAULT_MODEL` | `gpt-4o-mini` | LiteLLM model identifier used when creating new sessions. Any [LiteLLM-supported model](https://docs.litellm.ai/docs/providers) works (e.g. `bedrock/...`, `anthropic/...`, `openai/...`). |
| `ACE_MCP_SAFE_MODE` | `false` | When `true`, blocks `ace.learn.sample`, `ace.learn.feedback`, `ace.skillbook.save`, and `ace.skillbook.load`. Read-only tools (`ace.ask`, `ace.skillbook.get`) remain available. |
| `ACE_MCP_ALLOW_SAVE_LOAD` | `true` | When `false`, blocks `ace.skillbook.save` and `ace.skillbook.load` independently of safe mode. |
| `ACE_MCP_MAX_SAMPLES_PER_CALL` | `25` | Maximum number of samples accepted in a single `ace.learn.sample` call. |
| `ACE_MCP_MAX_PROMPT_CHARS` | `100000` | Maximum total characters across question + context fields. |
| `ACE_MCP_SESSION_TTL_SECONDS` | `3600` | Idle time (seconds) before a session is garbage-collected. |
| `ACE_MCP_LEARN_TIMEOUT_SECONDS` | `300` | Maximum seconds for a single `ace.learn.sample` or `ace.learn.feedback` call before returning `ACE_MCP_TIMEOUT`. |
| `ACE_MCP_SKILLBOOK_ROOT` | unset | If set, `ace.skillbook.save` and `ace.skillbook.load` reject paths outside this directory. |
| `ACE_MCP_LOG_LEVEL` | `INFO` | Server log level (`DEBUG`, `INFO`, `WARNING`, `ERROR`). Logs go to stderr. |
## Tools
### `ace.ask`
Ask a question using the current skillbook. Does **not** mutate the skillbook.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `session_id` | string | yes | Session identifier for state isolation. |
| `question` | string | yes | The question to answer. |
| `context` | string | no | Additional context for the question. |
| `session_config` | object | no | Override `model`, `temperature`, `max_tokens` for this session. |
Returns: `answer`, `skill_count`.
### `ace.learn.sample`
Provide sample question/answer pairs for ACE to learn from. Runs the full ACE pipeline (Agent, Evaluate, Reflect, Update, Apply).
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `session_id` | string | yes | Session identifier. |
| `samples` | array | yes | List of `{question, context?, ground_truth?, metadata?}` items (1–25). |
| `epochs` | int | no | Number of learning passes (default: 1, max: 20). |
| `session_config` | object | no | Override model settings. |
Returns: `processed`, `failed`, `skill_count_before`, `skill_count_after`, `new_skill_count`.
Blocked by: `ACE_MCP_SAFE_MODE=true`.
### `ace.learn.feedback`
Provide feedback on a previous answer. If a prior `ace.ask` exists for the session, learns directly from that interaction. Otherwise, builds a trace from the provided fields and learns from it.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `session_id` | string | yes | Session identifier. |
| `question` | string | yes | The original question. |
| `answer` | string | yes | The answer being evaluated. |
| `feedback` | string | yes | Feedback about answer quality. |
| `context` | string | no | Original context. |
| `ground_truth` | string | no | The correct answer. |
| `session_config` | object | no | Override model settings. |
Returns: `learned` (always `true` on success β€” the learning path executed), `skill_count_before`, `skill_count_after`, `new_skill_count`.
Blocked by: `ACE_MCP_SAFE_MODE=true`.
### `ace.skillbook.get`
Retrieve skills and statistics from the active skillbook.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `session_id` | string | yes | Session identifier. |
| `limit` | int | no | Max skills to return (default: 20, max: 200). |
| `include_invalid` | bool | no | Include invalidated skills (default: false). |
Returns: `stats`, `skills[]` (each with `id`, `content`, `topic`, `helpful`, `harmful`, `neutral`).
### `ace.skillbook.save`
Save the session's skillbook to a file on disk.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `session_id` | string | yes | Session identifier. |
| `path` | string | yes | File path to save to. |
Returns: `path` (resolved absolute path), `saved_skill_count`.
Blocked by: `ACE_MCP_SAFE_MODE=true` (`ACE_MCP_FORBIDDEN_IN_SAFE_MODE`) or `ACE_MCP_ALLOW_SAVE_LOAD=false` (`ACE_MCP_SAVE_LOAD_DISABLED`). The path is resolved to a canonical absolute path before validation and file I/O. Must be under `ACE_MCP_SKILLBOOK_ROOT` if configured.
### `ace.skillbook.load`
Load a skillbook from disk into the session, replacing the current one.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `session_id` | string | yes | Session identifier. |
| `path` | string | yes | File path to load from. |
Returns: `path` (resolved absolute path), `skill_count`.
Blocked by: `ACE_MCP_SAFE_MODE=true` (`ACE_MCP_FORBIDDEN_IN_SAFE_MODE`) or `ACE_MCP_ALLOW_SAVE_LOAD=false` (`ACE_MCP_SAVE_LOAD_DISABLED`). The path is resolved to a canonical absolute path before validation and file I/O. Must be under `ACE_MCP_SKILLBOOK_ROOT` if configured.
## Session Model
All state is isolated by `session_id`. Each session holds its own `ACELiteLLM` runner with an independent skillbook. Pass the same `session_id` across calls to persist context within server memory.
Sessions are garbage-collected after `ACE_MCP_SESSION_TTL_SECONDS` of inactivity. Per-session locks ensure concurrent requests to the same session are serialised.
Any tool that accepts `session_config` can override the model, temperature, and max_tokens for that session's runner on first creation. Once a session exists, `session_config` on subsequent calls is used only if it creates a new session.
## Architecture
The MCP server does **not** use custom pipeline steps. It is a thin async layer over `ACELiteLLM`:
```
MCP Client (stdio)
β†’ MCP SDK (handles JSON-RPC framing)
β†’ adapters.py (tool registration, schema generation, error mapping)
β†’ handlers.py (validation, session management, safety guards)
β†’ ACELiteLLM (sync runner β€” bridged via asyncio.to_thread)
β†’ Pipeline (internal β€” handles step execution, async_boundary, background learning)
```
The handlers use `asyncio.to_thread()` to call the sync `ACELiteLLM` methods from the async MCP event loop. This is the standard Python pattern for bridging async callers to sync APIs. The pipeline engine handles all internal async concerns (step-level `to_thread`, `async_boundary` for background learning) transparently.
## Testing with the MCP Inspector
The [MCP Inspector](https://github.com/modelcontextprotocol/inspector) provides a web UI for testing MCP servers interactively:
```bash
npx @modelcontextprotocol/inspector uv run ace-mcp
```
Set `ACE_MCP_DEFAULT_MODEL` in the Inspector's environment variables panel before connecting.
## File Layout
```
ace/integrations/mcp/
__init__.py ← Package marker
server.py ← Server creation and CLI entrypoint
config.py ← MCPServerConfig (pydantic-settings, env vars)
registry.py ← SessionRegistry (session lifecycle, TTL sweep)
handlers.py ← MCPHandlers (validation, safety, delegation to ACELiteLLM)
adapters.py ← MCP SDK glue (tool registration, schema inlining, error mapping)
models.py ← Pydantic request/response models for all six tools
errors.py ← ACEMCPError hierarchy and MCP error mapping
```