apcore MCP/OpenAI工具适配器

apcore-mcp 是一个将现有 apcore 项目无缝转换为 MCP 服务器和 OpenAI 工具提供器的服务适配层,方便开发者在不修改业务代码的情况下,让 AI 与代码以统一方式调用已有模块。

  • by aiperceivable
  • Python
  • 本地部署
  • 3 星标
  • 更新于
在 GitHub 查看 aipartnerup/apcore-mcp

使用说明

apcore-mcp

Build once, invoke by Code or AI. Same modules, same pipeline — an AI caller gets no shortcut.

apcore-mcp turns any apcore-based project into an MCP Server and OpenAI tool provider — with zero code changes to your existing project.

┌──────────────────┐
│  django-apcore   │  ← your existing apcore project (unchanged)
│  nestjs-apcore   │
│  tiptap-apcore   │
│  ...             │
└────────┬─────────┘
         │  extensions directory
         ▼
┌──────────────────┐
│    apcore-mcp    │  ← just install & point to extensions dir
└───┬──────────┬───┘
    │          │
    ▼          ▼
  MCP       OpenAI
 Server      Tools

Installation

=== "🐍 Python"

```bash
pip install apcore-mcp
```
*Requires Python 3.11+. The optional `[markdown]` extra adds Markdown tool descriptions.*

=== "📘 TypeScript"

```bash
npm install apcore-mcp
```
*Requires Node.js 20+, apcore-js >= 0.32.0 and apcore-toolkit >= 0.14.0.*

=== "🦀 Rust"

```bash
cargo add apcore-mcp
```
*Requires Rust 1.75+.*

Quick Start

1. Serve your modules via MCP

=== "🐍 Python"

```python
from apcore_mcp import APCoreMCP

mcp = APCoreMCP("./extensions")

# Launch as MCP Server over stdio
mcp.serve()

# Or with HTTP + Explorer UI
mcp.serve(transport="streamable-http", port=8000, explorer=True)
```

=== "📘 TypeScript"

```typescript
import { serve } from "apcore-mcp";

// Launch MCP server over stdio
await serve("./extensions");

// Launch over Streamable HTTP with Explorer UI
await serve("./extensions", {
  transport: "streamable-http",
  port: 8000,
  explorer: true,
});
```

=== "🦀 Rust"

```rust
use apcore_mcp::APCoreMCP;
use apcore::{Config, Executor};
use std::sync::Arc;

// Rust cannot discover modules from a directory — see the note below.
// Register your modules, then hand the builder an Executor.
let registry = build_my_registry();
let executor = Arc::new(Executor::new(registry, Config::default()));

let mcp = APCoreMCP::builder()
    .backend(executor)
    .build()?;
mcp.serve()?;
```

!!! warning "Rust does not support directory auto-discovery yet"
    `.backend("./extensions")` and the CLI's `--extensions-dir` compile and run, but they build
    an **empty registry** with a warning — apcore's public Rust API has no runtime directory
    discovery. The server starts and serves zero user modules (only the `__apcore_*` meta-tools).
    Use `BackendSource::Registry` — a `Registry`/`Executor` you construct in code — which is
    fully supported. Tracked in the CHANGELOG under *Known limitations (Rust)*; the Python and
    TypeScript paths above are unaffected.

=== "💻 CLI"

```bash
# stdio (default)
apcore-mcp --extensions-dir ./extensions

# Streamable HTTP with Explorer UI
apcore-mcp --extensions-dir ./extensions --transport streamable-http --port 8000 --explorer
```

*The Python and TypeScript CLIs discover modules from the directory. The **Rust** CLI does not —
`--extensions-dir` builds an empty registry there; see the Rust tab above.*

2. Export as OpenAI Tools

=== "🐍 Python"

```python
from apcore_mcp import APCoreMCP

mcp = APCoreMCP("./extensions")
tools = mcp.to_openai_tools()
```

=== "📘 TypeScript"

```typescript
import { APCoreMCP } from "apcore-mcp";

const mcp = new APCoreMCP("./extensions");
const tools = mcp.toOpenaiTools();
```

=== "🦀 Rust"

```rust
use apcore_mcp::APCoreMCP;

let mcp = APCoreMCP::builder()
    .backend(executor)
    .build()?;
//                          embed_annotations, strict
let tools = mcp.to_openai_tools(false,             true)?;
```

!!! note "strict does not default the same way in all three" Written exactly as above, the three tabs produce different OpenAI schemas from the same registry: Python's to_openai_tools() defaults strict=False and emits permissive schemas, while TypeScript's toOpenaiTools() defaults to true and the Rust call passes true positionally — both emit strict ones (additionalProperties: false, every property forced into required, nullable types wrapped, "strict": true on the function). OpenAI's function-calling treats the two shapes differently. Pass strict explicitly in anything portable: mcp.to_openai_tools(strict=True) / mcp.toOpenaiTools({ strict: true }).


Key Features

  • 🚀 Zero Intrusion: Your apcore project needs no code changes, no imports, and no extra dependencies.
  • 🔍 Auto-discovery: Point to an extensions directory, and everything is automatically discovered and exposed (Python and TypeScript; the Rust bridge needs a Registry you build in code — see the Quick Start note).
  • 🌐 Triple Transport: Supports stdio (for local LLMs), Streamable HTTP, and SSE.
  • 🛠️ Tool Explorer: Browser-based UI to browse schemas and test tools interactively (like Swagger UI for MCP).
  • 🛡️ Security: Built-in JWT authentication, PEM key support, and runtime approval elicitation.
  • 🤖 AI Optimized: Enriched metadata (x-when-to-use), error sanitization with AI guidance, and strict mode for OpenAI.
  • 🔄 Dynamic: Reflects module registrations/unregistrations at runtime without restarting.
  • 📄 OpenAPI Backend: Point the bridge at an openapi.json and every operation becomes an MCP tool, proxied over HTTP — no apcore project required (0.20+; the first backend source with full Rust parity).

Architecture

apcore-mcp acts as a protocol-specific adapter on top of the apcore Registry, mapping its metadata to MCP and OpenAI standards:

apcore Concept MCP Mapping OpenAI Mapping
module_id Tool name, verbatim — dots and all (image.resize); overridable via display.mcp.alias name (dash-normalized: image-resize)
description Tool description description
input_schema inputSchema parameters
annotations ToolAnnotations hints Description suffixes (optional)
metadata _meta fields —

MCP input contract

MCP input schemas preserve the module runtime's optionality, nullable values, defaults, references and free-form object behavior across Python, TypeScript and Rust. Arguments pass through unchanged. OpenAI strict schema projection remains specific to OpenAI tool exports. See the factory contract.

Features & Specifications

The project is architected as a set of modular features, each with its own specification to ensure consistency across languages:


Documentation


Implementations

Language Repository Package Status
Python apcore-mcp-python pip install apcore-mcp ✅ Available
TypeScript apcore-mcp-typescript npm install apcore-mcp ✅ Available
Rust apcore-mcp-rust cargo add apcore-mcp ✅ Available
Go apcore-mcp-go — Planned

License

This project is licensed under the Apache License 2.0. See the LICENSE file for details.