vee.kr

Agents

MCP server

Complete OAuth remote Model Context Protocol surface: four tools, every operation and type branch, transport, limits, and recovery hints. Same ownership, scopes, quotas, and audit trail as API v1.

Connect

Connect ChatGPT, Claude, or another remote MCP client to your Bidama host. The server URL is the public origin plus /mcp.

Transport How Auth
Remote HTTP POST /mcp Authorization: Bearer bdmo_at_...
OAuth discovery /.well-known/oauth-protected-resource/mcp Authorization code + PKCE
Remote MCP URL: https://<your-host>/mcp
  • HTTP is sessionless: each POST builds a temporary server from that request's OAuth access token. Unsafe cross-origin browser requests are rejected. Authenticated GET returns 405.
  • ChatGPT and Claude should be configured with https://<your-host>/mcp, then complete the browser OAuth consent flow.
  • Tool permissions are read, write, and delete. offline_access is only an authorization-server scope for refresh tokens.
  • JSON-RPC batch arrays are rejected before dispatch so one transport request cannot fan out into unbounded tool calls.
  • Each replica accepts at most four concurrent MCP HTTP requests and two per OAuth access token (429 + Retry-After beyond either bound). A POST body must finish within 60 seconds.

Tools

Four tools preserve authorization boundaries. Creation and change stay separate; delete is never mixed into write.

Tool Discriminator Scope readOnly destructive idempotent Description
bidama_read operation (7) read true false true Inspect account, resources, analytics, markdown versions, and jobs.
bidama_create type (8) write false false false Create any of the eight resource types, including files and artifacts.
bidama_change operation (4) write false true false Update, restore markdown, redeploy artifacts, or optimize originals.
bidama_delete delete false true true Soft-delete one owned resource by slug.

Annotations are client hints, never authorization. bidama_create is openWorld because Notion create can schedule an external fetch; the other tools operate only on this deployment.

bidama_read

Requires read. Select exactly one closed operation branch:

operation Input fields Description
get_accountIdentity, creation permissions, storage usage/limit, and enabled features.
list_resourcesq?, type?, label?, sort?, archived?, pinned?, limit?, cursor?Compact rows and next_cursor. Default limit 20; MCP maximum 100.
get_resourceslug, content?Type-specific detail plus etag. content is snippet (default), full, or none.
get_analyticsslug, days?, top?Hits, visitors, daily counts, ranked buckets. days defaults to 30 (0 = all time, max 365); top defaults to 5 (max 10).
list_markdown_versionsslugVersion rows with ID, number, source, size, preview, and created time.
get_markdown_versionslug, version_id, content?One historical markdown source; content defaults to full.
get_jobjob_idJob status, safe result projection, error, attempts, completion time, and next poll delay while active.
  • type filters: link, markdown, file, image, collection, notion, bio, artifact. sort: newest, pinned, title, expiring, most_viewed, recently_updated. archived: false (default), true, or all.
  • List rows omit owner IDs, internal object keys, and large bodies. Fetch get_resource for full public resource details.

bidama_create

Requires write. type selects one of eight closed branches. Unknown fields are rejected.

type Required type fields Optional type fields
linktarget_urlmax_views
markdownraw_markdownmax_views
filefile_name, file_contentcontent_type, max_views
imagefile_name, file_contentcontent_type
collection
notionsource_urlroot_page_id
biodisplay_name, headline, bio, theme
artifactarchive_base64 or filesvisibility
  • Common optional fields: slug, title, description, expires_at, password, labels.
  • file_content is base64. The server sniffs MIME: image requires image bytes and file requires non-image bytes.
  • Artifacts accept exactly one of archive_base64 (ZIP) or files as a native JSON array of {path, content, encoding?} — never a stringified JSON string, and never both modes. Prefer archive_base64 for multi-file packages when arrays are awkward. Decoded content is capped at 8 MiB; direct mode at most 500 files. visibility is public (default), unlisted, or private. max_views is not supported.
  • Results return slug, type, url, and etag, plus essentials such as stored filename or artifact deployment_id, origin_url, and entry_path.

