Fileaify agent API — Mcp — The remote MCP connector
Part of the Fileaify agent protocol. Start page and index: /agent. Everything in one document: /agent/full.
Remote MCP connector and OAuth
Server URL: https://fileaify.com/mcp. This is a Streamable HTTP endpoint, not an HTML page. The public guide remains available at /agent without authorization.
In Claude's custom connector dialog, enter Fileaify and that URL. Automatic OAuth registration is supported; published client identity documents are supported for Claude and ChatGPT. Other clients can use dynamic registration. Client availability and administrative settings depend on the client provider. No client secret needs to be pasted into chat.
The OAuth browser flow opens Fileaify sign-in when needed, then an explicit consent page. An owner or administrator chooses one workspace, one or more projects, read permission, optional documentary contribution/resource metadata permissions, and a duration of 1 to 30 days. No secret value, secret-use permission or self-approval capability is granted by this consent. A separate connection can select another workspace.
MCP tools:
list_projects: authorized projects.read_projectis the starting index (no document bodies by default);read_documentfetches only relevant documents/sections.read_contractincludesproject_instructions, each document’sinstructions,format_template, loading policy and thresholds.read_methodexposes the editable method and its versions.read_versionsreads retained history.list_changes: paginated proposal metadata, never document bodies.read_change: paginated unified diff, optionally for one document.create_document: create a minimal document definition and optionally propose initial content with its exact rationale/evidence. Returnsid,source_name,change_id,change_status,replayed. Supplyidempotency_keyfor retry safety (REST:Idempotency-Key); without a key, creation is not idempotent. A retry with the same body/key returns the original response withreplayed: true, even if the proposal has since been decided. Read the proposal to obtain its current status.archive_document,restore_document: archive or restore a COMPLETE document. An archived document leaves the list of active documents, is shown in the Archives section, and is no longer loaded or counted toward size limits by default; restoring brings it back. They propose a loading-policy change through the same review, locks and publication policy as document edits and never permanently delete a document. They do NOT move sections of a document: to lighten a large document usearchive_sections.submit_changes: the same version checks, locking, evidence, idempotency and project publication policy as REST.read_resources,read_readiness: linked metadata and missing-reference diagnostics, not secret values.request_binding: request a vault reference's attachment to the project; attachment itself grants no secret permission.request_access,list_access_requests: request a precise capability/duration/use count and read the human decision. Requests appear in Fileaify's existing notification panel and remote approval interface. A pending request is not an authorization.use_secret: approved broker call to the fixed service destination; requiressecrets.use.export_secret: disabled by default in Fileaify Administration → Connector security. While disabled, export calls and MCP requests forsecrets.exportare rejected, even with a previously approved grant. Only a platform administrator can enable delivery; enabling grants no access by itself. When enabled, explicitly approved value delivery to the MCP client/provider; requiressecrets.export. The plaintext value reaches the client/provider and may enter the model context. This is not zero-knowledge. Prefer broker use when the task supports it. Exported credentials cannot be recalled by revoking the connector.
The connector appears as an agent in Fileaify and can be suspended or revoked there. Short-lived access tokens last at most one hour, with rotating refresh tokens limited by the human-approved connection expiry. Reconnection after that expiry requires new consent. Tokens are scoped to /mcp; human cookies and direct REST tokens cannot authenticate this endpoint, and MCP tokens cannot authenticate the REST API. No premium assistant quota is consumed by MCP tools and no internal LLM is required.
OAuth discovery: /.well-known/oauth-protected-resource/mcp and /.well-known/oauth-authorization-server. Authorization code + mandatory PKCE S256, exact registered redirect matching, resource https://fileaify.com/mcp, scope mcp. Resource permissions remain structured project grants, not OAuth scope text. Streamable HTTP uses JSON responses and the 2025-03-26, 2025-06-18 and 2025-11-25 protocol versions; no server-side session is required. An authenticated GET /mcp accepting text/event-stream offers short SSE responses for notifications/tools/list_changed; reconnection uses Last-Event-ID and a 30-second retry interval. Initialization advertises listChanged=true, a catalogue-derived server version, and responses carry X-Fileaify-Tool-Catalog with Cache-Control: no-store. A client retaining the old 13-tool catalogue must rediscover tools/list; if its refresh does not do so, disconnect/reconnect the connector and start a new conversation. The server cannot replace tools already injected into a client conversation.
Bounded MCP reading and exact edits
A fresh session starts with read_project(project_id) (default view="index"), then read_contract, and read_document for documents relevant to the task and their update triggers. Load always documents as the shared starting context, on_demand documents when relevant, and archive only for historical questions. The index excludes archived documents by default (include_archive=true includes them) and includes locked and pending_change_id per document. It includes document IDs, titles, roles, filenames, revisions, character/token estimates, update dates, loading policy, a bounded heading outline and a 200-character preview. It also includes the contract version, locks, warnings, capabilities and publication policy. attention is included only at document offset=0; subsequent pages do not repeat it. Index pages fill the response budget rather than an arbitrary document count. Large indexes paginate documents with offset/next_offset. An explicit view="full" is bounded too and excludes archived documents unless include_archive=true.
read_document(project_id, document_id, section?, offset?, limit_chars?) returns the published revision for base_revision, content, total_chars, truncated and next_offset. section is an exact Markdown heading, including its subsections until the next heading of equal or higher level. Duplicate headings return ambiguous_match; missing headings return no_match. Offsets are character offsets within the selected document or section and must start at line boundaries. Page cuts preserve complete lines. A single line beyond the requested limit returns HTTP 409 / an MCP tool error line_too_long; increase the limit up to 45,000 characters or split that line in the source. Re-read from offset zero if the document revision changes between pages.
Every MCP tool result uses one text JSON envelope containing data, truncated, total_chars, next_offset or next_cursor, and approx_tokens. There is no duplicated structuredContent and no output schema. At the envelope level, total_chars measures the compact JSON serialization of the delivered data payload and approx_tokens = ceil(total_chars / 3.5). These are estimates, not a model tokenizer. Inside document/diff data, total_chars still means the full source document/section/diff length. The serialized HTTP response is capped at 51,000 characters, below the 60,000-character ceiling, including escaping. Large generic objects use data.encoding="json-fragment", data.serialized_json, source_total_chars and next_offset: repeat the same read using result_offset, concatenate the fragments and then parse JSON. Normal document/index pagination uses offset, and proposal pagination uses cursor; do not confuse these with fragment pagination. REST index/full reads also use the JSON fragment envelope when necessary, with the same result_offset query parameter. Never repeat a mutation solely to paginate its response.
For an unusually large generic result, data.serialized_json carries a JSON fragment with encoding="json-fragment". Repeat the same read with result_offset=next_offset, concatenate the fragments and parse the result. This fallback preserves data rather than silently dropping fields. Ordinary document/section pages use offset; proposal lists use cursor. Never replay a mutation for pagination. This budget also applies to version histories and contracts; their large contents may require generic pagination.
list_changes(project_id, status?, limit=10, cursor?) returns metadata only: identifiers, actor name, creation date, contract version, rationale/evidence previews (500 characters with truncation flags), mixed decision state and publication metadata. Items contain document ID, filename, base revision, item status, before/after character counts and added/removed line counts. The server can return fewer items than requested to respect the budget. Follow next_cursor until absent. read_change(project_id, change_id, document_id?, offset?, limit_chars?) returns the same before/after diff as the human review, rendered as unified text and paginated at line boundaries. REST GET /api/v1/projects/{id}/changes now returns this metadata envelope; ?include=content explicitly requests the legacy full review payload. REST document and diff pages are available at /documents/{document_id} and /changes/{change_id} respectively.
Each submit_changes item must contain either content or edits, never both:
{"document_id":"DOCUMENT_ID","base_revision":21,"edits":[{"old":"Current text","new":"Corrected text","replace_all":false}]}
Edits require the exact current base revision (revision_conflict otherwise). Up to 50 edits are applied sequentially in memory. old must be nonempty and appear once, unless replace_all=true. Missing matches return no_match with a closest-line suggestion; multiple matches return ambiguous_match with the occurrence count. Suggestions are never applied automatically. Matching normalizes Unicode NFC and line endings to LF, preserving typographic apostrophes and nonbreaking spaces. A straight apostrophe (') does not match a typographic apostrophe (’); copy the exact text or use the returned nearby-line suggestion to recompose the edit. A no-op returns result_unchanged. Size and permission checks, locking and publication rules remain in force. A failed item rolls back the whole submission. Submitted edits are retained for audit; the resolved final content is stored for the usual before/after human review. Rationale, evidence, contract version and idempotency key retain their existing meaning.
Document definitions support load: always | on_demand | archive and max_chars (advisory warning threshold, default 20,000); the project threshold defaults to 200,000 characters across non-archive documents. Archive documents trigger neither the project size warning nor individual size warnings; permission/reference checks still apply. Templates define defaults per role and a project threshold, and project administrators can adjust the copied settings. historical-audit defaults to archive loading; overview defaults to always, including imported legacy overviews without a saved policy. An explicitly customized policy is preserved. These are advisory thresholds, not permission grants or the 150,000-character content validation ceiling. Built-in templates instruct agents to keep current state and the five latest releases and move older entries to *-ARCHIVE.md with archive loading. Existing project instructions and customized templates are not rewritten automatically. Archiving reduces the active context budget and its size warnings, not the amount of retained data. always is a loading recommendation, not a guarantee of a sub-20,000-character document: an oversized overview remains visible as a warning until it is edited.
Resource diagnostics, visible only with resources.read, include binding_missing_purpose and grant_without_broker. Empty endpoints with disabled brokerage are normal and do not trigger a warning. A binding purpose describes its use in this project; missing purposes are reported unless a human explicitly confirms an empty value. No documentation or purpose text grants a secret permission. The generated register marks legacy empty purposes explicitly.