Skip to content
Back to skills

Api Server Mcp

ASecurity

REST API server and MCP protocol integration

  • 9,365 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 3, 2026
developmentrustgoapibackend

Works with

  • cli
  • api
  • mcp

Security analysis

A100/100

Scanned October 3, 2026

npx -y skills add xberg-io/xberg --skill api-server-mcp --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Api Server Mcp?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Api Server Mcp
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/xberg-io-api-server-mcp/badge)](https://www.skillsdirectory.com/skills/xberg-io-api-server-mcp)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
description: "REST API server and MCP protocol integration"
name: api-server-mcp
priority: critical
---

# API Server & MCP Protocol

**Axum server for document extraction, plus the rmcp Model Context Protocol surface**

Locations: `crates/xberg/src/api/` (`router.rs`, `handlers.rs`, `startup.rs`, `types.rs`,
`error.rs`, `jobs.rs`) and `crates/xberg/src/mcp/`. There is no `api/server.rs`.

## REST routes

Registered in `api/router.rs`, all on one `Router`:

| Route | Handler |
| --- | --- |
| `POST /extract` | `extract_handler` — multipart files, URL fields, or JSON; builds `ExtractInput` |
| `POST /extract-async` | `extract_async_handler` — queues a job |
| `GET`/`DELETE /jobs/{job_id}` | `job_status_handler` / `cancel_job_handler` |
| `POST /detect` | `detect_handler` |
| `GET /formats` | `formats_handler` |
| `GET /health` | `health_handler` |
| `GET /info`, `GET /version` | `info_handler`, `version_handler` |
| `GET /cache/stats` | `cache_stats_handler` |
| `DELETE /cache/clear` | `cache_clear_handler` |
| `GET /cache/manifest`, `POST /cache/warm` | `cache_manifest_handler`, `cache_warm_handler` |
| `PUT /process`, `POST /v1/convert/file` | `openweb_external_handler`, `openweb_docling_handler` (`api/openweb.rs`) |
| `GET /openapi.json` | `openapi_schema_handler` (feature `api`) |
| `GET /metrics` | `metrics_handler` (feature `prometheus`) |

There is **no** `POST /extract-url` (URL ingestion is a field on `ExtractInput` passed to
`/extract`) and **no** `POST /batch` (batch is `/extract-async` + `/jobs/{job_id}`).

Middleware, in order: `DefaultBodyLimit::max(limits.max_request_body_bytes)` +
`RequestBodyLimitLayer` (default 100 MB), CORS, request-id, compression, catch-panic,
sensitive-header stripping, tracing. CORS is built explicitly as
`CorsLayer::new().allow_origin(Any).allow_methods(Any).allow_headers(Any)` and warns loudly;
restrict it with `XBERG_CORS_ORIGINS`.

## Caching

`crates/xberg/src/cache/` — `GenericCache` is a **filesystem-backed** store with LRU-style
eviction, not an in-memory map. Keys are BLAKE3 content hashes (`blake3_hash_bytes` /
`blake3_hash_file`, `cache/utilities.rs`). Eviction is bounded by `max_age_days`,
`max_cache_size_mb` and `min_free_space_mb` — there is no entry-count limit.

## Error handling

`ApiError` is a **struct**, not an enum: `{ status: StatusCode, body: ErrorResponse }`
(`api/error.rs`). Status comes from the constructor, not a variant:

- `validation()` → 400, `unprocessable()` → 422, `internal()` → 500, `bad_gateway()` → 502
- `From<XbergError>` picks one via `error.api_status_category()`
  (`Validation` / `Unprocessable` / `Internal`)

There is no 404, 413 or 503 path with a named variant. Do not `match` on `ApiError`.

## MCP

`crates/xberg/src/mcp/`. Transport is a single nested rmcp streamable-HTTP service —
`Router::new().nest_service("/mcp", http_service)` — **not** a set of `/mcp/*` REST paths.
Tools, resources and prompts are JSON-RPC methods on it. Stdio transport serves the same
router over stdin/stdout.

### Tools (9)

`extract`, `extract_batch`, `detect_mime_type`, `list_formats`, `cache_stats`, `cache_clear`,
`get_version`, `cache_manifest`, `cache_warm`. The set is pinned by
`test_all_tools_are_registered` in `mcp/server.rs`. There is no `get_capabilities`.

`extract`, `extract_batch` and `cache_warm` are task-eligible (`TASK_ELIGIBLE_TOOLS`,
`mcp/server.rs`).

### Resources

`mcp/resources.rs`: `xberg://formats`, `xberg://models`, `xberg://languages/ocr`, plus
`xberg://presets/embeddings` behind `#[cfg(feature = "embeddings")]`.

### Prompts (3)

`mcp/prompts.rs`: `extract_document`, `extract_with_ocr`, `semantic_search`.

## Environment variables

There is no `.env.example`. Server-side vars are read in `core/server_config/env.rs`:

- `XBERG_HOST`, `XBERG_PORT` (defaults `127.0.0.1:8000`)
- `XBERG_MAX_REQUEST_BODY_BYTES`, `XBERG_MAX_MULTIPART_FIELD_BYTES` (both default 100 MB)
- `XBERG_CORS_ORIGINS` (comma-separated)

Extraction-side vars are documented on `ExtractionConfig::apply_env_overrides`
(`core/config/extraction/env.rs`) — `XBERG_OCR_BACKEND`, `XBERG_OCR_LANGUAGE`,
`XBERG_CHUNKING_MAX_CHARS`, `XBERG_CACHE_ENABLED`, `XBERG_LLM_*`, and others. Read that doc
comment rather than guessing a name.

## Critical Rules

### REST

1. **Validate uploads** — MIME type, size, magic bytes; never trust the filename.
2. **Size limits are configurable** — always read `limits.max_request_body_bytes`, never hardcode.
3. **Errors must be actionable** — include the operation and a remediation hint in `ErrorResponse`.
4. **CORS is permissive by default** — production deployments must set `XBERG_CORS_ORIGINS`.
5. **Long work goes to `/extract-async`** — do not block a request thread on a multi-minute extraction.

### MCP

1. **Register a new tool in `mcp/server.rs` and extend `test_all_tools_are_registered`** — the test is the contract.
2. **Feature-gate resources the same way `xberg://presets/embeddings` is** — a missing feature must not break
   `resources/list`.
3. **Resources are static** — no network or filesystem scans in a resource handler.
4. **Tools need timeouts** — a hung tool blocks the agent.

## Related Skills

- **extraction-pipeline-patterns** — the core extraction the handlers and tools call
- **chunking-embeddings** — optional chunking/embedding parameters
- **config-loading-precedence** — server-mode precedence and env overrides

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…