MCP Server
The Schift MCP server exposes your Schift knowledge layer to any MCP-compatible client such as Claude Code, Cursor, ChatGPT, and Gemini. It is a thin wrapper around the Schift Cloud REST API that translates MCP tool calls into bucket search, document upload, memory search, and workflow operations.
Install
Section titled “Install”Install the package globally from npm:
npm install -g @schift-io/mcpThe installed binary is schift-mcp. It requires Node.js 18 or later.
You can also run it directly with npx:
npx -y @schift-io/mcpAuthentication
Section titled “Authentication”All MCP tools call the Schift Cloud API on your behalf, so the server needs a Schift API key.
| Variable | Required | Default | Description |
|---|---|---|---|
SCHIFT_API_KEY | Yes for stdio and self-hosted static mode | — | Schift API key used to call {apiUrl}. |
SCHIFT_API_BASE_URL | No | {apiUrl} | Schift API origin. |
SCHIFT_USER_ID | No | Inferred from API key | Explicit user ID for source listing. |
SCHIFT_DEFAULT_BUCKET | No | — | Default bucket for search and schift_search. |
SCHIFT_MEMORY_BUCKETS | No | Authenticated user’s memory layer | Comma-separated bucket list to force for memory search. |
SCHIFT_MCP_AUTH_MODE | No | static locally, upstream-bearer in hosted deploys | How remote clients authenticate. |
SCHIFT_MCP_BEARER_TOKEN | HTTP static mode | — | Token clients use to authenticate to your self-hosted HTTP server. |
SCHIFT_MCP_ALLOW_UNAUTHENTICATED | No | — | Set to 1 for local-only unauthenticated HTTP testing. |
Note: For the Schift-hosted endpoint at
{mcpUrl}/mcp, send your Schift API key or OAuth access token as the MCP client bearer token. The server does not use a sharedSCHIFT_API_KEYin that mode.
Commands
Section titled “Commands”Run schift-mcp without arguments to start the stdio MCP server:
SCHIFT_API_KEY=sk_... SCHIFT_DEFAULT_BUCKET=docs schift-mcpschift-mcp --http
Section titled “schift-mcp --http”Start a Streamable HTTP server at /mcp:
SCHIFT_API_KEY=sk_... \SCHIFT_DEFAULT_BUCKET=docs \SCHIFT_MCP_BEARER_TOKEN=your-mcp-client-token \schift-mcp --httpThe default port is 8787. Set PORT or SCHIFT_MCP_PORT to change it. A health check is available at GET /healthz.
In hosted multi-user mode, run:
SCHIFT_MCP_AUTH_MODE=upstream-bearer schift-mcp --httpIn that mode each MCP client sends the user’s Schift token as Authorization: Bearer ..., and the server calls the Schift API with that token.
schift-mcp token
Section titled “schift-mcp token”Generate a random bearer token for self-hosted HTTP mode:
schift-mcp tokenschift-mcp init --client <target>
Section titled “schift-mcp init --client <target>”Print configuration for a specific MCP client. Supported targets are claude, cursor, remote, and chatgpt.
schift-mcp init --client cursor --bucket docsschift-mcp init --client claude --bucket docsschift-mcp init --client remote --bucket docs --server-url https://mcp.your-domain.com/mcpWire to clients
Section titled “Wire to clients”Claude Code
Section titled “Claude Code”Add to ~/.claude/mcp_servers.json:
{ "schift": { "command": "schift-mcp", "env": { "SCHIFT_API_KEY": "sk_...", "SCHIFT_DEFAULT_BUCKET": "docs" } }}Cursor
Section titled “Cursor”Add to ~/.cursor/mcp.json:
{ "mcpServers": { "schift": { "command": "schift-mcp", "env": { "SCHIFT_API_KEY": "sk_...", "SCHIFT_DEFAULT_BUCKET": "docs" } } }}ChatGPT and remote MCP clients
Section titled “ChatGPT and remote MCP clients”Use the Schift-hosted endpoint ({mcpUrl}/mcp):
<your-mcp-host>/mcpAuthorization: Bearer <your-schift-api-key>For OpenAI’s Responses API style configuration:
{ "type": "mcp", "server_label": "schift", "server_url": "<your-mcp-host>/mcp", "headers": { "Authorization": "Bearer <your-schift-api-key>" }, "allowed_tools": ["search", "fetch", "schift_search", "schift_memory_search"], "require_approval": "never"}For a self-hosted remote server, use the URL you deployed and the SCHIFT_MCP_BEARER_TOKEN value:
https://mcp.your-domain.com/mcpAuthorization: Bearer <your-mcp-client-token>search(query)
Section titled “search(query)”ChatGPT-compatible search alias. Searches SCHIFT_DEFAULT_BUCKET or the user’s default bucket and returns result IDs, titles, and URLs. This searches your Schift knowledge, not the public web.
fetch(id)
Section titled “fetch(id)”ChatGPT-compatible fetch alias. Returns cached content for an ID previously returned by search in the same MCP session.
schift_search(query, ...)
Section titled “schift_search(query, ...)”Schift-native bucket search through POST /v2/buckets/{bucket}/search.
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search query. |
bucket | string | No | Bucket ID or name. Defaults to SCHIFT_DEFAULT_BUCKET, then default. |
collection | string | No | Deprecated alias for bucket. |
top_k | number | No | Number of results. Default 10. |
filter | object | No | Metadata filters passed to Schift search. |
task | string | No | Search instruction preset such as question_answering. |
rerank | boolean | No | Enable reranking. |
rerank_top_k | number | No | Rerank result limit. |
schift_list_buckets()
Section titled “schift_list_buckets()”List buckets available to the API key. Use this before search when the user has not named a bucket.
schift_list_bucket_collections(bucket)
Section titled “schift_list_bucket_collections(bucket)”List child collections inside a bucket.
| Parameter | Type | Required | Description |
|---|---|---|---|
bucket | string | Yes | Bucket ID or name. |
schift_upload_document(...)
Section titled “schift_upload_document(...)”Upload a text or base64-encoded file into a bucket and queue async ingestion.
| Parameter | Type | Required | Description |
|---|---|---|---|
bucket | string | No | Bucket ID or name. Defaults to SCHIFT_DEFAULT_BUCKET, then default. |
filename | string | Yes | File name. |
text / content | string | One required | UTF-8 text content. |
content_base64 | string | One required | Base64-encoded content for binary files. |
content_type | string | No | MIME type, for example text/plain or application/pdf. |
metadata | object | No | Document metadata. |
collection_id | string | No | Optional child collection ID. |
ocr_strategy | string | No | OCR strategy passed to Schift upload. |
chunk_size | number | No | Chunk size override. |
chunk_overlap | number | No | Chunk overlap override. |
Note: Do not pass both
textandcontent_base64; use one or the other.
Memory tools
Section titled “Memory tools”Memory tools search the authenticated user’s memory layer, which includes connected sources such as Gmail, Notion, Slack, Linear, GitHub, Calendar, and Drive.
schift_memory_search(query, ...)
Section titled “schift_memory_search(query, ...)”Search across the user’s memory buckets.
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search query. |
bucket | string | No | Optional bucket override. |
sources | string[] | No | Filter to source types such as gmail, notion, slack. |
tags | string[] | No | key:value tag filters combined with AND. |
top_k | number | No | Number of results. Default 20. |
temporal | string | No | One of before, after, between, as_of, latest. |
temporal_start | number | No | Temporal start timestamp. |
temporal_end | number | No | Temporal end timestamp. |
By default the tool calls POST /v1/memory/search and lets Schift discover the user’s memory:{user_id}:* buckets. Set SCHIFT_MEMORY_BUCKETS only when you need a fixed bucket list.
schift_memory_list_sources()
Section titled “schift_memory_list_sources()”List connected memory sources with sync status and indexed document count.
Workflow tools
Section titled “Workflow tools”Workflow tools run installed Agent Workflow Protocol (AWP) workflows through the Schift API.
schift_workflow_list()
Section titled “schift_workflow_list()”List the organization’s installed workflows. Only workflows with status published can be run; draft workflows must be reviewed and published in the Schift console first.
schift_workflow_dry_run(workflow_id, inputs?)
Section titled “schift_workflow_dry_run(workflow_id, inputs?)”Dry-run a workflow with the given inputs. This produces no side effects and returns block-level results for review.
schift_workflow_run(workflow_id, ...)
Section titled “schift_workflow_run(workflow_id, ...)”Run a published workflow.
| Parameter | Type | Required | Description |
|---|---|---|---|
workflow_id | string | Yes | Workflow ID. |
inputs | object | No | Workflow input values keyed by input name. |
mode | string | No | simulate (default) stages side effects; live executes them. |
approvals | object | No | Per-block human approvals such as {"review_issue": true}. Only set after explicit human approval. |
If the workflow is still a draft, the tool returns status: "needs_review" and a message explaining that a human must publish it first.
Examples
Section titled “Examples”Search your default bucket
Section titled “Search your default bucket”{ "name": "schift_search", "arguments": { "query": "Q3 renewal terms", "top_k": 5 }}Search memory by source and tag
Section titled “Search memory by source and tag”{ "name": "schift_memory_search", "arguments": { "query": "acme renewal", "sources": ["gmail", "notion"], "tags": ["account:acme"], "top_k": 10 }}Upload a document
Section titled “Upload a document”{ "name": "schift_upload_document", "arguments": { "bucket": "docs", "filename": "notes.md", "text": "# Project notes\n\nKey decision: use v2 buckets.", "content_type": "text/markdown", "metadata": { "project": "migration" } }}Run a workflow
Section titled “Run a workflow”{ "name": "schift_workflow_run", "arguments": { "workflow_id": "wf_abc123", "inputs": { "query": "Summarize latest Slack threads" }, "mode": "simulate" }}Security model
Section titled “Security model”- Local stdio mode: the MCP client launches
schift-mcpwithSCHIFT_API_KEYin its environment. No separate MCP bearer token is needed. - Self-hosted HTTP static mode: set
SCHIFT_MCP_BEARER_TOKENand have clients sendAuthorization: Bearer <token>. The server uses the staticSCHIFT_API_KEYto call Schift. - Hosted upstream-bearer mode: the MCP client sends its own Schift token as bearer. The server forwards that token to the Schift API and does not store a shared
SCHIFT_API_KEY. - HTTP mode refuses to start without
SCHIFT_MCP_BEARER_TOKENunlessSCHIFT_MCP_AUTH_MODE=upstream-bearerorSCHIFT_MCP_ALLOW_UNAUTHENTICATED=1is set for local testing.
Environment variable summary
Section titled “Environment variable summary”| Variable | Used in | Purpose |
|---|---|---|
SCHIFT_API_KEY | stdio, self-hosted static | Schift API authentication. |
SCHIFT_API_BASE_URL | All modes | Schift API origin. |
SCHIFT_USER_ID | All modes | Optional explicit user ID. |
SCHIFT_DEFAULT_BUCKET | All modes | Default bucket for search and upload. |
SCHIFT_MEMORY_BUCKETS | All modes | Force memory search to these buckets. |
SCHIFT_MCP_AUTH_MODE | HTTP | static or upstream-bearer. |
SCHIFT_MCP_BEARER_TOKEN | HTTP static | Client-to-server bearer token. |
SCHIFT_MCP_ALLOW_UNAUTHENTICATED | HTTP local testing | Skip bearer token check. |
PORT / SCHIFT_MCP_PORT | HTTP | Server port. Default 8787. |