bidama_change

Requires write. Annotated destructive because branches can replace originals or retire deployments.

operation Input fields Description
update_resourceslug, if_match?, and at least one of title, description, new_slug, target_url, raw_markdown, expires_at, max_views, password, labels, archived, pinned, original_filenamePartial update of only fields present in the call. Empty expires_at or password clears it.
restore_markdown_versionslug, version_id, if_match?Snapshot current markdown and restore the selected version (reversible via history).
redeploy_artifactslug, if_match?, archive_base64 or filesPublish a new immutable deployment and retire the previous origin (same 8 MiB content modes as create).
optimize_originalslugEnqueue eligible JPEG/HEIC/HEIF original replacement; may irreversibly replace the stored original. Returns job_id for polling.
  • slug always identifies the current resource; new_slug is the replacement value on rename.
  • Poll optimize jobs with bidama_read operation get_job. On job_already_active, reuse the earlier job_id rather than enqueueing again.

bidama_delete

Requires delete and accepts slug. Soft-deletes the owned resource so the slug stops resolving publicly. Success returns {slug, deleted: true}. Annotated idempotent: a safe retry may report not_found.

Example calls

Tools take a discriminator (type or operation). Keep the returned etag for later edits. For artifacts, files must be a real JSON array (see the second example), not a string.

bidama_create
{
  "type": "markdown",
  "title": "Release notes",
  "raw_markdown": "# Hello\n\nShipped today."
}
bidama_create
{
  "type": "artifact",
  "title": "Demo",
  "files": [
    {"path": "index.html", "content": "<h1>Hi</h1>", "encoding": "text"}
  ]
}
bidama_change
{
  "operation": "update_resource",
  "slug": "release-notes",
  "if_match": "<etag-from-get_resource>",
  "title": "Release notes (final)"
}
bidama_read
{
  "operation": "get_job",
  "job_id": "<job-id-from-optimize_original>"
}

Conventions

  • Omit slug on create to auto-generate one. Slugs are 3–64 characters: a–z, 0–9, - or _.
  • get_resource returns an etag; pass it as if_match on bidama_change to avoid overwriting concurrent edits.
  • Inline file and artifact payloads are capped at 8 MiB decoded (12 MiB MCP JSON envelope). Use REST uploads for larger content.
  • Outputs include typed structuredContent plus a compact JSON text copy for clients that ignore structured output.
  • The machine-readable REST contract is also available as MCP resource (text/yaml): bidama://openapi.yaml

Errors and recovery

Failures keep the REST envelope (status, error_code, message, field/details, Retry-After) and append a short recovery hint for stable codes:

error_code Suggested action
slug_takenChoose another slug or omit it to auto-generate one.
etag_mismatchRe-read the resource and retry with the fresh etag.
insufficient_scopeReconnect or re-authorize with the required read, write, or delete scope.
rate_limitedWait for Retry-After and retry.
quota_exceededCall get_account and free storage or increase the quota.
job_already_activeReuse and poll the job ID from the earlier accepted call.
validation_failedCorrect the named field; do not retry unchanged input.
artifact_index_missingInclude a non-empty root index.html or another non-empty HTML entry.
not_foundCheck the slug/ID and ownership; the resource may be deleted or expired.

Deliberately not exposed

  • No list_jobs — agents poll job IDs returned by their own operations.
  • QR bytes are not returned as tool content; use the resource QR URL out of band.
  • Cookie-API-only bio blocks, collection items, upload requests, and Notion cached-page ops are not MCP tools.
  • No generic REST passthrough tool — typed schemas, annotations, and projections stay mandatory.

ChatGPT and Claude

In ChatGPT, Claude, or any remote MCP client, add a custom connector with this server URL and approve the requested scopes in Bidama.

{
  "name": "Bidama",
  "url": "https://<your-host>/mcp"
}

Revoke previously approved clients from Connected Apps: /connected-apps.

Also see: API · OpenAPI