@faq-app/agent-operation
v1.0.0
Published
Public MCP server for FAQ backend answer operations
Readme
@faq-app/agent-operation
Public MCP server package for FAQ backend operations.
This package lets MCP-capable clients (Claude Desktop, Cursor, VS Code Copilot) fetch questions and post answers through your FAQ backend using:
- MCP token (
FAQ_MCP_TOKEN) - dynamic client-key route (
/api/mcp/c/<clientKey>)
1. What this package provides
Package metadata (package.json):
- Name:
@faq-app/agent-operation - Version:
1.0.0 - Module type: ESM
- Bin entry:
faq-app-agent-operation(src/cli.mjs)
MCP tools exposed:
list_questions_for_answeringget_question_detailspost_answerbackend_health_check
All tool outputs are returned as text content containing pretty JSON.
2. Runtime requirements
- Node.js runtime with
fetchsupport (Node 18+ recommended). - Reachable backend API.
- Valid MCP token and client key issued by your backend.
3. Environment variables
Required:
FAQ_MCP_TOKEN
Base URL source (one of the following):
FAQ_MCP_API_BASE_URL(preferred)- fallback:
BACKEND_URL
Optional:
FAQ_MCP_CLIENT_KEY(used to compose URL if base does not already include/c/<clientKey>)FAQ_MCP_TIMEOUT_MS(request timeout in ms, default30000)
Production safety:
- In
NODE_ENV=production, MCP base URL must usehttps://unless target host is loopback (localhost,127.0.0.1,::1).
URL normalization behavior (from code)
The package normalizes base URL with normalizeApiBase(rawUrl, clientKey):
- If URL already contains
/api/mcp/c/-> used as-is. - If URL contains
/api/mcpbut no/c/-> appends/c/<clientKey>when key exists. - If URL ends with
/api-> converts to/api/mcpor/api/mcp/c/<clientKey>. - Otherwise -> appends
/api/mcpor/api/mcp/c/<clientKey>.
Validation enforces MCP operations base path:
- Base URL must include
/api/mcp/c/<clientKey> - Token must be present
4. Required backend API contract
This package expects these backend routes:
GET /api/mcp/c/:clientKey/questionsGET /api/mcp/c/:clientKey/questions/:idPOST /api/mcp/c/:clientKey/answers
Token lifecycle endpoints (backend admin/JWT side):
POST /api/mcp/token/rotateGET /api/mcp/token/statusDELETE /api/mcp/token
Credential model expected by this package/backend:
- One active token per shop
- One active client key per shop
- Rotation invalidates previous token+key immediately
5. Tool input schemas and behavior
list_questions_for_answering
Inputs:
answerState:"unanswered" | "answered" | "all"(defaultunanswered)page: integer >= 1 (default1)limit: integer 1..100 (default20)scanPages: integer 1..10 (default1)status: optional stringsearch: optional stringsortBy:"newest" | "oldest" | "popular"(defaultnewest)
Backend call:
GET /questionswith mapped query params
get_question_details
Inputs:
questionId: string, required- strict format:
^[A-Za-z0-9_-]{6,128}$
- strict format:
Backend call:
GET /questions/:questionId(URL-encoded by client)
post_answer
Inputs:
questionId: string, required- strict format:
^[A-Za-z0-9_-]{6,128}$
- strict format:
answerText: string (min 3, max 20000)status:"pending" | "published" | "rejected" | "suspended" | "draft"(defaultpending)idempotencyKey: optional string, pattern^[A-Za-z0-9:_-]{8,128}$
Backend call:
POST /answerswith{ questionId, answerText, status, idempotencyKey }- duplicate retries with same
idempotencyKeyreturn existing answer (idempotencyReplayed: true) instead of creating a second answer
backend_health_check
Backend call:
- requests
GET /api/mcp/c/:clientKey/health(auth-protected MCP route).
6. Security model (as used by this package)
For protected MCP operation calls, package sends:
Authorization: Bearer <FAQ_MCP_TOKEN>
Backend validates token + client key (from path) and rejects mismatches/invalid pairs.
Log safety:
- startup logs redact client key from MCP base URL (
.../api/mcp/c/[redacted-client-key]).
Error hinting in client:
- tool responses now include structured metadata:
- success:
_meta.ok = true - failure:
_meta.ok = falsepluserror.code,error.httpStatus,error.retryable,error.message
- success:
- backend MCP routes include
errorCodeandretryablefields for machine-actionable retry decisions
7. Quick start
- Rotate credentials from backend admin API:
POST /api/mcp/token/rotate
Authorization: Bearer <your-jwt>- Copy values from response:
token->FAQ_MCP_TOKENmcpApiBaseUrl->FAQ_MCP_API_BASE_URL
- Run package:
npx -y @faq-app/agent-operation@latest8. Client config examples
Use the same structure in Claude/Cursor/VS Code MCP config:
{
"mcpServers": {
"faq-backend-operations": {
"command": "npx",
"args": ["-y", "@faq-app/agent-operation@latest"],
"env": {
"FAQ_MCP_API_BASE_URL": "https://your-domain.com/api/mcp/c/YOUR_MCP_CLIENT_KEY",
"FAQ_MCP_TOKEN": "mcp_your_rotated_token"
}
}
}
}9. Local development (package source)
From repo root:
cd packages/agent-operation
node src/cli.mjsPublish flow:
- Update
versioninpackages/agent-operation/package.json npm publish --access public- Consumers use
npx -y @faq-app/agent-operation@latest
10. Troubleshooting
"Missing FAQ_MCP_TOKEN"
- Set
FAQ_MCP_TOKENfrom rotate response.
"MCP base URL must include client key path"
- Use
mcpApiBaseUrlreturned by rotate response directly.
401 errors after previously working setup
- Credentials were likely rotated; update both token and client-key URL.
Timeout errors
- Increase
FAQ_MCP_TIMEOUT_MS. - Confirm backend reachability and route prefix.
11. Remaining known gaps / assignable work
Use this section to assign implementation tasks:
Automated tests for package
- Extend with full integration coverage against a running backend instance.
Release hardening
- Add changelog + explicit semver/versioning policy for npm releases.
Operational docs
- Add explicit failure-mode matrix (401/404/timeout) and runbook for token rotation incidents.
12. Source of truth
This README is derived from:
packages/agent-operation/src/server.mjspackages/agent-operation/src/cli.mjspackages/agent-operation/package.json- backend MCP route/auth implementation:
backend/routes/mcp.jsbackend/middleware/mcpTokenAuth.jsbackend/services/mcpTokenService.js
